static mask_t create_lang_field (char *s) { char *p; mask_t bitfield = 0; for (p = s; *p != NIL; p++) { if (*p == ',') continue; bitfield |= get_language_mask(get_language(*p)); } return bitfield; }
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); }
/* * Read table from stdin, without assuming options section is sorted. */ static void read_table(void) { char line[512]; char *option_lines[MAX_OPTIONS]; int option_line_count = 0; char *p; int section = 0; int i = num_options; int j; strcpy(options[i].flag, "O_Unrecognized"); options[i].internal = TRUE; strcpy(options[i].name, ""); options[i].implies = NULL; i++; /* Find beginning of OPTIONS section. */ while (get_line(line) != EOF) { if (EMPTY(line)) continue; else if (line[0] == '%' && line[1] != '%') continue; else if (strcmp(line, "%%% OPTIONS") == 0) { section = OPTIONS; break; } else { internal_error("Unexpected line: %s", line); } } /* Read and sort the OPTIONS section. */ if (section != OPTIONS) { internal_error("OPTIONS section not found"); } option_line_count = 0; while (get_line(line) != EOF) { char* s; if (EMPTY(line)) continue; else if (line[0] == '%' && line[1] != '%') continue; else if (strncmp(line, "%%% ", 4) == 0) { if (strcmp(line, "%%% OPTIONS") == 0) internal_error("OPTIONS section seen twice"); else if (strcmp(line, "%%% COMBINATIONS") == 0) { section = COMBINATIONS; break; } else { internal_error("UNKNOWN SECTION: %s", line); } } s = malloc(strlen(line) + 1); if (s == NULL) internal_error("memory allocation failed"); strcpy(s, line); option_lines[option_line_count] = s; INCREMENT_INDEX(option_line_count, MAX_OPTIONS); } qsort(option_lines, option_line_count, sizeof(char*), reverse_strcmp); /* Process the option lines */ for (j = 0; j < option_line_count; ++j) { /* <name> <action> <langs> <phases> <implies> */ p = strtok(option_lines[j], SPACE); if (*p == 'I') { options[i].internal = TRUE; p++; } else options[i].internal = FALSE; if (*p != '-') internal_error("MISSING - : %s", p); options[i].syntax = set_option_name(options[i].name, p, &options[i].num_letters); if (options[i].syntax == normal && strlen(options[i].name) == 2) options[i].syntax = oneletter; set_flag_name(&options[i]); p = strtok(NULL, SPACE); store_string(options[i].action, p, ";"); if (strncmp(p, "toggle", 6) == 0) options[i].toggle = TRUE; else options[i].toggle = FALSE; if (!table_for_phase) { p = strtok(NULL, SPACE); options[i].languages = create_lang_field(p); if ( options[i].internal ) { options[i].languages |= get_language_mask ( L_internal ); } p = strtok(NULL, SPACE); options[i].phases = create_phase_field(p); } options[i].implies = create_option_list(&p,i); options[i].help = create_help_msg(p); INCREMENT_INDEX(i, MAX_OPTIONS); } check_dups(); /* Read and process the COMBINATIONS section */ if (section != COMBINATIONS) { internal_error("COMBINATIONS section not found"); } while (get_line(line) != EOF) { if (EMPTY(line)) continue; else if (line[0] == '%' && line[1] != '%') continue; else if (strncmp(line, "%%% ", 4) == 0) { internal_error("Unexpected sections line: %s", line); } else { /* <name> <action> <implies> */ if (line[0] != '\"') internal_error("MISSING \" : %s", line); p = strtok(line+1, DQUOTE); set_option_name(options[i].name, p, &options[i].num_letters); options[i].syntax = combo; set_flag_name(&options[i]); p = strtok(NULL, SPACE); store_string(options[i].action, p, "OKAY"); options[i].implies = create_option_list(&p,i); options[i].languages = ALL_LANGS; options[i].phases = ALL_PHASES; options[i].help = NULL; INCREMENT_INDEX(i, MAX_OPTIONS); } } num_options = i; }
/* * Read table from stdin, without assuming options section is sorted. */ static void read_table(void) { char line[512]; char line2[512]; char *option_lines[MAX_OPTIONS]; int option_line_count = 0; char *p; int section = 0; int i = num_options; int j; strcpy(options[i].flag, "O_Unrecognized"); options[i].internal = TRUE; strcpy(options[i].name, ""); options[i].implies = NULL; i++; option_line_count = 0; while (get_line(line) != EOF) { char* s; if (EMPTY(line)) continue; else if (line[0] == '%') continue; else if (line[0] == ' ' && line[1] == NIL) continue; else if (line[0] == '\t') internal_error("unexpected line (help msg?): %s", line); else if (line[0] != '-' && line[0] != 'I') internal_error("unexpected line: [%s]", line); if (get_line(line2) == EOF) internal_error("unexpected EOF for line2"); s = malloc(strlen(line) + strlen(line2) + 4); if (s == NULL) internal_error("memory allocation failed"); sprintf(s, "%s %c %s", line, FIELD_DIVIDER, line2); option_lines[option_line_count] = s; INCREMENT_INDEX(option_line_count, MAX_OPTIONS); } qsort(option_lines, option_line_count, sizeof(char*), reverse_strcmp); /* Process the option lines */ for (j = 0; j < option_line_count; ++j) { /* <name> <action> <langs> <phases> <implies> */ p = strtok(option_lines[j], SPACE); if (*p == 'I') { options[i].internal = TRUE; p++; } else options[i].internal = FALSE; if (*p != '-') internal_error("MISSING - : %s", p); options[i].syntax = set_option_name(options[i].name, p, &options[i].num_letters); if (options[i].syntax == normal && strlen(options[i].name) == 2) options[i].syntax = oneletter; set_flag_name(&options[i]); p = strtok(NULL, SPACE); store_string(options[i].action, p, ";"); if (strncmp(p, "toggle", 6) == 0) options[i].toggle = TRUE; else options[i].toggle = FALSE; if (!table_for_phase) { p = strtok(NULL, SPACE); options[i].languages = create_lang_field(p); if ( options[i].internal ) { options[i].languages |= get_language_mask ( L_internal ); } p = strtok(NULL, SPACE); options[i].phases = create_phase_field(p); } options[i].implies = create_option_list(&p,i); options[i].help = create_help_msg(p); INCREMENT_INDEX(i, MAX_OPTIONS); } check_dups(); num_options = i; }