📄 builtins.c
字号:
LIST* rule_name = lol_get( frame->args, 1 ); module_t* module = bindmodule(module_name->string); native_rule_t n, *np = &n; n.name = rule_name->string; if (module->native_rules && hashcheck(module->native_rules, (HASHDATA**)&np)) { new_rule_body(module, np->name, np->arguments, np->procedure, 1); } else { backtrace_line( frame->prev ); printf( "error: no native rule \"%s\" defined in module \"%s\"\n", n.name, module->name); backtrace( frame->prev ); exit(1); } return L0; }LIST *builtin_has_native_rule( PARSE *parse, FRAME *frame ){ LIST* module_name = lol_get( frame->args, 0 ); LIST* rule_name = lol_get( frame->args, 1 ); LIST* version = lol_get( frame->args, 2 ); module_t* module = bindmodule(module_name->string); native_rule_t n, *np = &n; n.name = rule_name->string; if (module->native_rules && hashcheck(module->native_rules, (HASHDATA**)&np)) { int expected_version = atoi(version->string); if (np->version == expected_version) return list_new(0, newstr("true")); } return L0; }LIST *builtin_user_module( PARSE *parse, FRAME *frame ){ LIST* module_name = lol_get( frame->args, 0 ); for(; module_name; module_name = module_name->next) { module_t* m = bindmodule( module_name->string); m->user_module = 1; } return L0;}LIST *builtin_nearest_user_location( PARSE *parse, FRAME *frame ){ LIST* result = 0; FRAME* nearest_user_frame = frame->module->user_module ? frame : frame->prev_user; if (nearest_user_frame) { char* file; int line; char buf[32]; get_source_line( nearest_user_frame->procedure, &file, &line ); sprintf( buf, "%d", line ); result = list_new( result, newstr( file ) ); result = list_new( result, newstr( buf ) ); return result; } else { return L0; }}LIST *builtin_check_if_file( PARSE *parse, FRAME *frame ){ LIST* name = lol_get( frame->args, 0 ); if (file_is_file(name->string) == 1) { return list_new(0, newstr("true")); } else { return L0; }}#ifdef HAVE_PYTHONLIST *builtin_python_import_rule( PARSE *parse, FRAME *frame ){ static int first_time = 1; char* python_module = lol_get( frame->args, 0 )->string; char* python_function = lol_get( frame->args, 1 )->string; char* jam_module = lol_get( frame->args, 2 )->string; char* jam_rule = lol_get( frame->args, 3 )->string; PyObject *pName, *pModule, *pDict, *pFunc; if (first_time) { /* At the first invocation, we add the value of the global EXTRA_PYTHONPATH to the sys.path Python variable. */ LIST* extra = 0; module_t* outer_module = frame->module; first_time = 0; if ( outer_module != root_module()) { exit_module( outer_module ); enter_module( root_module()); } extra = var_get("EXTRA_PYTHONPATH"); if ( outer_module != root_module()) { exit_module( root_module()); enter_module( outer_module ); } for(; extra; extra = extra->next) { string buf[1]; string_new(buf); string_append(buf, "import sys\nsys.path.append(\""); string_append(buf, extra->string); string_append(buf, "\")\n"); PyRun_SimpleString(buf->value); string_free(buf); } } pName = PyString_FromString(python_module); pModule = PyImport_Import(pName); Py_DECREF(pName); if (pModule != NULL) { pDict = PyModule_GetDict(pModule); pFunc = PyDict_GetItemString(pDict, python_function); if (pFunc && PyCallable_Check(pFunc)) { module_t* m = bindmodule(jam_module); RULE* r = bindrule( jam_rule, m ); /* Make pFunc owned */ Py_INCREF(pFunc); r->python_function = pFunc; } else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", python_function); } Py_DECREF(pModule); } else { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", python_module); } return L0;}#endifvoid lol_build( LOL* lol, char** elements ){ LIST* l = L0; lol_init( lol ); while ( elements && *elements ) { if ( !strcmp( *elements, ":" ) ) { lol_add( lol, l ); l = L0 ; } else { l = list_new( l, newstr( *elements ) ); } ++elements; } if ( l != L0 ) lol_add( lol, l );}#ifdef HAVE_PYTHON/** Calls the bjam rule specified by name passed in 'args'. The name is looked up in context of bjam's 'python_interface' module. Returns the list of string retured by the rule.*/PyObject*bjam_call(PyObject* self, PyObject* args){ FRAME inner[1]; LIST *result; PARSE *p; char* rulename; /* Build up the list of arg lists */ frame_init( inner ); inner->prev = 0; inner->prev_user = 0; inner->module = bindmodule("python_interface"); inner->procedure = 0; /* Extract the rule name and arguments from 'args' */ /* PyTuple_GetItem returns borrowed reference */ rulename = PyString_AsString(PyTuple_GetItem(args, 0)); { int i = 1; int size = PyTuple_Size(args); for( ; i < size; ++i) { PyObject* a = PyTuple_GetItem(args, i); if (PyString_Check(a)) { lol_add(inner->args, list_new(0, newstr(PyString_AsString(a)))); } else if (PySequence_Check(a)) { LIST* l = 0; int s = PySequence_Size(a); int i = 0; for(; i < s; ++i) { /* PySequence_GetItem returns new reference. */ PyObject* e = PySequence_GetItem(a, i); char* s = PyString_AsString(e); if (!s) { printf("Invalid parameter type passed from Python\n"); exit(1); } l = list_new(l, newstr(s)); Py_DECREF(e); } lol_add(inner->args, l); } } } result = evaluate_rule( rulename, inner ); frame_free( inner ); Py_INCREF(Py_None); return Py_None;}/** Accepts three arguments: module name, rule name and Python callable. Creates bjam rule with the specified name in the specified module, which will invoke the Python callable.*/PyObject*bjam_import_rule(PyObject* self, PyObject* args){ char* module; char* rule; PyObject* func; module_t* m; RULE* r; if (!PyArg_ParseTuple(args, "ssO:import_rule", &module, &rule, &func)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_RuntimeError, "Non-callable object passed to bjam.import_rule"); return NULL; } m = bindmodule(module); r = bindrule(rule, m); /* Make pFunc owned */ Py_INCREF(func); r->python_function = func; Py_INCREF(Py_None); return Py_None;}/* Accepts four arguments: - an action name - an action body - a list of variable that will be bound inside the action - integer flags. Defines an action on bjam side. */PyObject*bjam_define_action(PyObject* self, PyObject *args){ char* name; char* body; module_t* m; PyObject *bindlist_python; int flags; LIST *bindlist = L0; int n; int i; if (!PyArg_ParseTuple(args, "ssO!i:define_action", &name, &body, &PyList_Type, &bindlist_python, &flags)) return NULL; n = PyList_Size (bindlist_python); for (i = 0; i < n; ++i) { PyObject *next = PyList_GetItem(bindlist_python, i); if (!PyString_Check(next)) { PyErr_SetString(PyExc_RuntimeError, "bind list has non-string type"); return NULL; } bindlist = list_new(bindlist, PyString_AsString(next)); } new_rule_actions(root_module(), name, newstr(body), bindlist, flags); Py_INCREF(Py_None); return Py_None; }/* Returns the value of a variable in root Jam module. */PyObject*bjam_variable(PyObject* self, PyObject* args){ char *name; LIST* value; PyObject *result; int i; if (!PyArg_ParseTuple(args, "s", &name)) return NULL; enter_module(root_module()); value = var_get(name); exit_module(root_module()); result = PyList_New(list_length(value)); for (i = 0; value; value = list_next(value), ++i) PyList_SetItem(result, i, PyString_FromString(value->string)); return result;}PyObject*bjam_backtrace(PyObject* self, PyObject *args){ PyObject *result = PyList_New(0); struct frame *f = frame_before_python_call; for(; f = f->prev;) { PyObject *tuple = PyTuple_New(4); char* file; int line; char buf[32]; get_source_line( f->procedure, &file, &line ); sprintf( buf, "%d", line ); /* PyTuple_SetItem steals reference. */ PyTuple_SetItem(tuple, 0, PyString_FromString(file)); PyTuple_SetItem(tuple, 1, PyString_FromString(buf)); PyTuple_SetItem(tuple, 2, PyString_FromString(f->module->name)); PyTuple_SetItem(tuple, 3, PyString_FromString(f->rulename)); PyList_Append(result, tuple); Py_DECREF(tuple); } return result;}#endif#ifdef HAVE_POPEN#if defined(_MSC_VER) || defined(__BORLANDC__) #define popen _popen #define pclose _pclose#endifLIST *builtin_shell( PARSE *parse, FRAME *frame ){ LIST* command = lol_get( frame->args, 0 ); LIST* result = 0; string s; int ret; char buffer[1024]; FILE *p = NULL; int exit_status = -1; int exit_status_opt = 0; int no_output_opt = 0; /* Process the variable args options. */ { int a = 1; LIST * arg = lol_get( frame->args, a ); while ( arg ) { if ( strcmp("exit-status", arg->string) == 0 ) { exit_status_opt = 1; } else if ( strcmp("no-output", arg->string) == 0 ) { no_output_opt = 1; } arg = lol_get( frame->args, ++a ); } } string_new( &s ); fflush(NULL); p = popen(command->string, "r"); if ( p == NULL ) return L0; while ( (ret = fread(buffer, sizeof(char), sizeof(buffer)-1, p)) > 0 ) { buffer[ret] = 0; if ( ! no_output_opt ) { string_append( &s, buffer ); } } exit_status = pclose(p); /* The command output is returned first. */ result = list_new( L0, newstr(s.value) ); string_free(&s); /* The command exit result next. */ if ( exit_status_opt ) { sprintf (buffer, "%d", exit_status); result = list_new( result, newstr( buffer ) ); } return result;}#elseLIST *builtin_shell( PARSE *parse, FRAME *frame ){ return L0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -