1 /* Copyright (c) 1997-2021
2    Ewgenij Gawrilow, Michael Joswig, and the polymake team
3    Technische Universität Berlin, Germany
4    https://polymake.org
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version: http://www.gnu.org/licenses/gpl.txt.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 --------------------------------------------------------------------------------
16 */
17 
18 #include "polymake/perl/glue.h"
19 #include "polymake/Main.h"
20 
21 namespace pm { namespace perl {
22 
23 namespace {
24 
25 glue::cached_cv application_cv{ "Polymake::User::application" },
26             app_from_object_cv{ "Polymake::Main::application_from_object" },
27                   new_scope_cv{ "Polymake::Main::createNewScope" },
28                  set_custom_cv{ "Polymake::Main::set_custom" },
29                reset_custom_cv{ "Polymake::Main::reset_custom" },
30                local_custom_cv{ "Polymake::Main::local_custom" },
31                    greeting_cv{ "Polymake::Main::greeting" },
32                shell_enable_cv{ "Polymake::Main::shell_enable" },
33               shell_execute_cv{ "Polymake::Main::shell_execute" },
34              shell_complete_cv{ "Polymake::Main::shell_complete" },
35          shell_context_help_cv{ "Polymake::Main::shell_context_help" };
36 
37 const char Extension[]="Polymake::Core::Extension";
38 
39 }
40 
set_application(const AnyString & appname)41 void Main::set_application(const AnyString& appname)
42 {
43    dTHX;
44    PmStartFuncall(1);
45    mPUSHp(appname.ptr, appname.len);
46    PUTBACK;
47    glue::call_func_void(aTHX_ application_cv);
48 }
49 
set_application_of(const BigObject & x)50 void Main::set_application_of(const BigObject& x)
51 {
52    dTHX;
53    PmStartFuncall(1);
54    PUSHs(x.obj_ref);
55    PUTBACK;
56    glue::call_func_void(aTHX_ app_from_object_cv);
57 }
58 
add_extension(const AnyString & path)59 void Main::add_extension(const AnyString& path)
60 {
61    dTHX;
62    PmStartFuncall(2);
63    mPUSHp(Extension, sizeof(Extension)-1);
64    mPUSHp(path.ptr, path.len);
65    PUTBACK;
66    glue::call_method_void(aTHX_ "add");
67 }
68 
include(const AnyString & path)69 void Main::include(const AnyString& path)
70 {
71    call_app_method("include_rules", path);
72 }
73 
set_preference(const AnyString & label_exp)74 void Main::set_preference(const AnyString& label_exp)
75 {
76    call_app_method("set_preference", label_exp);
77 }
78 
reset_preference(const AnyString & label_exp)79 void Main::reset_preference(const AnyString& label_exp)
80 {
81    call_app_method("reset_preference", label_exp);
82 }
83 
lookup_extension(const AnyString & path)84 SV* Main::lookup_extension(const AnyString& path)
85 {
86    dTHX;
87    PmStartFuncall(2);
88    mPUSHp(Extension, sizeof(Extension)-1);
89    mPUSHp(path.ptr, path.len);
90    PUTBACK;
91    return glue::call_method_scalar(aTHX_ "lookup");
92 }
93 
call_app_method(const char * method,const AnyString & arg)94 void Main::call_app_method(const char* method, const AnyString& arg)
95 {
96    dTHX;
97    PmStartFuncall(2);
98    SV* const app = glue::get_current_application(aTHX);
99    PUSHs(app);
100    mPUSHp(arg.ptr, arg.len);
101    PUTBACK;
102    glue::call_method_void(aTHX_ method);
103 }
104 
set_custom_var(const AnyString & name,const AnyString & key,Value & x)105 void Main::set_custom_var(const AnyString& name, const AnyString& key, Value& x)
106 {
107    dTHX;
108    PmStartFuncall(4);
109    SV* const app = glue::get_current_application(aTHX);
110    PUSHs(app);
111    mPUSHp(name.ptr, name.len);
112    if (key.ptr) mPUSHp(key.ptr, key.len);
113    PUSHs(x.get_temp());
114    PUTBACK;
115    glue::call_func_void(aTHX_ set_custom_cv);
116 }
117 
reset_custom(const AnyString & name,const AnyString & key)118 void Main::reset_custom(const AnyString& name, const AnyString& key)
119 {
120    dTHX;
121    PmStartFuncall(3);
122    SV* const app = glue::get_current_application(aTHX);
123    PUSHs(app);
124    mPUSHp(name.ptr, name.len);
125    if (key.ptr) mPUSHp(key.ptr, key.len);
126    PUTBACK;
127    glue::call_func_void(aTHX_ reset_custom_cv);
128 }
129 
newScope()130 Scope Main::newScope()
131 {
132    dTHX;
133    PmStartFuncall(0);
134    return Scope(this, call_func_scalar(aTHX_ new_scope_cv));
135 }
136 
prefer_now(const AnyString & labels) const137 void Scope::prefer_now(const AnyString& labels) const
138 {
139    pm_main->call_app_method("prefer_now", labels);
140 }
141 
set_custom_var(const AnyString & name,const AnyString & key,Value & x) const142 void Scope::set_custom_var(const AnyString& name, const AnyString& key, Value& x) const
143 {
144    dTHX;
145    PmStartFuncall(4);
146    SV* const app = glue::get_current_application(aTHX);
147    PUSHs(app);
148    mPUSHp(name.ptr, name.len);
149    if (key.ptr) mPUSHp(key.ptr, key.len);
150    PUSHs(x.get_temp());
151    PUTBACK;
152    glue::call_func_void(aTHX_ local_custom_cv);
153 }
154 
greeting(int verbose)155 std::string Main::greeting(int verbose)
156 {
157    dTHX;
158    PmStartFuncall(1);
159    mPUSHi(verbose);
160    PUTBACK;
161    return glue::call_func_string(aTHX_ greeting_cv);
162 }
163 
shell_enable()164 void Main::shell_enable()
165 {
166    dTHX;
167    PmStartFuncall(0);
168    glue::call_func_void(aTHX_ shell_enable_cv);
169 }
170 
shell_execute(const std::string & input)171 Main::shell_execute_t Main::shell_execute(const std::string& input)
172 {
173    if (input.empty())
174       return shell_execute_t(true, input, input, input);
175 
176    dTHX;
177    PmStartFuncall(1);
178    mPUSHp(input.c_str(), input.size());
179    PUTBACK;
180    if (glue::call_func_list(aTHX_ shell_execute_cv) != 4)
181       return shell_execute_t(false, "", "", "unknown error");
182 
183    SPAGAIN;
184    bool executed = false;
185    std::string out, err, exc;
186    Value(POPs) >> exc;
187    Value(POPs) >> err;
188    Value(POPs) >> out;
189    Value(POPs) >> executed;
190    PmFinishFuncall;
191    return shell_execute_t(executed, std::move(out), std::move(err), std::move(exc));
192 }
193 
shell_complete(const std::string & input)194 Main::shell_complete_t Main::shell_complete(const std::string& input)
195 {
196    dTHX;
197    PmStartFuncall(1);
198    mPUSHp(input.c_str(), input.size());
199    PUTBACK;
200    int n = glue::call_func_list(aTHX_ shell_complete_cv);
201    int offset = 0;
202    char append = 0;
203    std::vector<std::string> proposals(n > 2 ? n-2 : 0);
204    if (n >= 2) {
205       SPAGAIN;
206       while (--n >= 2) {
207          Value(POPs) >> proposals[n-2];
208       }
209       Value(POPs) >> append;
210       Value(POPs) >> offset;
211       PmFinishFuncall;
212    }
213    return shell_complete_t(offset, append, std::move(proposals));
214 }
215 
shell_context_help(const std::string & input,size_t pos,bool full,bool html)216 std::vector<std::string> Main::shell_context_help(const std::string& input, size_t pos, bool full, bool html)
217 {
218    dTHX;
219    PmStartFuncall(4);
220    mPUSHp(input.c_str(), input.size());
221    if (pos == std::string::npos)
222       pos = input.size();
223    mPUSHi(pos);
224    SV* bool_sv = full ? &PL_sv_yes : &PL_sv_no;
225    PUSHs(bool_sv);
226    bool_sv = html ? &PL_sv_yes : &PL_sv_no;
227    PUSHs(bool_sv);
228    PUTBACK;
229    int n = glue::call_func_list(aTHX_ shell_context_help_cv);
230    std::vector<std::string> results(n);
231    if (n > 0) {
232       SPAGAIN;
233       while (--n >= 0) {
234          Value(POPs) >> results[n];
235       }
236       PmFinishFuncall;
237    }
238    return results;
239 }
240 
set_interrupt_signal(int signum)241 void Main::set_interrupt_signal(int signum)
242 {
243    dTHX;
244    glue::set_interrupt_signal(aTHX_ signum);
245 }
246 
247 } }
248 
249 // Local Variables:
250 // mode:C++
251 // c-basic-offset:3
252 // indent-tabs-mode:nil
253 // End:
254