/*
 *
 * 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;
}
