Exemple #1
0
int main (int argc, char **argv)
{
    int i, j, n;
    List *files = NULL;
    char *s, *srcfile;
    Dependency *dep;
    List *deplist = NULL;   /* Dependencies */
    List *modlist = NULL;   /* Defined modules */
    List *extradeps = NULL; /* "Extra" dependencies (given by the '-d' option */
    List *rules = NULL;  /* List of rules to be added to all dependency lines */
    List *fspecrules = NULL; /* FileSpecific rules */
    List *obj = NULL;
    List *macrolist = NULL;  /* -D MACRO */
    Module *mod;
    List *h1, *h2;

    set_progname(argv[0]);

    if (argc == 1)  {
        printf ("%s", helpstring);
        exit (EXIT_SUCCESS);
    }

    /* Set a few option defaults */
    options.warn_missing = false;
    options.modfile_fmt = (char *)MODFILE_FMT_DEFAULT;
    options.src_fmt = SUFFIX;
    options.create_obj = false;
    options.exe_name = NULL;
    options.link_rule = (char *)LINK_RULE_DEFAULT;
    options.coco = false;
    options.obj_dir_set = false;
    options.obj_dir = "";
    options.src_dep = true;
    options.ignore_mods = NULL;
    options.src_path = NULL;

    /* Parse command line arguments */
    for (i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) {
            printf ("%s", helpstring);
            exit (EXIT_SUCCESS);

        } else if (strcmp(argv[i], "-V") == 0 
               || strcmp(argv[i], "--version") == 0) {
            printf("%s\n", ver);
            printf("%s\n", license);
            exit (EXIT_SUCCESS);

        } else if (strcmp(argv[i], "-W") == 0 
                   || strcmp(argv[i], "-Wmissing") == 0) {
            options.warn_missing = true;

        } else if (strcmp(argv[i], "-Wconfused") == 0) {
            options.warn_confused = true;

        } else if (strncmp(argv[i], "-m", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-m' needs argument");
                options.modfile_fmt = xstrdup(argv[++i]);
            } else
                options.modfile_fmt = xstrdup(&(argv[i][2]));

        } else if (strncmp (argv[i], "-u", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-u' needs argument");
                s = xstrdup(argv[++i]);
            } else
                s = xstrdup(&(argv[i][2]));

            if (!list_find(options.ignore_mods, s, COMP_FUN(&strcasecmp)))
                options.ignore_mods = list_prepend(options.ignore_mods, s);

        } else if (strcmp(argv[i], "-fixed") == 0) {
            options.src_fmt = FIXED;

        } else if (strcmp(argv[i], "-free") == 0) {
            options.src_fmt = FREE;

        } else if (strncmp(argv[i], "-d", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-d' needs argument");
                s = xstrdup(argv[++i]);
            } else
                s = xstrdup(&(argv[i][2]));

            if (!list_find(extradeps, s, COMP_FUN(&strcasecmp)))
                extradeps = list_prepend(extradeps, s);

        } else if (strncmp(argv[i], "-r", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error ("Option '-r' needs argument");
                s = xstrdup(argv[++i]);
            } else
                s = xstrdup(&(argv[i][2]));

            if (!list_find(rules, s, COMP_FUN(&strcasecmp)))
                rules = list_append(rules, s);
        
        } else if (strncmp(argv[i], "-R", 2) == 0) {
            Fsr *h;
            h = (Fsr *) xmalloc(sizeof(Fsr));
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-R' needs 2 arguments");
                h->file = xstrdup(argv[++i]);
            } else
                h->file = xstrdup(&(argv[i][2]));

            if (i == argc-1) fatal_error("Option '-R' needs 2 arguments");
            h->rule = xstrdup (argv[++i]);
            fspecrules = list_append(fspecrules, h);

        } else if (strncmp(argv[i], "-o", 2) == 0) {
            options.create_obj = true;
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-o' needs argument");
                options.exe_name = xstrdup(argv[++i]);
            } else
                options.exe_name = xstrdup(&(argv[i][2]));

        } else if (strncmp(argv[i], "-l", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc-1)  fatal_error("Option '-l' needs argument");
                options.link_rule = xstrdup(argv[++i]);
            } else
                options.link_rule = xstrdup(&(argv[i][2]));

        } else if (strcmp(argv[i], "-coco") == 0) {
            options.coco = true;
            options.src_fmt = FREE;
                
        } else if (strncmp(argv[i], "-D", 2) == 0) {
            Macro *mac;
            char *eq;
            char *s;

            /* Copy the argument of -D (ignoring any '=definition') to a
             * 'Macro' and add it to 'macrolist'. */
            mac = macro_new ();
            if (strlen(argv[i]) == 2) {
                char *eq;
                char *s;

                if (i == argc-1)  fatal_error("Option '-D' needs argument");
                i++;

                eq = strchr(argv[i], '=');
                if (eq != NULL)
                    s = xstrndup(argv[i], eq - argv[i]);
                else
                    s = xstrdup(argv[i]);
                
                macro_setname(mac, s);
            } else {
                eq = strchr(&argv[i][2], '=');
                if (eq != NULL)
                    s = xstrndup(&argv[i][2], eq - argv[i] - 2);
                else
                    s = xstrdup(&argv[i][2]);
                
                macro_setname(mac, s);
            }
            if (!list_find(macrolist, mac, &macrocmp))
                macrolist = list_prepend(macrolist, mac);

        } else if (strncmp(argv[i], "-b", 2) == 0) {
            if (strlen(argv[i]) == 2) {
                if (i == argc - 1) fatal_error("Option '-b' needs argument");
                options.obj_dir = xstrdup(argv[++i]);
            } else
                if (argv[i][2] == '=') {
                    options.obj_dir = xstrdup(&(argv[i][3]));
                } else
                    options.obj_dir = xstrdup(&(argv[i][2]));

            n = strlen(options.obj_dir);
            if (n > 0 && options.obj_dir[n - 1] != '/') {
                options.obj_dir = xrealloc(options.obj_dir, n+2);
                strcat(options.obj_dir, "/");
            }

            options.obj_dir_set = true;

        } else if (strncmp(argv[i], "-I", 2) == 0) {
            int jp;

            if (strlen(argv[i]) == 2) {
                if (i == argc - 1) fatal_error("Option '-I' needs argument");
                s = xstrdup(argv[++i]);
            } else
                if (argv[i][2] == '=' ) {
                    s = xstrdup(&(argv[i][3]));
                } else
                    s = xstrdup(&(argv[i][2]));

            n = strlen(s);
            jp = 0;
            for(j = 0;j < n; j++){
               if (s[j] == ' ' || s[j]==':') {
                 options.src_path = list_append(options.src_path, 
                                                xstrndup(s+jp, j-jp));
                 jp = j + 1;
               } else if (j == n-1) {
                 options.src_path = list_append(options.src_path,xstrdup(s+jp));
               }
            }

        } else if (strcmp(argv[i], "-nosrc") == 0) {
            options.src_dep = false;

        /*
         * Add new options here
         */

        } else if (*argv[i] == '-') {
            fatal_error("Unknown Option '%s'", argv[i]);

        } else {
            /* Gee, we got a filename! */
            if (!list_find(files, argv[i], COMP_FUN(&strcasecmp)))
                files = list_prepend(files, argv[i]);
        }
    }

    /* Parse the files, creating target and dependency lists. */
    for (h1 = files; h1; h1 = h1->next) {
        char *tmp;

        dep = dependency_new();
        srcfile = (char *)h1->data;
        if (find_dep(srcfile, dep, &modlist, macrolist)) {
            dep->sourcefile = srcfile;

            tmp = replace_suffix(srcfile, ".o");
            if (!list_find(dep->targets, tmp, COMP_FUN(&strcasecmp)))
                dep->targets = list_prepend(dep->targets, tmp);
            else
                free(tmp);

            if (options.src_dep)
                dep->includes = list_prepend(dep->includes, srcfile);

            if (options.coco) {
                char *setfile;
                struct stat blah;

                setfile = replace_suffix(srcfile, ".set");
                if (stat(setfile, &blah) == 0) {
                    if (!list_find(dep->includes,setfile,COMP_FUN(&strcasecmp)))
                        dep->includes = list_append(dep->includes, setfile);
                } else if (stat("coco.set", &blah) == 0) {
                    free(setfile);
                    setfile = xstrdup("coco.set");
                    if (!list_find(dep->includes,setfile,COMP_FUN(&strcasecmp)))
                        dep->includes = list_append(dep->includes, setfile);
                } else
                    free(setfile);
            }

            deplist = list_prepend(deplist, dep);
        } else
            free(dep);

        if (options.create_obj)
            obj = list_prepend(obj, replace_suffix(srcfile, ".o"));
    }

    /* Print FOBJ macro and linking dependecy-line + rule. */
    if (options.create_obj) {
        printf("FOBJ=");
        for (h1 = obj; h1; h1 = h1->next)
            if (options.obj_dir_set)
                printf("%s ", set_path(h1->data, options.obj_dir));
            else
                printf("%s ", (char *)h1->data);
        printf("\n\n%s: $(FOBJ)\n\t%s\n\n", options.exe_name,options.link_rule);
    }

    /* Print the 'target: dependency' lists. */
    for (h1 = deplist; h1; h1 = h1->next) {
        bool byR = false;

        dep = (Dependency *)h1->data;

        /* If there are no dependencys, there is no need to output anything */
        if (list_length(dep->includes) + list_length(dep->modules) == 0)
            continue;

        /* Targets */
        for (h2 = dep->targets; h2; h2 = h2->next)  
            if (options.obj_dir_set)
                printf("%s ", set_path(h2->data, options.obj_dir));
            else
                printf("%s ", (char *)h2->data);

        printf(": ");;

        /* Includes */
        for (h2 = dep->includes; h2; h2 = h2->next)  
            printf("%s ", (char *)h2->data);

        /* Modules */
        for (h2 = dep->modules; h2; h2 = h2->next) {
            List *l;
            s = (char *)h2->data;

            if (!(l = list_find(modlist, s, &modstrcmp))) {
                /* Don't write *.mod-file to dependency list if its definition 
                 * isn't found. */
                if (options.warn_missing)  warning("Module '%s' not found", s);

            } else {
                mod = (Module *)l->data;
                if (strcasecmp(mod->sourcefile, dep->sourcefile) == 0) {
                    /* Dont' write *.mod-file to the dependency list if it 
                     * defined in the same file it is USEd from. */
                } else {
                    if (options.obj_dir_set)
                        printf("%s ", 
                               set_path(mod->modfile_name, options.obj_dir));
                    else
                        printf("%s ", mod->modfile_name);
                }
            }

        }

        /* Extra dependencies (given with the '-d' option */
        for (h2 = extradeps; h2; h2 = h2->next)  
            printf("%s ", (char *)h2->data);

        putchar('\n');

        /* Print -R rules (if there are any) */
        for (h2 = fspecrules; h2; h2 = h2->next) {
            Fsr *h = (Fsr *)h2->data;

            if (fsr_strcmp(dep->sourcefile, h) == 0) {
                char *tmp = expand_rule(h->rule, dep->sourcefile);
                printf("%s\n", tmp);
                free(tmp);
                byR = true;
            }
        }
            
        /* If the file wasn't given any rules by the -R option, print -r rules*/
        if (!byR) {
            for (h2 = rules; h2; h2 = h2->next) {
                char *tmp = expand_rule((char *)h2->data, dep->sourcefile);
                printf("%s\n", tmp);
                free(tmp);
            }
        }

    }

    exit(EXIT_SUCCESS);
}
static void
primary_parser_dep_start (PrimarySAXContext *ctx,
                          const char *name,
                          const char **attrs)
{
    SAXContext *sctx = &ctx->sctx;

    const char *tmp_name = NULL;
    const char *tmp_version = NULL;
    const char *tmp_release = NULL;
    const char *tmp_epoch = NULL;
    const char *tmp_flags = NULL;
    gboolean tmp_pre = FALSE;
    Dependency *dep;
    int i;
    gboolean ignore = FALSE;
    const char *attr;
    const char *value;

    if (!strcmp (name, "rpm:entry")) {
        for (i = 0; attrs && attrs[i]; i++) {
            attr = attrs[i];
            value = attrs[++i];

            if (!strcmp (attr, "name")) {
                if (!strncmp (value, "rpmlib(", strlen ("rpmlib("))) {
                    ignore = TRUE;
                    break;
                }
                tmp_name = value;
            } else if (!strcmp (attr, "flags"))
                tmp_flags = value;
            else if (!strcmp (attr, "epoch"))
                tmp_epoch = value;
            else if (!strcmp (attr, "ver"))
                tmp_version = value;
            else if (!strcmp (attr, "rel"))
                tmp_release = value;
            else if (!strcmp (attr, "pre"))
                tmp_pre = TRUE;
        }

        if (!ignore) {
            GStringChunk *chunk = sctx->current_package->chunk;

            dep = dependency_new ();
            dep->name = g_string_chunk_insert (chunk, tmp_name);
            if (tmp_flags)
                dep->flags = g_string_chunk_insert (chunk, tmp_flags);
            if (tmp_epoch)
                dep->epoch = g_string_chunk_insert (chunk, tmp_epoch);
            if (tmp_version)
                dep->version = g_string_chunk_insert (chunk, tmp_version);
            if (tmp_release)
                dep->release = g_string_chunk_insert (chunk, tmp_release);
            dep->pre = tmp_pre;

            *ctx->current_dep_list = g_slist_prepend (*ctx->current_dep_list,
                                                      dep);
        }
    }
}