/* * The idea here is to take directives like this emitted * by cpp: * * # num * * and convert them to directives like this that are * understood by the GNU assembler: * * .line num * * and similarly: * * # num "string" optional stuff * * is converted to * * .line num * .file "string" * * While this could be done with a sequence of sed * commands, this is simpler and faster.. */ static pid_t filter(int pipein, int pipeout) { pid_t pid; FILE *in, *out; char *wspace; size_t wspace_len; if (verbose) (void) fprintf(stderr, "{#line filter} "); switch (pid = fork()) { case 0: if (dup2(pipein, 0) == -1 || dup2(pipeout, 1) == -1) { perror("dup2"); exit(1); } closefrom(3); break; case -1: perror("fork"); exit(1); default: return (pid); } in = fdopen(0, "r"); out = fdopen(1, "w"); /* * Key off the CODEMGR_WS environment variable to detect * if we're in an activated workspace, and to get the * path to the workspace. */ wspace = getenv("CODEMGR_WS"); if (wspace != NULL) wspace_len = strlen(wspace); while (!feof(in)) { int c, num; switch (c = fgetc(in)) { case '#': switch (fscanf(in, " %d", &num)) { case 0: /* * discard comment lines completely * discard ident strings completely too. * (GNU as politely ignores them..) */ copyuntil(in, NULL, '\n'); break; default: (void) fprintf(stderr, "fscanf botch?"); /*FALLTHROUGH*/ case EOF: exit(1); /*NOTREACHED*/ case 1: /* * This line has a number at the beginning; * if it has a string after the number, then * it's a filename. * * If this is an activated workspace, use * copyuntil_path() to do path rewriting * that will prevent workspace paths from * being burned into the resulting object. * If not in an activated workspace, then * copy the existing path straight through * without interpretation. */ if (fgetc(in) == ' ' && fgetc(in) == '"') { (void) fprintf(out, "\t.file \""); if (wspace != NULL) copyuntil_path(in, out, '"', wspace, wspace_len); else copyuntil(in, out, '"'); (void) fputc('\n', out); } (void) fprintf(out, "\t.line %d\n", num - 1); /* * discard the rest of the line */ copyuntil(in, NULL, '\n'); break; } break; case '\n': /* * preserve newlines */ (void) fputc(c, out); break; case EOF: /* * don't write EOF! */ break; default: /* * lines that don't begin with '#' are copied */ (void) fputc(c, out); copyuntil(in, out, '\n'); break; } if (ferror(out)) exit(1); } exit(0); /*NOTREACHED*/ }
static int linescan(String *lp, String tokstring){ int retval = TOK_ERR; switch(**lp){ case '\n': /* New line */ debug(DEBUG_INCOMPLETE, "TOK_NL"); retval = TOK_NL; break; case ';': case '#': debug(DEBUG_INCOMPLETE, "TOK_COMMENT"); /* Comment */ retval = TOK_COMMENT; break; case '=': /* Value */ (*lp)++; copyuntil(tokstring, lp, MAX_VALUE, "#;\n"); debug(DEBUG_INCOMPLETE, "TOK_VALUE"); retval = TOK_VALUE; break; case '[': /* Section start */ (*lp)++; if(copyuntil(tokstring, lp, MAX_SECTION, "]\n") == ']'){ (*lp)++; debug(DEBUG_INCOMPLETE, "TOK_SECTION"); retval = TOK_SECTION; } else{ debug(DEBUG_UNEXPECTED, "Section not closed off"); retval = TOK_ERR; /* Section broken */ } break; default: /* Look for a key */ if(isalnum(**lp)){ debug(DEBUG_INCOMPLETE, "lp: %s", *lp); copyuntil(tokstring, lp, MAX_KEY, "=\n"); debug(DEBUG_INCOMPLETE, "stop char: %s", *lp); if(**lp == '='){ debug(DEBUG_INCOMPLETE, "TOK_KEY"); retval = TOK_KEY; } else{ debug(DEBUG_INCOMPLETE, "TOK_ERR, key broken"); retval = TOK_ERR; // Key broken } } else{ debug(DEBUG_INCOMPLETE, "TOK_ERR, invalid char %c", **lp); retval = TOK_ERR; // Not something valid } break; } return retval; }