/* * --- ROCK-COPYRIGHT-NOTE-BEGIN --- * * This copyright note is auto-generated by ./scripts/Create-CopyPatch. * Please add additional copyright information _after_ the line containing * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by * the ./scripts/Create-CopyPatch script. Do not edit this copyright text! * * ROCK Linux: rock-src/misc/tools-source/descparser.c * ROCK Linux is Copyright (C) 1998 - 2006 Clifford Wolf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. A copy of the GNU General Public * License can be found at Documentation/COPYING. * * Many people helped and are helping developing ROCK Linux. Please * have a look at https://www.rocklinux.org/ and the Documentation/TEAM * file for details. * * --- ROCK-COPYRIGHT-NOTE-END --- */ /* this is a 1st proof-of-concept implementation */ #include #include #include #include #include int check_condition(const char *cond) { char *t = strdup(cond); char *left = strtok(t, " \t\n"); char *op = strtok(0, " \t\n"); char *right = strtok(0, " \t\n"); int retcode = 0; if ( !strcmp(left, "xpkg") && getenv("descparser_ign_xpkg") ) { free(t); return 1; } if ( !strcmp(op, "==") ) { char regex[strlen(right)+3]; char *text = getenv(left); regex_t re; sprintf(regex, "^%s$", right); if ( !text ) text = "_undef_"; if ( regcomp(&re, regex, REG_EXTENDED|REG_NOSUB) ) { fprintf(stderr, "failed to compile regex: '%s'.\n", right); exit(1); } if ( !regexec(&re, text, 0, 0, 0) ) retcode = 1; regfree(&re); } else { fprintf(stderr, "Unknown operator: '%s'.\n", op); exit(1); } free(t); return retcode; } char line[4096]; int condstack[128]; int condcount = -1; int falselevel = 0; void parse_file(FILE *f); void parse_file(FILE *f) { while ( fgets(line, 4096, f) ) { if (line[0] == '#') { if ( !strncmp(line, "#if ", 4) ) { condstack[++condcount] = check_condition(line+4); if ( !condstack[condcount] ) falselevel++; } else if ( !strncmp(line, "#else", 5) ) { falselevel += condstack[condcount] ? +1 : -1; condstack[condcount] = !condstack[condcount]; } else if ( !strncmp(line, "#elsif ", 7) ) { if ( !condstack[condcount] ) { condstack[condcount] = check_condition(line+7); if ( condstack[condcount] ) falselevel--; } else falselevel++; } else if ( !strncmp(line, "#endif", 6) ) { if ( !condstack[condcount--] ) falselevel--; } else if ( !strncmp(line, "#include ", 9) ) { FILE *i; if (strchr(line, '\n')) *strchr(line, '\n') = 0; i = fopen(line+9, "r"); if (i) { parse_file(i); fclose(i); } else fprintf(stderr, "Can't #include '%s'.\n", line+9); } } else if ( !falselevel ) fputs(line, stdout); } } int main() { parse_file(stdin); return 0; }