/* $Id: genmodule.c,v 1.1.1.1 2012/03/29 17:21:05 uid42307 Exp $
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#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 <module.in> <Makefile[.am]>\n", argv[0]);
        return EXIT_FAILURE;
    }

    str = malloc(MAXLINE);

    /* Starting with initial input Makefile, look for include <file> or
     * YASM_MODULES += <module>.  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<num_modules; i++) {
                if (strncmp(modules[i], str+8, len) == 0) {
                    fprintf(out, "    {\"%s\", &yasm_%s_LTX_%s},\n",
                            modules[i]+len+1, modules[i]+len+1, str+8);
                }
            }
        } else if (strncmp(str, "EXTERN_LIST", 11) == 0) {
            for (i=0; i<num_modules; i++) {
                strcpy(str, modules[i]);
                strp = str;
                while (*strp != '\0' && *strp != '_')
                    strp++;
                *strp++ = '\0';

                fprintf(out, "extern yasm_%s_module yasm_%s_LTX_%s;\n",
                        str, strp, str);
            }
        } else
            fputs(str, out);
    }

    fclose(in);
    fclose(out);

    for (i=0; i<num_modules; i++)
        free(modules[i]);
    free(str);

    return EXIT_SUCCESS;
}
