static void macro_expand_command (char *exp, int from_tty) { struct macro_scope *ms = NULL; char *expanded = NULL; struct cleanup *cleanup_chain = make_cleanup (free_current_contents, &ms); make_cleanup (free_current_contents, &expanded); /* You know, when the user doesn't specify any expression, it would be really cool if this defaulted to the last expression evaluated. Then it would be easy to ask, "Hey, what did I just evaluate?" But at the moment, the `print' commands don't save the last expression evaluated, just its value. */ if (! exp || ! *exp) error (_("You must follow the `macro expand' command with the" " expression you\n" "want to expand.")); ms = default_macro_scope (); if (ms) { expanded = macro_expand (exp, standard_macro_lookup, ms); fputs_filtered ("expands to: ", gdb_stdout); fputs_filtered (expanded, gdb_stdout); fputs_filtered ("\n", gdb_stdout); } else macro_inform_no_debuginfo (); do_cleanups (cleanup_chain); return; }
char* macro_process(rbtree_t* store, struct replay_runtime* runtime, char* text) { char buf[10240]; char* next, *expand; char* at = text; if(!strstr(text, "${")) return strdup(text); /* no macros */ buf[0] = 0; buf[sizeof(buf)-1]=0; while( (next=strstr(at, "${")) ) { /* copy text before next macro */ if((size_t)(next-at) >= sizeof(buf)-strlen(buf)) return NULL; /* string too long */ (void)strlcpy(buf+strlen(buf), at, (size_t)(next-at+1)); /* process the macro itself */ next += 2; expand = macro_expand(store, runtime, &next); if(!expand) return NULL; /* expansion failed */ (void)strlcpy(buf+strlen(buf), expand, sizeof(buf)-strlen(buf)); free(expand); at = next; } /* copy remainder fixed text */ (void)strlcpy(buf+strlen(buf), at, sizeof(buf)-strlen(buf)); return strdup(buf); }
static pobject builtin_macro_expand(pobject env, pobject params) { pobject p = cons_car(params); if (is_cons(p)) { pobject macro = eval(env, cons_car(p)); if (is_macro(macro)) return macro_expand(env, macro, cons_cdr(p)); } return NIL; }
/* * macro_bind * * Lexical binding for macros. Invoked via lexeme_bind when a * macro name is encountered. */ static int macro_bind (lexctx_t lctx, void *vctx, quotelevel_t ql, quotemodifier_t qm, lextype_t lt, condstate_t cs, lexeme_t *lex, lexseq_t *result) { macroctx_t ctx = vctx; name_t *np = lexeme_ctx_get(lex); if (cs == COND_CWA || cs == COND_AWC || ql == QL_MACROSKIP) { lexeme_free(lctx, lex); return 1; } switch (qm) { case QM_QUOTE: lex->type = LEXTYPE_UNBOUND; return 0; case QM_EXPAND: lexeme_free(lctx, lex); return macro_expand(ctx, np, result); case QM_UNQUOTE: lex->type = LEXTYPE_NAME_MACRO; return 0; default: break; } // no quote modifier if (ql == QL_MACRO) { lex->type = LEXTYPE_UNBOUND; return 0; } lexeme_free(lctx, lex); return macro_expand(ctx, np, result); } /* macro_bind */
/** do macro recursion */ static char* do_macro_recursion(rbtree_t* store, struct replay_runtime* runtime, char* at, size_t remain) { char* after = at+2; char* expand = macro_expand(store, runtime, &after); if(!expand) return NULL; /* expansion failed */ if(!do_buf_insert(at, remain, after, expand)) { free(expand); return NULL; } free(expand); return at; /* and parse over the expanded text to see if again */ }
int check_macro (const char *line, sb *expand, const char **error, macro_entry **info) { const char *s; char *copy, *cs; macro_entry *macro; sb line_sb; if (! ISALPHA (*line) && *line != '_' && *line != '$' && (! macro_mri || *line != '.')) return 0; s = line + 1; while (ISALNUM (*s) || *s == '_' || *s == '$') ++s; copy = (char *) alloca (s - line + 1); memcpy (copy, line, s - line); copy[s - line] = '\0'; for (cs = copy; *cs != '\0'; cs++) *cs = TOLOWER (*cs); macro = (macro_entry *) hash_find (macro_hash, copy); if (macro == NULL) return 0; /* Wrap the line up in an sb. */ sb_new (&line_sb); while (*s != '\0' && *s != '\n' && *s != '\r') sb_add_char (&line_sb, *s++); sb_new (expand); *error = macro_expand (0, &line_sb, macro, expand); sb_kill (&line_sb); /* Export the macro information if requested. */ if (info) *info = macro; return 1; }
// // SLOT // load up a configuration file void QEpicsAcqLocal::setConfigFile( const QString &cfname) { if( running) // software fails miserably if an attempt is made to rebuild the return; // scan configuration while tasks are runnning! if( cfname.isEmpty() ) // can't delete by setting a null file name. return; char expand[512]; config_file = cfname; macro_expand(cfname.toAscii().constData(), expand, NULL); acq_file_load( expand, master); showMode(AS_OFF); threadTimerLock.lock(); // emit onNewConfig(); signalOnNewConfig = TRUE; threadTimerLock.unlock(); }
value_t compile(value_t expr, value_t next) { value_t result; expr = macro_expand(expr); protect_value(expr); if (is_symbol(expr)) { result = make_list(OP_LOOKUP, expr, next, 0); } else if (is_pair(expr)) { result = compile_form(expr, next); } else if (expr == EMPTY_LIST) { error(1, 0, "Illegal empty combination ()"); } else { result = make_list(OP_CONSTANT, expr, next, 0); } unprotect_storage(1); return result; }
static struct varnish * varnish_new(const char *name) { struct varnish *v; struct vsb *vsb; char buf[1024]; AN(name); ALLOC_OBJ(v, VARNISH_MAGIC); AN(v); REPLACE(v->name, name); v->vl = vtc_logopen(name); AN(v->vl); bprintf(buf, "${tmpdir}/%s", name); vsb = macro_expand(v->vl, buf); AN(vsb); v->workdir = strdup(VSB_data(vsb)); AN(v->workdir); VSB_delete(vsb); bprintf(buf, "rm -rf %s ; mkdir -p %s ; echo ' %ld' > %s/_S", v->workdir, v->workdir, random(), v->workdir); AZ(system(buf)); if (*v->name != 'v') vtc_log(v->vl, 0, "Varnish name must start with 'v'"); v->args = VSB_new_auto(); v->storage = VSB_new_auto(); VSB_printf(v->storage, "-sfile,%s,10M", v->workdir); AZ(VSB_finish(v->storage)); v->cli_fd = -1; VTAILQ_INSERT_TAIL(&varnishes, v, list); return (v); }
/* * determine the value based on the 'have' flag, the macro string, and the stored value. * if the macro string is not in a macro form, it is the reponsibility of the calling application * to have interpreted the string and placed a reasonable value in the 'setting' field. * Otherwise, the string is expanded, and on a successful expanson to a value that can * be interpreted as a double this is returned. In the event of expansion failure, it is\ * assumed that there is no actual value. */ static int find_scanRecord_value( unsigned int haveSetting, double setting, char *macro, double *result) { double val; char expanded[100]; char *last; if( haveSetting == 0) return 0; if( macro && *macro == '$') { macro_expand(macro, expanded, NULL); val = strtod(expanded, &last); if( last != expanded) { *result = val; return 1; } return 0; } *result = setting; return 1; }
void Preprocess::macro_expand(const Token& token) { const string& s = token.str; macro_type& vec = macros_map[s]; if (vec.kind == tok::macfunc_type) { macro_expand_func(token); } else { assert(vec.kind == tok::macobj_type); avoid_recursion.insert(s); for (std::vector<Token>::iterator i = vec.expand.begin(); i != vec.expand.end(); ++i) { Token tok = *i; if (macros_map.find(tok.str) == macros_map.end()) // { macros_buffer.push_back(tok); } else if(avoid_recursion.find(tok.str) != avoid_recursion.end()) { macros_buffer.push_back(tok); } else { macro_expand(tok); } } avoid_recursion.erase(s); } }
void parse_string(const char *spec, const struct cmds *cmd, void *priv, struct vtclog *vl) { char *token_s[MAX_TOKENS], *token_e[MAX_TOKENS]; struct vsb *token_exp[MAX_TOKENS]; char *p, *q, *f, *buf; int nest_brace; int tn; const struct cmds *cp; AN(spec); buf = strdup(spec); AN(buf); for (p = buf; *p != '\0'; p++) { if (vtc_error || vtc_stop) break; /* Start of line */ if (isspace(*p)) continue; if (*p == '\n') continue; if (*p == '#') { for (; *p != '\0' && *p != '\n'; p++) ; if (*p == '\0') break; continue; } q = strchr(p, '\n'); if (q == NULL) q = strchr(p, '\0'); if (q - p > 60) vtc_log(vl, 2, "=== %.60s...", p); else vtc_log(vl, 2, "=== %.*s", (int)(q - p), p); /* First content on line, collect tokens */ tn = 0; f = p; while (*p != '\0') { assert(tn < MAX_TOKENS); if (*p == '\n') { /* End on NL */ break; } if (isspace(*p)) { /* Inter-token whitespace */ p++; continue; } if (*p == '\\' && p[1] == '\n') { /* line-cont */ p += 2; continue; } if (*p == '"') { /* quotes */ token_s[tn] = ++p; q = p; for (; *p != '\0'; p++) { if (*p == '"') break; if (*p == '\\') { p += VAV_BackSlash(p, q) - 1; q++; } else { if (*p == '\n') vtc_log(vl, 0, "Unterminated quoted string in line: %*.*s", (int)(p - f), (int)(p - f), f); assert(*p != '\n'); *q++ = *p; } } token_e[tn++] = q; p++; } else if (*p == '{') { /* Braces */ nest_brace = 0; token_s[tn] = p + 1; for (; *p != '\0'; p++) { if (*p == '{') nest_brace++; else if (*p == '}') { if (--nest_brace == 0) break; } } assert(*p == '}'); token_e[tn++] = p++; } else { /* other tokens */ token_s[tn] = p; for (; *p != '\0' && !isspace(*p); p++) ; token_e[tn++] = p; } } assert(tn < MAX_TOKENS); token_s[tn] = NULL; for (tn = 0; token_s[tn] != NULL; tn++) { token_exp[tn] = NULL; AN(token_e[tn]); /*lint !e771 */ *token_e[tn] = '\0'; /*lint !e771 */ if (NULL == strstr(token_s[tn], "${")) continue; token_exp[tn] = macro_expand(vl, token_s[tn]); if (vtc_error) { return; } token_s[tn] = VSB_data(token_exp[tn]); token_e[tn] = strchr(token_s[tn], '\0'); } for (cp = cmd; cp->name != NULL; cp++) if (!strcmp(token_s[0], cp->name)) break; if (cp->name == NULL) { vtc_log(vl, 0, "Unknown command: \"%s\"", token_s[0]); return; } assert(cp->cmd != NULL); cp->cmd(token_s, priv, cmd, vl); } }
static void read_lines(char *filename, FILE *fp) { verify(filename != NULL, "null arg filename"); verify(filename[0] != '\0', "empty arg filename"); verify(fp != NULL, "null arg fp"); if (verbose > 0) { fprintf(stderr, "%s: read_lines(%s)\n", prog, filename); } char original[MAXLINE+2]; // from fgets() char expanded[MAXLINE+2]; // after macro expansion char buffer[MAXLINE+2]; // working copy, safe to modify char whsp[] = " \t\n\v\f\r"; // whitespace characters int line_number = 0; int recipe_line_number = 0; while (fgets(original, MAXLINE, fp) != NULL) { // it is possible that the input line was too long, so terminate the string cleanly original[MAXLINE] = '\n'; original[MAXLINE+1] = '\0'; line_number++; if (verbose > 0) printf("%s: %s: line %d: %s", prog, filename, line_number, original); // assume original[] is constructed properly // assume expanded[] is large enough macro_expand(original, expanded); if (verbose > 0) printf("%s: %s: line %d: %s", prog, filename, line_number, expanded); strcpy(buffer, expanded); // copy, safe to modify char *buf = buffer; while (*buf == ' ') buf++; // skip past leading spaces (not tabs!) char *p_hash = strchr(buf, '#'); // a comment starts with # if (p_hash != NULL) { *p_hash = '\0'; } // remove the comment int n = 0; // remove trailing whitespace while (buf[n] != '\0') { int n1 = strspn(&buf[n], whsp); // buf[n .. n+n1-1] is whitespace int n2 = strcspn(&buf[n + n1], whsp); // buf[n+n1 .. n+n1+n2-1] is not if (n2 == 0) { buf[n] = '\0'; break; } // remove trailing whitespace n += n1 + n2; } if (buf[0] == '\0') // nothing left? { continue; } char *p_colon = strchr(buf, ':'); // : indicates a target-prerequisite line char *p_equal = strchr(buf, '='); // = indicates a macro definition if (buffer[0] == '\t') { recipe_line_number++; if (verbose > 0) printf(" >>> recipe line %d\n", recipe_line_number); // (save this for a later project) } else if (p_colon != NULL) { recipe_line_number = 0; if (verbose > 0) printf(" >>> target-prerequisite\n"); // (save this for a later project) } else if (p_equal != NULL) { if (verbose > 0) printf(" >>> macro definition\n"); // name = body // *p_equal is '=' char *name_start = buf; while (*name_start == ' ' || *name_start == '\t') // skip past spaces and tabs { name_start++; } char *name_end = p_equal-1; while (*name_end == ' ' || *name_end == '\t') { name_end--; } name_end++; *name_end = '\0'; char *body_start = p_equal+1; while (*body_start == ' ' || *body_start == '\t') { body_start++; } char *body_end = body_start; while (*body_end != '\0') // end of string { body_end++; } while (*body_end == ' ' || *body_end == '\t') { body_end--; } body_end++; *body_end = '\0'; if (verbose > 1) macro_list_print(); macro_set(name_start, body_start); if (verbose > 1) macro_list_print(); } else if (strncmp("include", buf, 7) == 0) { if (verbose > 0) printf(" >>> include\n"); char *name_start = buf + 7; // skip past "include" while (*name_start == ' ' || *name_start == '\t') // skip past spaces and tabs { name_start++; } if (*name_start == '\0') { // following GNU Make, this is not an error if (verbose > 0) fprintf(stderr, "%s: %s: line %d: include but no filename\n", prog, filename, line_number); continue; } else if (*name_start == '\'' || *name_start == '"') // quoted filename { // find matching quote, remove it char *q = name_start + 1; // skip past ' or " while (*q != *name_start && *q != '\0') q++; // find end of string or line if (*q == '\0') { fprintf(stderr, "%s: %s: line %d: file name error: >>>%s<<<\n", prog, filename, line_number, name_start); continue; } name_start++; // skip past opening quote *q = '\0'; // remove closing quote } read_file(name_start, 0); } else { if (verbose > 0) printf(" >>> something else\n"); fprintf(stderr, "%s: %s: line %d: not recognized: %s", prog, filename, line_number, original); } } if (ferror(fp)) // error when reading the file { fprintf(stderr, "%s: %s: read error: %s\n", prog, filename, strerror(errno)); } return; }
static void read_lines(char *filename, FILE *fp) { // if (verbose > 0) // { fprintf(stderr, "%s: read_lines(%s)\n", prog, filename); } char original[MAXLINE+2]; // from fgets() char expanded[MAXLINE+2]; // after macro expansion char buffer[MAXLINE+2]; // working copy, safe to modify char whsp[] = " \t\n\v\f\r"; // whitespace characters int line_number = 0; int recipe_line_number = 0; bool have_target = false; // recipes must follow targets while (fgets(original, MAXLINE, fp) != NULL) { // it is possible that the input line was too long, so terminate the string cleanly original[MAXLINE] = '\n'; original[MAXLINE+1] = '\0'; line_number++; if (verbose > 0) printf("%s: %s: line %d: %s\n", "prog", filename, line_number, original); // assume original[] is constructed properly // assume expanded[] is large enough macro_expand(original, expanded); if (verbose > 0) printf("%s: %s: line %d: %s\n", "prog", filename, line_number, expanded); strcpy(buffer, expanded); // copy, safe to modify char *buf = buffer; while (*buf == ' ') buf++; // skip past leading spaces (not tabs!) char *p_hash = strchr(buf, '#'); // a comment starts with # if (p_hash != NULL) { *p_hash = '\0'; } // remove the comment int n = 0; // remove trailing whitespace while (buf[n] != '\0') { int n1 = strspn(&buf[n], whsp); // buf[n .. n+n1-1] is whitespace int n2 = strcspn(&buf[n + n1], whsp); // buf[n+n1 .. n+n1+n2-1] is not if (n2 == 0) { buf[n] = '\0'; break; } // remove trailing whitespace n += n1 + n2; } if (buf[0] == '\0') // nothing left? { continue; } char *p_colon = strchr(buf, ':'); // : indicates a target-prerequisite line char *p_equal = strchr(buf, '='); // = indicates a macro definition if (buffer[0] == '\t') { recipe_line_number++; if (verbose > 0) printf(" diagnosis: recipe line %d\n", recipe_line_number); if (have_target == false) { fprintf(stderr, "%s: %s: line %d: recipe but no target\n", prog, filename, line_number); continue; } int count = 0; while(*(buffer+1+count) != '\0') { count++; } char *recipe_temp = malloc((count+1)*sizeof(char)); set_chars(recipe_temp, buffer+1); struct target* temp_update_target = find_target(first_related_target); for(int i = 0; i < target_length; i++) { temp_update_target->target_recipes = add_recipe(temp_update_target->target_recipes, recipe_temp); if(target_length > 1) temp_update_target = temp_update_target->next; } } else if (p_colon != NULL) { first_related_target = NULL; target_length = 0; recipe_line_number = 0; if (verbose > 0) printf(" diagnosis: target-prerequisite\n"); have_target = true; char *source_start = p_colon+1; while(*source_start == ' ') { source_start++; } char *source_end = source_start; struct source *source_head = malloc(sizeof(struct source)); if(source_head == NULL) { printf("Malloc failed to allocate space for a source_head in the main program\n"); return; } if(*source_end == '\n' || *source_end == '\0' || *source_end == '\r') { source_head = add_source(source_head, ""); } while(*source_end != '\n' && *source_end != '\0' && *source_end != '\r') { if(*source_end == ' ' || *source_end == '\0') { *source_end = '\0'; int count = 0; while(*(source_start+count) != '\0') { count++; } char *source_temp = malloc((count+1)*sizeof(char)); set_chars(source_temp, source_start); source_head = add_source(source_head, source_temp); source_start = source_end+1; } if(*(source_end+1) == '\0') { int count = 0; while(*(source_start+count) != '\0') { count++; } char *source_temp = malloc((count+1)*sizeof(char)); set_chars(source_temp, source_start); source_head = add_source(source_head, source_temp); } source_end++; } char *tar_start = buf; while(*tar_start == ' ') { tar_start++; } char *tar_end = tar_start; while(*tar_end != ':' && *tar_end != '\0') { if(*tar_end == ' ' || *tar_end == '\t') { *tar_end = '\0'; if(default_goal == NULL) { int count = 0; while(*(tar_start+count) != '\0') { count++; } default_goal = malloc((count+1)*sizeof(char)); set_chars(default_goal, tar_start); } struct recipe* super_temp = malloc(sizeof(struct recipe)); super_temp->line = "replaceme"; char* temp = malloc(30 * sizeof(char)); set_chars(temp, tar_start); add_target(temp, source_head, super_temp); if(first_related_target == NULL) { int count = 0; while(*(tar_start+count) != '\0') { count++; } first_related_target = malloc((count+1)*sizeof(char)); if (first_related_target == NULL) { printf("malloc failed\n"); } for(int i = 0; i < count+2; i++) { *(first_related_target+i) = *(tar_start+i); } } target_length++; tar_start = (tar_end+1); } if(*(tar_end+1) == ':' ) { if(*(tar_end) != ' ') { int count = 0; while(*(tar_start+count) != ':') { count++; } *(tar_end+1) = '\0'; char *tar_temp = malloc((count+1)*sizeof(char)); set_chars(tar_temp, tar_start); struct recipe* super_temp = malloc(sizeof(struct recipe)); super_temp->line = "replaceme"; add_target(tar_temp, source_head, super_temp); if(first_related_target == NULL) { int count = 0; while(*(tar_start+count) != '\0') { count++; } first_related_target = malloc((count+1)*sizeof(char)); if (first_related_target == NULL) { printf("malloc failed\n"); } set_chars(first_related_target, tar_start); } } } tar_end++; } } else if (p_equal != NULL) { first_related_target = NULL; target_length = 0; if (verbose > 0) printf(" diagnosis: macro definition\n"); have_target = false; // name = body // *p_equal is '=' char *name_start = buf; while (*name_start == ' ' || *name_start == '\t') // skip past spaces and tabs { name_start++; } char *name_end = p_equal-1; while (*name_end == ' ' || *name_end == '\t') { name_end--; } name_end++; *name_end = '\0'; char *body_start = p_equal+1; while (*body_start == ' ' || *body_start == '\t') { body_start++; } char *body_end = body_start; while (*body_end != '\0') // end of string { body_end++; } while (*body_end == ' ' || *body_end == '\t') { body_end--; } body_end++; *body_end = '\0'; if (verbose > 1) macro_list_print(); macro_set(name_start, body_start); if (verbose > 1) macro_list_print(); } else if (strncmp("include", buf, 7) == 0) { first_related_target = NULL; target_length = 0; if (verbose > 0) printf(" diagnosis: include\n"); have_target = false; char *name_start = buf + 7; // skip past "include" while (*name_start == ' ' || *name_start == '\t') // skip past spaces and tabs { name_start++; } if (*name_start == '\0') { // following GNU Make, this is not an error if (verbose > 0) fprintf(stderr, "%s: %s: line %d: include but no filename\n", prog, filename, line_number); continue; } else if (*name_start == '\'' || *name_start == '"') // quoted filename { // find matching quote, remove it char *q = name_start + 1; // skip past ' or " while (*q != *name_start && *q != '\0') q++; // find end of string or line if (*q == '\0') { fprintf(stderr, "%s: %s: line %d: file name error [%s]\n", prog, filename, line_number, name_start); continue; } name_start++; // skip past opening quote *q = '\0'; // remove closing quote } pr8_read(name_start); } else { if (verbose > 0) printf(" diagnosis: something else\n"); have_target = false; // fprintf(stderr, "%s: %s: line %d: not recognized: %s", prog, filename, line_number, original); } } // if (ferror(fp)) // error when reading the file // { fprintf(stderr, "%s: %s: read error: %s\n", prog, filename, strerror(errno)); } return; }
static void varnish_launch(struct varnish *v) { struct vsb *vsb, *vsb1; int i, nfd, nap; struct vss_addr **ap; char abuf[128], pbuf[128]; struct pollfd fd[2]; enum VCLI_status_e u; char *r; v->vd = VSM_New(); VSC_Setup(v->vd); /* Create listener socket */ nap = VSS_resolve("127.0.0.1", "0", &ap); AN(nap); v->cli_fd = VSS_listen(ap[0], 1); VTCP_myname(v->cli_fd, abuf, sizeof abuf, pbuf, sizeof pbuf); AZ(VSB_finish(v->args)); vtc_log(v->vl, 2, "Launch"); vsb = VSB_new_auto(); AN(vsb); VSB_printf(vsb, "cd ${pwd} &&"); VSB_printf(vsb, " ${varnishd} -d -d -n %s", v->workdir); VSB_printf(vsb, " -l 10m,1m,-"); VSB_printf(vsb, " -p auto_restart=off"); VSB_printf(vsb, " -p syslog_cli_traffic=off"); VSB_printf(vsb, " -a '%s'", "127.0.0.1:0"); VSB_printf(vsb, " -S %s/_S", v->workdir); VSB_printf(vsb, " -M '%s %s'", abuf, pbuf); VSB_printf(vsb, " -P %s/varnishd.pid", v->workdir); VSB_printf(vsb, " %s", VSB_data(v->storage)); VSB_printf(vsb, " %s", VSB_data(v->args)); AZ(VSB_finish(vsb)); vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb)); vsb1 = macro_expand(v->vl, VSB_data(vsb)); AN(vsb1); VSB_delete(vsb); vsb = vsb1; vtc_log(v->vl, 3, "CMD: %s", VSB_data(vsb)); AZ(pipe(&v->fds[0])); AZ(pipe(&v->fds[2])); v->pid = fork(); assert(v->pid >= 0); if (v->pid == 0) { assert(dup2(v->fds[0], 0) == 0); assert(dup2(v->fds[3], 1) == 1); assert(dup2(1, 2) == 2); AZ(close(v->fds[0])); AZ(close(v->fds[1])); AZ(close(v->fds[2])); AZ(close(v->fds[3])); for (i = 3; i <getdtablesize(); i++) (void)close(i); AZ(execl("/bin/sh", "/bin/sh", "-c", VSB_data(vsb), (char*)0)); exit(1); } else { vtc_log(v->vl, 3, "PID: %ld", (long)v->pid); } AZ(close(v->fds[0])); AZ(close(v->fds[3])); v->fds[0] = v->fds[2]; v->fds[2] = v->fds[3] = -1; VSB_delete(vsb); AZ(pthread_create(&v->tp, NULL, varnish_thread, v)); AZ(pthread_create(&v->tp_vsl, NULL, varnishlog_thread, v)); /* Wait for the varnish to call home */ memset(fd, 0, sizeof fd); fd[0].fd = v->cli_fd; fd[0].events = POLLIN; fd[1].fd = v->fds[0]; fd[1].events = 0; /* Only care about POLLHUP, which is output-only */ i = poll(fd, 2, 10000); vtc_log(v->vl, 4, "CLIPOLL %d 0x%x 0x%x", i, fd[0].revents, fd[1].revents); if (i == 0) { vtc_log(v->vl, 0, "FAIL timeout waiting for CLI connection"); return; } if (fd[1].revents & POLLHUP) { vtc_log(v->vl, 0, "FAIL debug pipe closed"); return; } if (!(fd[0].revents & POLLIN)) { vtc_log(v->vl, 0, "FAIL CLI connection wait failure"); return; } nfd = accept(v->cli_fd, NULL, NULL); if (nfd < 0) { vtc_log(v->vl, 0, "FAIL no CLI connection accepted"); return; } AZ(close(v->cli_fd)); v->cli_fd = nfd; vtc_log(v->vl, 3, "CLI connection fd = %d", v->cli_fd); assert(v->cli_fd >= 0); /* Receive the banner or auth response */ u = varnish_ask_cli(v, NULL, &r); if (vtc_error) return; if (u != CLIS_AUTH) vtc_log(v->vl, 0, "CLI auth demand expected: %u %s", u, r); bprintf(abuf, "%s/_S", v->workdir); nfd = open(abuf, O_RDONLY); assert(nfd >= 0); assert(sizeof abuf >= CLI_AUTH_RESPONSE_LEN + 7); strcpy(abuf, "auth "); VCLI_AuthResponse(nfd, r, abuf + 5); AZ(close(nfd)); free(r); strcat(abuf, "\n"); u = varnish_ask_cli(v, abuf, &r); if (vtc_error) return; if (u != CLIS_OK) vtc_log(v->vl, 0, "CLI auth command failed: %u %s", u, r); free(r); (void)VSL_Arg(v->vd, 'n', v->workdir); AZ(VSC_Open(v->vd, 1)); }
/* * Substitute the arguments args appearing in the input sequence is * Result is created in the output sequence os and finally has the specified * hide set added to it, before getting returned. */ static PtokenSequence subst(const Macro &m, dequePtoken is, const mapArgval &args, HideSet hs, bool skip_defined, const Macro *caller) { PtokenSequence os; // output sequence while (!is.empty()) { if (DP()) cout << "subst: is=" << is << " os=" << os << endl; const Ptoken head(is.front()); is.pop_front(); // is is now the tail dequePtoken::iterator ti, ti2; mapArgval::const_iterator ai; switch (head.get_code()) { case '#': // Stringizing operator ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); os.push_back(stringize(ai->second)); continue; } break; case CPP_CONCAT: ti = find_nonspace(is.begin(), is.end()); if (ti != is.end()) { if ((ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); if (ai->second.size() != 0) // Only if actuals can be empty os = glue(os, ai->second); } else { PtokenSequence t(ti, ti + 1); is.erase(is.begin(), ++ti); os = glue(os, t); } continue; } break; default: ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && ti->get_code() == CPP_CONCAT) { /* * Implement the following gcc extension: * "`##' before a * rest argument that is empty discards the preceding sequence of * non-whitespace characters from the macro definition. (If another macro * argument precedes, none of it is discarded.)" * Otherwise, break to process a non-formal argument in the default way */ if ((ai = find_formal_argument(args, head)) == args.end()) { if (m.get_is_vararg()) { ti2 = find_nonspace(ti + 1, is.end()); if (ti2 != is.end() && (ai = find_formal_argument(args, *ti2)) != args.end() && ai->second.size() == 0) { // All conditions satisfied; discard elements: // <non-formal> <##> <empty-formal> is.erase(is.begin(), ++ti2); continue; } } break; // Non-formal arguments don't deserve special treatment } // Paste but not expand LHS, RHS if (ai->second.size() == 0) { // Only if actuals can be empty is.erase(is.begin(), ++ti); // Erase including ## ti = find_nonspace(is.begin(), is.end()); if (ti != is.end() && (ai = find_formal_argument(args, *ti)) != args.end()) { is.erase(is.begin(), ++ti); // Erase the ## RHS PtokenSequence actual(ai->second); os.splice(os.end(), actual); } } else { is.erase(is.begin(), ti); // Erase up to ## PtokenSequence actual(ai->second); os.splice(os.end(), actual); } continue; } if ((ai = find_formal_argument(args, head)) == args.end()) break; // Othewise expand head PtokenSequence expanded(macro_expand(ai->second, false, skip_defined, caller)); os.splice(os.end(), expanded); continue; } os.push_back(head); } return (hsadd(hs, os)); }
/* We have been given a filename describing where we should get our executable from. That name could be of the form "<hostname>:<pathname>", or it could just be <pathname>. Also the <pathname> part could contain macros to be looked up in our config file. We do that macro expansion here, and also check the <hostname> part. If the hostname refers to our own host, we set "on_this_host" to TRUE and if it refers to the submitting host, we set it to FALSE. For now, it is an error if it refers to some third host. We then ruturn a pointer to the macro expanded pathname in a static data area. The pathname could also be an AFS file, in which case we can also access the file with a symlink. The form is "/afs/...". */ char * UserProc::expand_exec_name( int &on_this_host ) { char *host_part; char *path_part; char *tmp; char *a_out; int status; a_out = NULL; status = REMOTE_CONDOR_get_a_out_name( a_out ); if( status < 0 || a_out == NULL ) { EXCEPT( "Can't get name of a.out file" ); } if( strchr(a_out,':') ) { // form is <hostname>:<path> host_part = strtok( a_out, " \t:" ); if( host_part == NULL ) { EXCEPT( "Can't find host part" ); } path_part = strtok( NULL, " \t:"); if( path_part == NULL ) { EXCEPT( "Can't find path part" ); } if( strcmp(host_part,ThisHost) == MATCH ) { on_this_host = TRUE; } else { if( strcmp(host_part,InitiatingHost) == MATCH ) { on_this_host = FALSE; } else { EXCEPT( "Unexpected host_part \"%s\", ThisHost %s", host_part, ThisHost ); } } } else if( strncmp("/afs",a_out,4) == MATCH ) { on_this_host = TRUE; path_part = a_out; } else { // form is <path> on_this_host = FALSE; path_part = a_out; } // expand macros in the pathname part tmp = macro_expand( path_part ); free( m_a_out ); m_a_out = strdup( tmp ); FREE( tmp ); free(a_out); if( on_this_host ) { if( access(m_a_out,X_OK) == 0 ) { dprintf( D_ALWAYS, "Executable is located on this host\n" ); } else { dprintf( D_FAILURE|D_ALWAYS, "Executable located on this host - but not executable\n" ); on_this_host = FALSE; } } else { dprintf( D_ALWAYS, "Executable is located on submitting host\n" ); } dprintf( D_ALWAYS, "Expanded executable name is \"%s\"\n", m_a_out ); return m_a_out; }
static void read_lines(char *filename, FILE *fp) { verify(filename != NULL, "null arg filename"); verify(filename[0] != '\0', "empty arg filename"); verify(fp != NULL, "null arg fp"); fprintf(stderr, "%s: read_lines(%s)\n", prog, filename); char original[MAXLINE+2]; // from fgets() char expanded[MAXLINE+2]; // after macro expansion char buffer[MAXLINE+2]; // working copy, safe to modify char whsp[] = " \t\n\v\f\r"; // whitespace characters int line_number = 0; int recipe_line_number = 0; while (fgets(original, MAXLINE, fp) != NULL) { // it is possible that the input line was too long, so terminate the string cleanly original[MAXLINE] = '\n'; original[MAXLINE+1] = '\0'; line_number++; //printf("%s: %s: line %d: %s", prog, filename, line_number, original); // assume original[] is constructed properly // assume expanded[] is large enough macro_expand(original, expanded); printf("%s: %s: line %d: %s", prog, filename, line_number, expanded); strcpy(buffer, expanded); // copy, safe to modify char *buf = buffer; while (*buf == ' ') buf++; // skip past leading spaces (not tabs!) char *p_hash = strchr(buf, '#'); // a comment starts with # if (p_hash != NULL) { *p_hash = '\0'; } // remove the comment int n = 0; // remove trailing whitespace while (buf[n] != '\0'){ int n1 = strspn(&buf[n], whsp); // buf[n .. n+n1-1] is whitespace int n2 = strcspn(&buf[n + n1], whsp); // buf[n+n1 .. n+n1+n2-1] is not if (n2 == 0) { buf[n] = '\0'; break; } // remove trailing whitespace n += n1 + n2; } if (buf[0] == '\0') { // nothing left? continue; } char *p_colon = strchr(buf, ':'); // : indicates a target-prerequisite line char *p_equal = strchr(buf, '='); // = indicates a macro definition // ---------------------------Recipes--------------------------------------------------------- if (buffer[0] == '\t') { recipe_line_number++; //printf(" >>> recipe line %d\n", recipe_line_number); // the target that is before the recipe struct target *myTarget = tg_list.head; if ( myTarget != NULL) { myTarget->rp_list.head = NULL; myTarget->rp_list.tail = NULL; // (save this for a later project) char *recipe = Malloc(128*sizeof(char *)); int i = 1; for(; buffer[i] != '\0'; i++) { recipe[i-1] = buffer[i]; } recipe[i] = '\0'; list_recipes_append(&(myTarget->rp_list), recipe); } } // --------------------------------Targets-------------------------------------------------------- else if (p_colon != NULL) { recipe_line_number = 0; // printf(" >>> target-prerequisite\n"); // (save this for a later project) char *target = Malloc(128 * sizeof(char *)); int i = 0; //printf("%s\n",buffer); // store target to the list while(buffer[i] != ':' && buffer[i] != ' ') { target[i] = buffer[i]; i++; } target[i] = '\0'; list_targets_append(&tg_list, target); struct target *myTarget = target_lookup(tg_list, target); // --------------------------------Sources------------------------------------------------------ //struct list_sources sc_list = *(myTarget->sc_list); myTarget->sc_list.head = NULL; myTarget->sc_list.tail = NULL; // store source to the list // skip all the spaces and ':', and go to the first source while(buffer[i] == ' ' || buffer[i] == ':' ) { i++; } // store sources to the list while(buffer[i] != '\0') { // not terminate until the end of line if( isalpha(buffer[i]) ) { char* source = Malloc(128*sizeof(char)); assert(source != NULL); int j=0; while( isalpha(buffer[i]) ) { source[j] = buffer[i]; // printf("source: %s\n", source); j++; i++; } list_sources_append(&(myTarget->sc_list), source); } else { // skip one whitespace i++; } } } // --------------------------------Macros----------------------------------------------------- else if (p_equal != NULL){ // printf(" >>> macro definition\n"); // name = body // *p_equal is '=' char *name_start = buf; while (*name_start == ' ' || *name_start == '\t') // skip past spaces and tabs { name_start++; } char *name_end = p_equal-1; while (*name_end == ' ' || *name_end == '\t') { name_end--; } name_end++; *name_end = '\0'; char *body_start = p_equal+1; while (*body_start == ' ' || *body_start == '\t') { body_start++; } char *body_end = body_start; while (*body_end != '\0') // end of string { body_end++; } while (*body_end == ' ' || *body_end == '\t') { body_end--; } body_end++; *body_end = '\0'; macro_list_print(); macro_set(name_start, body_start); macro_list_print(); } else if (strncmp("include", buf, 7) == 0) { // printf(" >>> include\n"); char *name_start = buf + 7; // skip past "include" while (*name_start == ' ' || *name_start == '\t') { // skip past spaces and tabs name_start++; } if (*name_start == '\0') { // following GNU Make, this is not an error // fprintf(stderr, "%s: %s: line %d: include but no filename\n", prog, filename, line_number); continue; } else if (*name_start == '\'' || *name_start == '"'){ // quoted filename // find matching quote, remove it char *q = name_start + 1; // skip past ' or " while (*q != *name_start && *q != '\0') { q++; // find end of string or line } if (*q == '\0') { fprintf(stderr, "%s: %s: line %d: file name error: >>>%s<<<\n", prog, filename, line_number, name_start); continue; } name_start++; // skip past opening quote *q = '\0'; // remove closing quote } read_file(name_start, 0); } else { printf(" >>> something else\n"); fprintf(stderr, "%s: %s: line %d: not recognized: %s", prog, filename, line_number, original); } } if (ferror(fp)) { // error when reading the file fprintf(stderr, "%s: %s: read error: %s\n", prog, filename, strerror(errno)); } return; }
static callback_ret_t mastermap_callback(CFStringRef key, CFStringRef invalue, void *udata) { char *key_str, *value_str, *value; CFIndex key_len, value_len; char *pmap, *opts; char dir[LINESZ], map[LINESZ], qbuff[LINESZ]; struct loadmaster_cbdata *temp = (struct loadmaster_cbdata *)udata; char *defopts = temp->defopts; char **stack = temp->stack; char ***stkptr = temp->stkptr; CFIndex i; if (trace > 1) { key_str = od_CFStringtoCString(key); value_str = od_CFStringtoCString(invalue); if (key_str != NULL && value_str != NULL) { trace_prt(1, " mastermap_callback called: key %s, value %s\n", key_str, value_str); } free(value_str); free(key_str); } key_len = od_cfstrlen(key); value_len = od_cfstrlen(invalue); if (key_len >= LINESZ || value_len >= LINESZ) return (OD_CB_KEEPGOING); if (key_len < 2 || value_len < 2) return (OD_CB_KEEPGOING); value_str = od_CFStringtoCString(invalue); value = value_str; i = value_len; while (i > 0 && isspace((unsigned char)*value)) { value++; i--; } if (*value == '\0') { free(value_str); return (OD_CB_KEEPGOING); } if (!od_cfstrlcpy(dir, key, key_len)) { free(value_str); return (OD_CB_KEEPGOING); } if (isspace((unsigned char)dir[0]) || dir[0] == '#') { free(value_str); return (OD_CB_KEEPGOING); } if (trace > 1) trace_prt(1, "mastermap_callback: dir= [ %s ]\n", dir); for (i = 0; i < LINESZ; i++) qbuff[i] = ' '; switch (macro_expand("", dir, qbuff, sizeof (dir))) { case MEXPAND_OK: break; case MEXPAND_LINE_TOO_LONG: pr_msg( "%s in Open Directory map: entry too long (max %zu chars)", dir, sizeof (dir) - 1); free(value_str); return (OD_CB_KEEPGOING); case MEXPAND_VARNAME_TOO_LONG: pr_msg( "%s in Open Directory map: variable name too long", dir); free(value_str); return (OD_CB_KEEPGOING); } strlcpy(map, value, sizeof (map)); /* we know this will not truncate */ free(value_str); if (trace > 1) trace_prt(1, "mastermap_callback: map= [ %s ]\n", map); switch (macro_expand("", map, qbuff, sizeof (map))) { case MEXPAND_OK: break; case MEXPAND_LINE_TOO_LONG: pr_msg( "%s in Open Directory map: entry too long (max %zu chars)", map, sizeof (map) - 1); return (OD_CB_KEEPGOING); case MEXPAND_VARNAME_TOO_LONG: pr_msg( "%s in Open Directory map: variable name too long", map); return (OD_CB_KEEPGOING); } pmap = map; while (*pmap && isspace(*pmap)) pmap++; /* skip blanks in front of map */ opts = pmap; while (*opts && !isspace(*opts)) opts++; if (*opts) { *opts++ = '\0'; while (*opts && isspace(*opts)) opts++; if (*opts == '-') opts++; else opts = defopts; } /* * Check for no embedded blanks. */ if (strcspn(opts, " \t") == strlen(opts)) { if (trace > 1) trace_prt(1, "mastermap_callback: dir=[ %s ], pmap=[ %s ]\n", dir, pmap); dirinit(dir, pmap, opts, 0, stack, stkptr); } else { /* XXX - this was "dn=" for LDAP; is that the server name? */ pr_msg( "Warning: invalid entry for %s in Open Directory ignored.\n", dir); } if (trace > 1) trace_prt(1, "mastermap_callback exiting...\n"); return (OD_CB_KEEPGOING); }
int Preprocess::next(Token& tok) { for(;;) { if (!macros_buffer.empty()) { tok = macros_buffer.front(); macros_buffer.pop_front(); return tok.kind; } int t = lex.next(tok, fbuffer); switch(t) { case tok::IFDEF: case tok::IFNDEF: direct_ifdef(t); continue; case tok::IF: direct_if(); continue; case tok::ENDIF: direct_endif(); continue; case tok::ELSE: direct_else(); continue; case tok::ELIF: direct_elif(); continue; default: break; } //if the token in undefined branch if (!c_macro_level.status) continue; switch(t) { default: return t; case tok::INCLUDE: direct_inc(); break; case tok::DEFINE: direct_def(); break; case tok::UNDEF: direct_undef(); break; case tok::IDENT: if (macros_map.find(tok.str) != macros_map.end()) { macro_expand(tok); continue; } else { return t; } break; case tok::LINE: direct_line(); break; case tok::COMMENT: case tok::SCOMMENT: comment(t); break; case tok::TEOF: if (!buffers.empty()) { inc_set.erase(fbuffer->name); delete fbuffer; fbuffer = buffers.top(); buffers.pop(); break; } delete fbuffer; return t; } } assert(0); return tok::TEOF; }
static void FFN(Fdefun)(object args) { object name,oname; object body, form; if (endp(args) || endp(MMcdr(args))) FEtoo_few_argumentsF(args); if (MMcadr(args) != Cnil && !consp(MMcadr(args))) FEerror("~S is an illegal lambda-list.", 1, MMcadr(args)); oname=name = MMcar(args); if (type_of(name) != t_symbol) name=ifuncall1(sSfunid_to_sym,name); if (name->s.s_sfdef != NOT_SPECIAL) { if (name->s.s_mflag) { if (symbol_value(sSAinhibit_macro_specialA) != Cnil) name->s.s_sfdef = NOT_SPECIAL; } else if (symbol_value(sSAinhibit_macro_specialA) != Cnil) FEerror("~S, a special form, cannot be redefined.", 1, name); } if (name->s.s_hpack == lisp_package && name->s.s_gfdef != OBJNULL && !raw_image && sLwarn->s.s_gfdef) { vs_push(make_simple_string("~S is being redefined.")); ifuncall2(sLwarn, vs_head, name); vs_popp; } vs_base = vs_top; if (lex_env[0] == Cnil && lex_env[1] == Cnil && lex_env[2] == Cnil) { vs_push(MMcons(sLlambda_block, args)); } else { vs_push(MMcons(lex_env[2], args)); vs_base[0] = MMcons(lex_env[1], vs_base[0]); vs_base[0] = MMcons(lex_env[0], vs_base[0]); vs_base[0] = MMcons(sLlambda_block_closure, vs_base[0]); } {/* object fname; */ vs_base[0]=fSfset_in(name,vs_base[0]); /* object x=alloc_object(t_ifun); */ /* x->ifn.ifn_self=vs_base[0]; */ /* x->ifn.ifn_name=name; */ /* x->ifn.ifn_call=Cnil; */ /* vs_base[0]=x; */ /* fname = clear_compiler_properties(name,vs_base[0]); */ /* fname->s.s_gfdef = vs_base[0]; */ /* fname->s.s_mflag = FALSE; */ } vs_base[0] = oname; for (body = MMcddr(args); !endp(body); body = body->c.c_cdr) { form = macro_expand(body->c.c_car); if (type_of(form) == t_string) { if (endp(body->c.c_cdr)) break; vs_push(form); name->s.s_plist = putf(name->s.s_plist, form, sSfunction_documentation); vs_popp; break; } if (!consp(form) || form->c.c_car != sLdeclare) break; } }
void Preprocess::macro_expand_func(const Token& token) { Token tok; int t; const string& s = token.str; macro_type& vec = macros_map[s]; assert(vec.kind == tok::macfunc_type); do{ t = lex.next(tok, fbuffer); }while (t == tok::SPACE); // macro followed by ')' don't expand if (t == tok::RPAREN) { macros_buffer.push_back(token); macros_buffer.push_back(tok); } else if (t == tok::LPAREN) { std::vector<string> argus; parse_arguments(argus); if (argus.size() != vec.params.size()) fatal_error("macro " + s + " parameters and arguments size not match"); std::map<string, string> pa_map; int i = 0; for (; i < vec.params.size(); ++i) { pa_map[vec.params[i].str] = argus[i]; } string expands; std::deque<string> dq; avoid_recursion.insert(token.str); for(std::vector<Token>::iterator i = vec.expand.begin(); i != vec.expand.end(); ++i) { // tok follow '\n' don't expand if (avoid_recursion.find(i->str) != avoid_recursion.end()) dq.push_back("\n");//expands += "\n"; if ((pa_map.find(i->str) != pa_map.end())) { dq.push_back(pa_map[i->str]); //expands += pa_map[i->str]; } else { if (i->str == "##") { string p = dq.back(); dq.pop_back(); string n = (++i)->str; dq.push_back(p + n); } if (i->str == "#") { string n = "\"" + (++i)->str + "\""; dq.push_back(n); } //expands += i->str; } } while (!dq.empty()) { expands += dq.front(); dq.pop_front(); } Buffer buffer; buffer.name = fbuffer->name; buffer.line_num = fbuffer->line_num; buffer.column_num = fbuffer->column_num; buffer.ptr = expands.c_str(); buffer.ptr_end = buffer.ptr + expands.length(); buffers.push(fbuffer); fbuffer = &buffer; bool next_expand = true; while ((t = lex.next(tok, &buffer)) != tok::TEOF) { if (t == tok::NEWLINE) { next_expand = false; continue; } if ((macros_map.find(tok.str) != macros_map.end()) && next_expand) { macro_expand(tok); } else macros_buffer.push_back(tok); next_expand = true; } fbuffer = buffers.top(); buffers.pop(); } else { fatal_error("macro " + s + " need arguments"); } avoid_recursion.erase(token.str); }