Пример #1
0
static void
write_opt_action (void)
{
	int i;
	buffer_t buf;
	char *tvar;
	char *tval;
	FILE *f;
	f = begin_file("opt_action.i");
	fprintf(f, "#include \"string_utils.h\"\n\n");
	fprintf(f, "#include \"get_options.h\"\n\n");
	fprintf(f, "#include \"lib_phase_dir.h\"\n\n");
	fprintf(f, "/* do action associated with option */\n");
	fprintf(f, "extern void\n");
	fprintf(f, "opt_action (int optflag)\n");
	fprintf(f, "{\n");
	fprintf(f, "switch (optflag) {\n");

	for (i = 0; i < num_options; i++) {
		if (!options[i].internal &&
		    //options[i].syntax != combo &&
		    !EMPTY(options[i].action) &&
		    find_by_flag(options[i].flag, i) == NULL) {
			fprintf(f, "case %s:\n", options[i].flag);
			fprintf(f, "\t%s\n", options[i].action);
			fprintf(f, "\tbreak;\n");
		}
	}
	fprintf(f, "}\n");
	fprintf(f, "}\n\n");
	fprintf(f, "/* return whether to mark this flag as unseen */\n");
	fprintf(f, "extern boolean\n");
	fprintf(f, "flag_is_superceded (int optflag)\n");
	fprintf(f, "{\n");
        fprintf(f, "switch (optflag) {\n");
	for (i = 0; i < num_options; i++) {
		if (options[i].toggle) {
			if (find_by_flag(options[i].flag, i))
				continue;

			fprintf(f, "case %s:\n", options[i].flag);
			/* get var after "toggle(&" */
			strcpy(buf, options[i].action+8);
			tvar = strtok(buf,COMMA);
			/* get value after "toggle(&<var>," */
			tval = strtok(NULL,RPAREN);
			fprintf(f, "\tif (%s != %s) return TRUE;\n", tvar, tval);
			fprintf(f, "\tbreak;\n");
		}
	}
        fprintf(f, "}\n");
        fprintf(f, "return FALSE;\n");
	fprintf(f, "}\n\n");
	fclose(f);
}
Пример #2
0
static void
write_option_names (void)
{
	int i;
	char *ivar;
	buffer_t buffer;
	FILE *f;
	f = begin_file("option_names.h");
	for (i = 0; i < num_options; i++) {
		if (!find_by_flag(options[i].flag, i))
			fprintf(f, "#define %s %d\n", options[i].flag, i);
		if (options[i].toggle) {
			/* get var after "toggle(&" */
			// Handle multiple toggles such as:
			//   toggle(&var1,10);toggle(&var2,11)
			char *p = options[i].action;
			while ((p = strstr(p, "toggle(&")) != NULL) {
			  p = p + 8;
			  strcpy(buffer, p);
			  ivar = strtok(buffer,COMMA);
			  add_implicit_var(ivar);
			}
		}
	}
	fprintf(f, "#define LAST_PREDEFINED_OPTION %d\n", num_options);
	fprintf(f, "extern int max_options;\n\n");
	for (i = 0; i < n_ivars; i++) {
		fprintf(f, "extern int %s;\n", implicit_vars[i]);
	}
	fclose(f);
}
Пример #3
0
/*
 * Check repeated definitions of a flag, to ensure they are all
 * identical.
 */
static void check_dups(void)
{
    int i;

    for (i = 1; i < num_options; i++) {
        option_info_t *opt = find_by_flag(options[i].flag, i);
        if (opt == NULL)
            continue;
        if (!compare_options(&options[i], opt)) {
            fprintf(stderr, "Error: %s and %s are not identical\n",
                    options[i].name, opt->name);
            exit(1);
        }
    }
}
Пример #4
0
static void
write_get_option (void)
{
    int i, j;
    FILE *f;
    f = begin_file("get_option.i");
    fprintf(f, "/* return option index */\n");
    fprintf(f, "extern int\n");
    fprintf(f, "get_option(int *argi, char *argv[])\n");
    fprintf(f, "{\n");
    fprintf(f, "/* don't reset optargs, as may contain needed info */\n");
    fprintf(f, "optargd = 0;\n");
    fprintf(f, "switch (argv[*argi][optindex]) {\n");
    i = 0;
    while (i < num_options) {
        if (options[i].internal || options[i].syntax == combo) {
            /* skip */
            i++;
            continue;
        }
        if (find_by_flag(options[i].flag, i))
            continue;
        if (options[i].name[1] == '\0')	/* special case "-" */
            fprintf(f, "case '\\0':\n");
        else
            fprintf(f, "case '%c':\n", options[i].name[1]);
        while (1) {
            switch (options[i].syntax) {
            case normal:
                fprintf(f, "\tif (strcmp(argv[*argi],\"%s\") == 0) {\n",
                        options[i].name);
                fprintf(f, "\t\tget_next_arg(argi);\n");
                fprintf(f, "\t\treturn %s;\n", options[i].flag);
                fprintf(f, "\t\t/* NOTREACHED */\n");
                fprintf(f, "\t}\n");
                break;
            case oneletter:
                fprintf(f, "\tget_next_char(argv, argi);\n");
                fprintf(f, "\treturn %s;\n", options[i].flag);
                fprintf(f, "\t/* NOTREACHED */\n");
                break;
            case oneletter_space:
            case multiletter_space:
                if (options[i].syntax == multiletter_space) {
                    char *temp = string_copy(options[i].name);
                    int nil_index = options[i].num_letters+1;
                    temp[nil_index] = NIL;
                    fprintf(f, "\tif ((strncmp(argv[*argi],\"%s\",%d) == 0)\n",
                            temp, nil_index);
                    fprintf(f, "\t&& strcmp(next_string_after(\"%s\",argv,argi),\"%s\") == 0) {\n",
                            temp, options[i].name+nil_index);
                    fprintf(f, "\t\tend_option(argv, argi, %d);\n", nil_index);
                } else {
                    fprintf(f, "\tif (strcmp(next_string(argv,argi), \"%s\") == 0) {\n",
                            options[i].name+2);
                }
                fprintf(f, "\t\toptargs = get_optarg(argv,argi);\n");
                fprintf(f, "\t\tget_next_arg(argi);\n");
                fprintf(f, "\t\treturn %s;\n", options[i].flag);
                fprintf(f, "\t\t/* NOTREACHED */\n");
                fprintf(f, "\t}\n");
                break;
            case needs_string_or_dash:
            case needs_string:
            case needs_directory:
            case needs_decimal:
#ifdef KEY
            case needs_directory_or_null:
#endif
                /* require this to be a separate arg */
                fprintf(f, "\tif (!is_new_arg) break;\n");
                /* for cases where base is > 1 letter,
                 * check that whole string matches */
                if (strlen(options[i].name) > 2) {
#ifdef KEY /* Mac port */
                    fprintf(f, "\tif (strncmp(argv[*argi],\"%s\",%ld) == 0) {\n",
                            options[i].name, (long) strlen(options[i].name));
                    fprintf(f, "\t\tend_option(argv, argi, %ld);\n",
                            (long) strlen(options[i].name));
#else /* KEY Mac port */
                    fprintf(f, "\tif (strncmp(argv[*argi],\"%s\",%d) == 0) {\n",
                            options[i].name, strlen(options[i].name));
                    fprintf(f, "\t\tend_option(argv, argi, %d);\n",
                            strlen(options[i].name));
#endif /* KEY Mac port */
                } /* else -<single-letter> */
                if (options[i].syntax == needs_decimal) {
                    fprintf(f, "\tif (is_decimal(next_string(argv,argi))) {\n");
                } else if (options[i].syntax == needs_directory
#ifdef KEY
                           || options[i].syntax == needs_directory_or_null
#endif
                          ) {
                    fprintf(f, "\tif (want_directory(next_string(argv,argi))) {\n");
                }
                fprintf(f, "\t\toptargs = get_optarg(argv, argi);\n");
                if (options[i].syntax == needs_decimal) {
                    fprintf(f, "\t\toptargd = atoi(optargs);\n");
                }
                fprintf(f, "\t\tget_next_arg(argi);\n");
                if (options[i].syntax == needs_string_or_dash)
                    fprintf(f, "\t\treturn add_string_option_or_dash(%s,optargs);\n",
                            options[i].flag);
#ifdef KEY
                else if (options[i].syntax == needs_directory)
                    fprintf(f, "\t\treturn add_any_string_option(%s,optargs);\n",
                            options[i].flag);
#endif
                else
                    fprintf(f, "\t\treturn add_string_option(%s,optargs);\n",
                            options[i].flag);
                fprintf(f, "\t\t/* NOTREACHED */\n");
                if (options[i].syntax == needs_directory
#ifdef KEY
                        || options[i].syntax == needs_directory_or_null
#endif
                   ) {
                    fprintf(f, "\t} else if (!is_last_char(argv,argi)) {\n");
                    fprintf(f, "\t\tif (fullwarn) {\n");
                    fprintf(f, "\t\t\twarning(\"%%s does not refer to a valid directory\", option_name);\n");
                    fprintf(f, "\t\t}\n");
                    fprintf(f, "\t\toptargs = get_optarg(argv,argi);\n");
                    fprintf(f, "\t\tget_next_arg(argi);\n");
#ifdef KEY
                    fprintf(f, "\t\treturn add_any_string_option(%s,optargs);\n",
                            options[i].flag);
#else
                    fprintf(f, "\t\treturn add_string_option(%s,optargs);\n",
                            options[i].flag);
#endif
                    fprintf(f, "\t\t/* NOTREACHED */\n");
                }
#ifdef KEY
                // Ignore %D? option if no dir arg is found by changing
                // them into -dummy.
                if (options[i].syntax == needs_directory_or_null) {
                    fprintf(f, "\t} else {\n");
                    fprintf(f, "\t  optargs = current_string(argv,argi);\n");
                    fprintf(f, "\t  get_next_arg(argi);\n");
                    fprintf(f, "\t  return O_dummy;\n");
                }
#endif
                if (options[i].syntax != needs_string
                        && options[i].syntax != needs_string_or_dash
                   ) {
                    fprintf(f, "\t}\n");
                }
                if (strlen(options[i].name) > 2) {
                    fprintf(f, "\t}\n");
                }
                break;
            case complicated:
                /* for cases where base is > 1 letter,
                 * check that whole string matches */
                if (strlen(options[i].name) > 2) {
#ifdef KEY /* Mac port */
                    fprintf(f, "\tif (strncmp(argv[*argi],\"%s\",%ld) == 0) {\n",
                            options[i].name, (long) strlen(options[i].name));
#else /* KEY Mac port */
                    fprintf(f, "\tif (strncmp(argv[*argi],\"%s\",%d) == 0) {\n",
                            options[i].name, strlen(options[i].name));
#endif /* KEY Mac port */
                }
                fprintf(f, "\t\treturn parse_%s_option(argv, argi);\n",
                        options[i].name+1);
                fprintf(f, "\t\t/* NOTREACHED */\n");
                if (strlen(options[i].name) > 2) {
                    fprintf(f, "\t}\n");
                }
                break;
            }
            if (i+1 < num_options
                    && options[i+1].name[1] == options[i].name[1])
            {
                /* stay within the case stm */
                i++;
            } else {
                break;	/* goto next case */
            }
        }
        fprintf(f, "\tbreak;\n");
        i++;
    }
    fprintf(f, "}\n");
    fprintf(f, "optargs = current_string(argv,argi);\n");
    fprintf(f, "get_next_arg(argi);\n");
    fprintf(f, "return O_Unrecognized;\n");
    fprintf(f, "}\n");

    /* now write alias routine */
    fprintf(f, "/* if alias, return real option index */\n");
    fprintf(f, "extern int\n");
    fprintf(f, "get_real_option_if_aliased(int flag)\n");
    fprintf(f, "{\n");
    fprintf(f, "  switch (flag) {\n");
    for (i = 0; i < num_options; i++) {
        /* alias is option with:
         * no action, one implies, all langs, no phases.
         */
        if (options[i].languages == get_language_mask(L_ALL)
                && options[i].phases == 0
                && EMPTY(options[i].action)
                && options[i].implies != NULL
                && options[i].implies->next == NULL)
        {
            j = options[i].implies->info_index;
            if (options[i].syntax == normal
                    || options[i].syntax == oneletter)
            {
                if (options[j].syntax == normal) {
                    fprintf(f, "\tcase %s: return %s;\n",
                            options[i].flag,
                            options[j].flag);
                }
                else if (options[j].syntax == needs_string ||
                         options[j].syntax == needs_string_or_dash) {
                    fprintf(f, "\tcase %s: {\n", options[i].flag);
                    fprintf(f, "\t\toptargs = \"%s\";\n",
                            options[i].implies->name
                            + strlen(options[j].name));
                    fprintf(f, "\t\treturn add_string_option(%s,optargs);\n",
                            options[j].flag);
                    fprintf(f, "\t\t}\n");
                }
                else continue;	/* don't know how to handle */
            }
            else if (options[i].syntax == options[j].syntax) {
                /* will catch this on derived case */
                fprintf(f, "\tcase %s: return %s;\n",
                        options[i].flag,
                        options[j].flag);
            }
            else continue;	/* don't know how to handle */
        }
    }
    fprintf(f, "\tdefault: return flag;\n");
    fprintf(f, "  }\n");
    fprintf(f, "}\n");
    fclose(f);
}
Пример #5
0
static void
write_init_options (void)
{
    int i;
    option_list_t *q;
    FILE *f;
    f = begin_file("init_options.i");
    fprintf(f, "#include \"option_names.h\"\n");
    fprintf(f, "#include \"opt_actions.h\"\n\n");
    for (i = 0; i < n_ivars; i++) {
        fprintf(f, "int %s = UNDEFINED;\n", implicit_vars[i]);
    }
    fprintf(f, "\n");
    fprintf(f, "static void\n");
    if (table_for_phase) {
        fprintf(f, "create_option_info (int flag, char *name, char *help_msg)\n");
        fprintf(f, "{\n");
    } else {
        fprintf(f, "create_option_info (int flag, mask_t lang_mask, mask_t phase_mask, char *name, char *help_msg)\n");
        fprintf(f, "{\n");
        fprintf(f, "\toptions[flag].valid_langs = lang_mask;\n");
        fprintf(f, "\toptions[flag].valid_phases = phase_mask;\n");
        fprintf(f, "\toptions[flag].combo_list = NULL;\n");
    }
    fprintf(f, "\toptions[flag].implies = NULL;\n");
    fprintf(f, "\toptions[flag].name = string_copy(name);\n");
    fprintf(f, "\toptions[flag].help_msg = string_copy(help_msg);\n");
    fprintf(f, "}\n\n");
    fprintf(f, "static void\n");
    fprintf(f, "create_implies_item (int key, int index, char *name)\n");
    fprintf(f, "{\n");
    fprintf(f, "\toption_list_t *p;\n");
    fprintf(f, "\tp = (option_list_t *) malloc(sizeof(option_list_t));\n");
    fprintf(f, "\tp->info_index = index;\n");
    fprintf(f, "\tp->name = string_copy(name);\n");
    fprintf(f, "\tp->next = options[key].implies;\n");
    fprintf(f, "\toptions[key].implies = p;\n");
    fprintf(f, "}\n\n");
    if (!table_for_phase) {
        fprintf(f, "static void\n");
        fprintf(f, "create_combo_item (int key, int index)\n");
        fprintf(f, "{\n");
        fprintf(f, "\tindex_list_t *p;\n");
        fprintf(f, "\tp = (index_list_t *) malloc(sizeof(index_list_t));\n");
        fprintf(f, "\tp->info_index = index;\n");
        fprintf(f, "\tp->next = options[key].combo_list;\n");
        fprintf(f, "\toptions[key].combo_list = p;\n");
        fprintf(f, "}\n\n");
    }
    fprintf(f, "\nextern void\n");
    fprintf(f, "init_options (void)\n");
    fprintf(f, "{\n");
    fprintf(f, "\toptions = (option_info_t *) malloc(max_options*sizeof(option_info_t));\n");

    for (i = 0; i < num_options; i++) {
        if (find_by_flag(options[i].flag, i))
            continue;
        if (table_for_phase) {
            fprintf(f, "\tcreate_option_info(%d,\"%s\",",
                    i, options[i].name);
        } else {
            if (sizeof(mask_t)>4)
            {
                fprintf(f, "\tcreate_option_info(%d,%#"PRIx64"LL,%#"PRIx64"LL,\"%s\",",
                        i,
                        (unsigned long)options[i].languages,
                        (unsigned long)options[i].phases,
                        options[i].name);
            }
            else
            {
                fprintf(f, "\tcreate_option_info(%d,%#"PRIx64",%#"PRIx64",\"%s\",",
                        i,
                        (unsigned long)options[i].languages,
                        (unsigned long)options[i].phases,
                        options[i].name);
            }
        }
        if (options[i].help == NULL)
            fprintf(f, "NULL);\n");
        else
            fprintf(f, "\"%s\");\n", options[i].help);
        q = options[i].implies;
        while (q != NULL) {
            /* we write reversed lists back in reverse order,
             * so now in correct order */
            fprintf(f, "\tcreate_implies_item(%s, %d, \"%s\");\n",
                    options[i].flag, q->info_index, q->name);
            q = q->next;
        }
        if (!table_for_phase) {
            if (options[i].syntax == combo) {
                index_list_t *index_lst = options[i].combo_list;
                while (index_lst != NULL) {
                    fprintf(f, "\tcreate_combo_item(%s, %d);\n",
                            options[i].flag, index_lst->info_index);
                    index_lst = index_lst->next;
                }
            }
        }
    }
    fprintf(f, "}\n\n");
    fclose(f);
}
Пример #6
0
static void
write_check_combos (void)
{
    int i, n;
    index_list_t *q;
    FILE *f;
    f = fopen("check_combos.c", "w");
    fprintf(f, "/* THIS FILE IS AUTOMATICALLY GENERATED BY table */\n\n");
    fprintf(f, "#include <stddef.h>\n");
    fprintf(f, "#include \"options.h\"\n");
    fprintf(f, "#include \"option_seen.h\"\n");
    fprintf(f, "#include \"option_names.h\"\n");
    fprintf(f, "#include \"opt_actions.h\"\n");
    fprintf(f, "#include \"errors.h\"\n");
    fprintf(f, "\n");
    fprintf(f, "/* replace individual options with combo */\n");
    fprintf(f, "static void\n");
    fprintf(f, "replace_with_combo (int combo_index)\n");
    fprintf(f, "{\n");
    fprintf(f, "\tint flag;\n");
    fprintf(f, "\tint count = 1;\n");
    fprintf(f, "\tFOREACH_OPTION_IN_COMBO(flag,combo_index) {\n");
    fprintf(f, "\t\tif (count == 1) {\n");
    fprintf(f, "\t\t\treplace_option_seen(flag, combo_index);\n");
    fprintf(f, "\t\t} else {\n");
    fprintf(f, "\t\t\tset_option_unseen(flag);\n");
    fprintf(f, "\t\t}\n");
    fprintf(f, "\t\tcount++;\n");
    fprintf(f, "\t}\n");
    fprintf(f, "}\n\n");
    fprintf(f, "static void\n");
    fprintf(f, "report_combo_errors (void)\n");
    fprintf(f, "{\n");
    for (i = 0; i < num_options; i++) {
        if (options[i].syntax == combo && !EMPTY(options[i].action)) {
            if (find_by_flag(options[i].flag, i))
                continue;
            fprintf(f, "\tif (option_was_seen(%s)) {\n",
                    options[i].flag);
            if (strcmp(options[i].action, "WARNING") == 0) {
                fprintf(f, "\t\twarning(\"%s combination not allowed, replaced with %s\");\n",
                        options[i].name, list_to_string(options[i].implies));
            } else {
                fprintf(f, "\t\tparse_error(\"%s\", \"illegal combination\");\n",
                        options[i].name);
            }
            fprintf(f, "\t}\n");
        }
    }
    fprintf(f, "}\n\n");
    fprintf(f, "extern boolean\n");
    fprintf(f, "is_replacement_combo (int combo_index)\n");
    fprintf(f, "{\n");
    fprintf(f, "\tswitch (combo_index) {\n");
    for (i = n = 0; i < num_options; i++) {
        if (options[i].syntax == combo && !EMPTY(options[i].action)
                && strcmp(options[i].action, "WARNING") == 0 )
        {
            if (find_by_flag(options[i].flag, i))
                continue;
            fprintf(f, "\tcase %s:\n", options[i].flag);
            n++;
        }
    }
    if (n)
        fprintf(f, "\t\treturn TRUE;\n");
    fprintf(f, "\tdefault:\n");
    fprintf(f, "\t\treturn FALSE;\n");
    fprintf(f, "\t}\n");
    fprintf(f, "}\n\n");
    fprintf(f, "extern void\n");
    fprintf(f, "check_for_combos (void)\n");
    fprintf(f, "{\n");
    for (i = 0; i < num_options; i++) {
        if (options[i].syntax == combo) {
            if (find_by_flag(options[i].flag, i))
                continue;
            q = options[i].combo_list;
            if (q == NULL) internal_error("empty combo_list?");
            fprintf(f, "\tif (");
            if (q->negated) fprintf(f, "!");
            fprintf(f, "option_was_seen(%s)",
                    options[q->info_index].flag);
            q = q->next;
            while (q != NULL) {
                fprintf(f, " && ");
                if (q->negated) fprintf(f, "!");
                fprintf(f, "option_was_seen(%s)",
                        options[q->info_index].flag);
                q = q->next;
            }
            fprintf(f, ") {\n");
            /* replace in seen array */
            fprintf(f, "\t\treplace_with_combo(%s);\n",
                    options[i].flag);
            /* untoggle individual options */
            for (q = options[i].combo_list; q != NULL; q = q->next) {
                if (options[q->info_index].toggle) {
                    fprintf(f, "\t\tun%s\n",
                            options[q->info_index].action);
                }
            }
            fprintf(f, "\t}\n");
        }
    }
    fprintf(f, "\treport_combo_errors();\n");
    fprintf(f, "}\n\n");
    fclose(f);
}