static int dag_parse_node(struct lexer *bk) { struct token *t = lexer_next_token(bk); if(t->type != TOKEN_FILES) { lexer_report_error(bk, "Error reading rule."); } lexer_free_token(t); struct dag_node *n; n = dag_node_create(bk->d, bk->line_number); if(verbose_parsing && bk->d->nodeid_counter % parsing_rule_mod_counter == 0) { fprintf(stdout, "\rRules parsed: %d", bk->d->nodeid_counter + 1); fflush(stdout); } n->category = bk->category; list_push_tail(n->category->nodes, n); dag_parse_node_filelist(bk, n); bk->environment->node = n; /* Read variables, if any */ while((t = lexer_peek_next_token(bk)) && t->type != TOKEN_COMMAND) { switch (t->type) { case TOKEN_VARIABLE: dag_parse_variable(bk, n); break; default: lexer_report_error(bk, "Expected COMMAND or VARIABLE, got: %s", lexer_print_token(t)); break; } } if(!t) { lexer_report_error(bk, "Rule does not have a command.\n"); } dag_parse_node_command(bk, n); bk->environment->node = NULL; n->next = bk->d->nodes; bk->d->nodes = n; itable_insert(bk->d->node_table, n->nodeid, n); debug(D_MAKEFLOW_PARSER, "Setting resource category '%s' for rule %d.\n", n->category->label, n->nodeid); dag_node_fill_resources(n); dag_node_print_debug_resources(n); return 1; }
int dag_parse(struct dag *d, FILE * dag_stream) { char *line = NULL; struct lexer_book *bk = calloc(1, sizeof(struct lexer_book)); //Taking advantage that calloc zeroes memory bk->d = d; bk->stream = dag_stream; bk->category = dag_task_category_lookup_or_create(d, "default"); while((line = dag_parse_readline(bk, NULL)) != NULL) { if(strlen(line) == 0 || line[0] == '#') { /* Skip blank lines and comments */ free(line); continue; } if(strncmp(line, "export ", 7) == 0) { if(!dag_parse_export(bk, line)) { dag_parse_error(bk, "export"); goto failure; } } else if(strchr(line, '=')) { if(!dag_parse_variable(bk, NULL, line)) { dag_parse_error(bk, "variable"); goto failure; } } else if(strstr(line, ":")) { if(!dag_parse_node(bk, line)) { dag_parse_error(bk, "node"); goto failure; } } else { dag_parse_error(bk, "syntax"); goto failure; } free(line); } //ok dag_close_over_environment(d); dag_compile_ancestors(d); free(bk); return 1; failure: free(line); free(bk); return 0; }
static int dag_parse_export(struct lexer *bk) { struct token *t, *vtoken, *vname; const char *name; int count = 0; while((t = lexer_peek_next_token(bk)) && t->type != TOKEN_NEWLINE) { switch(t->type) { case TOKEN_VARIABLE: vtoken = lexer_next_token(bk); //Save VARIABLE token. vname = lexer_peek_next_token(bk); if(vname->type == TOKEN_LITERAL) { name = xxstrdup(vname->lexeme); } else { lexer_report_error(bk, "Variable definition has name missing.\n"); } lexer_preppend_token(bk, vtoken); //Restore VARIABLE token. dag_parse_variable(bk, NULL); break; case TOKEN_LITERAL: t = lexer_next_token(bk); name = xxstrdup(t->lexeme); lexer_free_token(t); break; default: lexer_report_error(bk, "Malformed export syntax.\n"); break; } set_insert(bk->d->export_vars, name); count++; debug(D_MAKEFLOW_PARSER, "export variable: %s", name); } if(t) { //Free newline t = lexer_next_token(bk); lexer_free_token(t); } if(count < 1) { lexer_report_error(bk, "The export syntax needs the explicit name of the variables to be exported.\n"); } return 1; }
static int dag_parse(struct dag *d, FILE *stream) { struct lexer *bk = lexer_create(STREAM, stream, 1, 1); bk->d = d; bk->stream = stream; bk->category = dag_task_category_lookup_or_create(d, "default"); struct dag_variable_lookup_set s = { d, NULL, NULL, NULL }; bk->environment = &s; struct token *t; while((t = lexer_peek_next_token(bk))) { s.category = bk->category; s.node = NULL; s.table = NULL; switch (t->type) { case TOKEN_NEWLINE: case TOKEN_SPACE: /* Skip newlines, spaces at top level. */ lexer_free_token(lexer_next_token(bk)); break; case TOKEN_SYNTAX: dag_parse_syntax(bk); break; case TOKEN_FILES: dag_parse_node(bk); break; case TOKEN_VARIABLE: dag_parse_variable(bk, NULL); break; default: lexer_report_error(bk, "Unexpected token. Expected one of NEWLINE, SPACE, SYNTAX, FILES, or VARIABLE, but got: %s\n:", lexer_print_token(t)); break; } } dag_close_over_environment(d); dag_compile_ancestors(d); free(bk); return 1; }
int dag_parse_export(struct lexer_book *bk, char *line) { int i, argc; char *end_export, *equal; char **argv; end_export = strstr(line, "export "); if(!end_export) return 0; else end_export += strlen("export "); while(isblank(*end_export)) end_export++; if(end_export == '\0') return 0; string_split_quotes(end_export, &argc, &argv); for(i = 0; i < argc; i++) { equal = strchr(argv[i], '='); if(equal) { if(!dag_parse_variable(bk, NULL, argv[i])) { return 0; } else { *equal = '\0'; setenv(argv[i], equal + 1, 1); //this shouldn't be here... } } set_insert(bk->d->export_vars, xxstrdup(argv[i])); debug(D_DEBUG, "export variable=%s", argv[i]); } free(argv); return 1; }
int dag_parse_node(struct lexer_book *bk, char *line_org) { struct dag *d = bk->d; char *line; char *outputs = NULL; char *inputs = NULL; struct dag_node *n; n = dag_node_create(bk->d, bk->line_number); n->category = bk->category; list_push_tail(n->category->nodes, n); line = xxstrdup(line_org); outputs = line; inputs = strchr(line, ':'); *inputs = 0; inputs = inputs + 1; inputs = string_trim_spaces(inputs); outputs = string_trim_spaces(outputs); dag_parse_node_filelist(bk, n, outputs, 0); dag_parse_node_filelist(bk, n, inputs, 1); int ok; char *comment; //parse variables and comments while((line = dag_parse_readline(bk, n)) != NULL) { if(line[0] == '@' && strchr(line, '=')) { ok = dag_parse_variable(bk, n, line); free(line); if(ok) { continue; } else { dag_parse_error(bk, "node variable"); free(line); return 0; } } comment = strchr(line, '#'); if(comment) { *comment = '\0'; int n = strspn(line, " \t"); int m = strlen(line); *comment = '#'; /* make sure that only spaces and tabs appear before the hash */ if(n == m) { continue; } } /* not a comment or a variable, so we break to parse the command */ break; } ok = dag_parse_node_command(bk, n, line); free(line); if(ok) { n->next = d->nodes; d->nodes = n; itable_insert(d->node_table, n->nodeid, n); } else { dag_parse_error(bk, "node command"); return 0; } debug(D_DEBUG, "Setting resource category '%s' for rule %d.\n", n->category->label, n->nodeid); dag_task_fill_resources(n); dag_task_print_debug_resources(n); return 1; }