static struct ast_node* stmt(void *opaque) { struct ast_node *node; token_t prev_token; prev_token = current_token; if (match(TOKEN_FUNCTION)) node = process_function(opaque); else if (match(TOKEN_LOCAL)) node = process_local_declaration(opaque); else if (match(TOKEN_IF)) node = if_expr(opaque); else if (match(TOKEN_FOR)) node = for_expr(opaque); else if (match(TOKEN_WHILE)) node = while_expr(opaque); else if (match(TOKEN_BREAK)) node = break_expr(opaque); else if (match(TOKEN_CONTINUE)) node = continue_expr(opaque); else if (match(TOKEN_RETURN)) node = process_return_node(opaque); else if (match(TOKEN_LBRACE)) node = process_scope(opaque); else if (match(TOKEN_RBRACE)) node = end_scope_expr(opaque); else if (match(TOKEN_UNKNOWN)) node = unknown_expr(opaque); else node = other_expr(opaque); return node; }
static const char * walk_dollar_expansion(const char *start, const char *p, const char *end, char endchar, char disable_quote) { if ('(' == *p) return process_scope(NULL, start, p + 1, end, NULL, NULL, ')', NULL) + 1; if ('\'' == *p && !disable_quote) return walk_statement_dollared_quote_parsing(p + 1, end, '\'') + 1; if ('{' != *p) { if ('$' == *p) // short circuit it. return p + 1; while (p < end && endchar != *p) { if (isspace(*p)) return p; if ('$' == *p) return walk_dollar_expansion(start, p + 1, end, endchar, 0); if (!isalnum(*p)) { if ('_' != *p) { return p; } } ++p; } return p >= end ? end : p; } ++p; // shortcut ${$} to avoid going too deep. ${$a} isn't valid so no concern if ('$' == *p) return p + 1; while (p < end && '}' != *p) { if ('$' == *p) p = walk_dollar_expansion(start, p + 1, end, endchar, 0); else ++p; } return p + 1; }
int main(int argc, char *argv[]) { int ch; int retval; char *inputfilename; scope_t *sentinal; STAILQ_INIT(&patches); SLIST_INIT(&search_path); STAILQ_INIT(&seq_program); TAILQ_INIT(&cs_tailq); SLIST_INIT(&scope_stack); /* Set Sentinal scope node */ sentinal = scope_alloc(); sentinal->type = SCOPE_ROOT; includes_search_curdir = 1; appname = *argv; regfile = NULL; listfile = NULL; #if DEBUG yy_flex_debug = 0; mm_flex_debug = 0; yydebug = 0; mmdebug = 0; #endif while ((ch = getopt(argc, argv, "d:i:l:n:o:p:r:I:X")) != -1) { switch(ch) { case 'd': #if DEBUG if (strcmp(optarg, "s") == 0) { yy_flex_debug = 1; mm_flex_debug = 1; } else if (strcmp(optarg, "p") == 0) { yydebug = 1; mmdebug = 1; } else { fprintf(stderr, "%s: -d Requires either an " "'s' or 'p' argument\n", appname); usage(); } #else stop("-d: Assembler not built with debugging " "information", EX_SOFTWARE); #endif break; case 'i': stock_include_file = optarg; break; case 'l': /* Create a program listing */ if ((listfile = fopen(optarg, "w")) == NULL) { perror(optarg); stop(NULL, EX_CANTCREAT); } listfilename = optarg; break; case 'n': /* Don't complain about the -nostdinc directrive */ if (strcmp(optarg, "ostdinc")) { fprintf(stderr, "%s: Unknown option -%c%s\n", appname, ch, optarg); usage(); /* NOTREACHED */ } break; case 'o': if ((ofile = fopen(optarg, "w")) == NULL) { perror(optarg); stop(NULL, EX_CANTCREAT); } ofilename = optarg; break; case 'p': /* Create Register Diagnostic "printing" Functions */ if ((regdiagfile = fopen(optarg, "w")) == NULL) { perror(optarg); stop(NULL, EX_CANTCREAT); } regdiagfilename = optarg; break; case 'r': if ((regfile = fopen(optarg, "w")) == NULL) { perror(optarg); stop(NULL, EX_CANTCREAT); } regfilename = optarg; break; case 'I': { path_entry_t include_dir; if (strcmp(optarg, "-") == 0) { if (includes_search_curdir == 0) { fprintf(stderr, "%s: Warning - '-I-' " "specified multiple " "times\n", appname); } includes_search_curdir = 0; for (include_dir = SLIST_FIRST(&search_path); include_dir != NULL; include_dir = SLIST_NEXT(include_dir, links)) /* * All entries before a '-I-' only * apply to includes specified with * quotes instead of "<>". */ include_dir->quoted_includes_only = 1; } else { include_dir = (path_entry_t)malloc(sizeof(*include_dir)); if (include_dir == NULL) { perror(optarg); stop(NULL, EX_OSERR); } include_dir->directory = strdup(optarg); if (include_dir->directory == NULL) { perror(optarg); stop(NULL, EX_OSERR); } include_dir->quoted_includes_only = 0; SLIST_INSERT_HEAD(&search_path, include_dir, links); } break; } case 'X': /* icc version of -nostdinc */ break; case '?': default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 1) { fprintf(stderr, "%s: No input file specifiled\n", appname); usage(); /* NOTREACHED */ } if (regdiagfile != NULL && (regfile == NULL || stock_include_file == NULL)) { fprintf(stderr, "%s: The -p option requires the -r and -i options.\n", appname); usage(); /* NOTREACHED */ } symtable_open(); inputfilename = *argv; include_file(*argv, SOURCE_FILE); retval = yyparse(); if (retval == 0) { if (SLIST_FIRST(&scope_stack) == NULL || SLIST_FIRST(&scope_stack)->type != SCOPE_ROOT) { stop("Unterminated conditional expression", EX_DATAERR); /* NOTREACHED */ } /* Process outmost scope */ process_scope(SLIST_FIRST(&scope_stack)); /* * Decend the tree of scopes and insert/emit * patches as appropriate. We perform a depth first * tranversal, recursively handling each scope. */ /* start at the root scope */ dump_scope(SLIST_FIRST(&scope_stack)); /* Patch up forward jump addresses */ back_patch(); if (ofile != NULL) output_code(); if (regfile != NULL) symtable_dump(regfile, regdiagfile); if (listfile != NULL) output_listing(inputfilename); } stop(NULL, 0); /* NOTREACHED */ return (0); }
static PyObject * pkgcore_filter_env_run(PyObject *self, PyObject *args, PyObject *kwargs) { /* Arguments. */ PyObject *out, *envvar_callback=NULL; const char *file_buff; PyObject *var_matcher, *func_matcher; Py_ssize_t file_size; char *res_p = NULL; static char *kwlist[] = {"out", "file_buff", "vsr", "fsr", "global_envvar_callback", NULL}; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os#OO|O", kwlist, &out, &file_buff, &file_size, &var_matcher, &func_matcher, &envvar_callback)) return NULL; int result = PyObject_IsTrue(func_matcher); if (result < 0) return NULL; if (!result) func_matcher = NULL; result = PyObject_IsTrue(var_matcher); if (result < 0) return NULL; if (!result) var_matcher = NULL; if (file_buff[file_size] != '\0') { PyErr_SetString(PyExc_ValueError, "file_buff should end in NULL"); return NULL; } if(envvar_callback) { int true_ret = PyObject_IsTrue(envvar_callback); if(-1 == true_ret) { goto filter_env_cleanup; } if(!true_ret) { envvar_callback = (PyObject *)NULL; } } res_p = (char *)process_scope( out, file_buff, file_buff, file_buff + file_size, var_matcher, func_matcher, '\0', envvar_callback); filter_env_cleanup: if (!res_p) { if (!PyErr_Occurred()) { PyErr_SetString(PyExc_ValueError, "Parsing failed"); } return NULL; } Py_RETURN_NONE; }
static const char * process_scope(PyObject *out, const char *start, const char *buff, const char *end, PyObject *var_matcher, PyObject *func_matcher, const char endchar, PyObject *envvar_callback) { const char *p = NULL; const char *window_start = NULL, *window_end = NULL; const char *new_p = NULL; const char *com_start = NULL; char *s = NULL; char *e = NULL; char *temp_string = NULL; regmatch_t matches[3]; p = buff; matches[0].rm_so = matches[1].rm_so = matches[2].rm_so = -1; window_start = buff; window_end = NULL; while (p < end && *p != endchar) { /* wander forward to the next non space */ if (window_end != NULL) { if (out) { PyObject *string = PyString_FromStringAndSize( window_start, window_end - window_start); if (!string) return NULL; PyObject *result = PyObject_CallMethodObjArgs( out, write_str, string, NULL); Py_DECREF(string); if (!result) return NULL; Py_DECREF(result); } window_start = p; window_end = NULL; } com_start = p; if (isspace(*p)) { ++p; continue; } /* ignore comments */ if (*p == '#') { p = walk_statement_pound(start, p, endchar); continue; } if(NULL != (new_p = is_function(p, &s, &e))) { if(-1 == asprintf(&temp_string, "%.*s", (int)(e - s), s)) return NULL; INFO("matched func name '%s'", temp_string); /* output it if it doesn't match */ new_p = process_scope( NULL, start, new_p, end, NULL, NULL, '}', NULL); INFO("ended processing '%s'", temp_string); if (func_matcher) { int regex_result = regex_matches(func_matcher, temp_string); if (-1 == regex_result) { free(temp_string); return NULL; } if (regex_result) { /* well, it matched. so it gets skipped. */ INFO("filtering func '%s'", temp_string); window_end = com_start; } } free(temp_string); if(!new_p) return NULL; p = new_p; ++p; continue; } // check for env assignment if (NULL == (new_p = is_envvar(p, &s, &e))) { //exactly as it sounds, non env assignment. p = walk_command_complex(start, p, end, endchar, COMMAND_PARSING); if (!p) return NULL; // icky icky icky icky if (p < end && *p != endchar) ++p; } else { //env assignment if(-1 == asprintf(&temp_string, "%.*s", (int)(e - s), s)) return NULL; INFO("matched env assign '%s'", temp_string); do_envvar_callback(envvar_callback, temp_string); if (var_matcher) { int regex_result = regex_matches(var_matcher, temp_string); if (-1 == regex_result) { free(temp_string); return NULL; } if (regex_result) { //this would be filtered. INFO("filtering var '%s'", temp_string); window_end = com_start; } } free(temp_string); p = new_p; if (p >= end) { return p; } while(p < end && !isspace(*p) && ';' != *p) { if ('\'' == *p) p = walk_statement_no_parsing(p + 1, end, '\'') + 1; else if ('"' == *p || '`' == *p) p = walk_command_escaped_parsing(start, p + 1, end, *p) + 1; else if ('(' == *p) { p = walk_command_escaped_parsing(start, p + 1, end, ')') + 1; } else if ('$' == *p) { ++p; if (p >= end) { continue; } p = walk_dollar_expansion(start, p, end, endchar, endchar); continue; } else { // blah=cah ; single word. p = walk_command_complex(start, p, end, ' ', SPACE_PARSING); if (!p) { return NULL; } } } } } if (out) { if (window_end == NULL) window_end = p; if (window_end > end) window_end = end; PyObject *string = PyString_FromStringAndSize( window_start, window_end - window_start); if (!string) return NULL; PyObject *result = PyObject_CallMethodObjArgs( out, write_str, string, NULL); Py_DECREF(string); if (!result) return NULL; Py_DECREF(result); } return p; }