/* $Id: genmodule.c 1827 2007-04-22 05:09:49Z peter $ * * Generate module.c from module.in and Makefile.am or Makefile. * * Copyright (C) 2004-2007 Peter Johnson * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include "compat-queue.h" #define OUTPUT "module.c" #define MAXNAME 128 #define MAXLINE 1024 #define MAXMODULES 128 #define MAXINCLUDES 256 typedef struct include { STAILQ_ENTRY(include) link; char *filename; } include; int main(int argc, char *argv[]) { FILE *in, *out; char *str; int i; size_t len; char *strp; char *modules[MAXMODULES]; int num_modules = 0; STAILQ_HEAD(includehead, include) includes = STAILQ_HEAD_INITIALIZER(includes); include *inc; int isam = 0; int linecont = 0; if (argc != 3) { fprintf(stderr, "Usage: %s \n", argv[0]); return EXIT_FAILURE; } str = malloc(MAXLINE); /* Starting with initial input Makefile, look for include or * YASM_MODULES += . Note this currently doesn't handle * a relative starting path. */ len = strlen(argv[2]); inc = malloc(sizeof(include)); inc->filename = malloc(len+1); strcpy(inc->filename, argv[2]); STAILQ_INSERT_TAIL(&includes, inc, link); isam = argv[2][len-2] == 'a' && argv[2][len-1] == 'm'; while (!STAILQ_EMPTY(&includes)) { inc = STAILQ_FIRST(&includes); STAILQ_REMOVE_HEAD(&includes, link); in = fopen(inc->filename, "rt"); if (!in) { fprintf(stderr, "Could not open `%s'.\n", inc->filename); return EXIT_FAILURE; } free(inc->filename); free(inc); while (fgets(str, MAXLINE, in)) { /* Strip off any trailing whitespace */ len = strlen(str); if (len > 0) { strp = &str[len-1]; while (len > 0 && isspace(*strp)) { *strp-- = '\0'; len--; } } strp = str; /* Skip whitespace */ while (isspace(*strp)) strp++; /* Skip comments */ if (*strp == '#') continue; /* If line continuation, skip to continue copy */ if (linecont) goto keepgoing; /* Check for include if original input is .am file */ if (isam && strncmp(strp, "include", 7) == 0 && isspace(strp[7])) { strp += 7; while (isspace(*strp)) strp++; /* Build new include and add to end of list */ inc = malloc(sizeof(include)); inc->filename = malloc(strlen(strp)+1); strcpy(inc->filename, strp); STAILQ_INSERT_TAIL(&includes, inc, link); continue; } /* Check for YASM_MODULES = or += */ if (strncmp(strp, "YASM_MODULES", 12) != 0) continue; strp += 12; while (isspace(*strp)) strp++; if (strncmp(strp, "+=", 2) != 0 && *strp != '=') continue; if (*strp == '+') strp++; strp++; while (isspace(*strp)) strp++; keepgoing: /* Check for continuation */ if (len > 0 && str[len-1] == '\\') { str[len-1] = '\0'; while (isspace(*strp)) *strp-- = '\0'; linecont = 1; } else linecont = 0; while (*strp != '\0') { /* Copy module name */ modules[num_modules] = malloc(MAXNAME); len = 0; while (*strp != '\0' && !isspace(*strp)) modules[num_modules][len++] = *strp++; modules[num_modules][len] = '\0'; num_modules++; while (isspace(*strp)) strp++; } } fclose(in); } out = fopen(OUTPUT, "wt"); if (!out) { fprintf(stderr, "Could not open `%s'.\n", OUTPUT); return EXIT_FAILURE; } fprintf(out, "/* This file auto-generated by genmodule.c" " - don't edit it */\n\n"); in = fopen(argv[1], "rt"); if (!in) { fprintf(stderr, "Could not open `%s'.\n", argv[1]); fclose(out); remove(OUTPUT); return EXIT_FAILURE; } len = 0; while (fgets(str, MAXLINE, in)) { if (strncmp(str, "MODULES_", 8) == 0) { len = 0; strp = str+8; while (*strp != '\0' && *strp != '_') { len++; strp++; } *strp = '\0'; for (i=0; i