📄 protoize.c
字号:
def_dec_p->formal_decls = NULL; if (def_dec_p->is_func_def) { p = semicolon_p; check_aux_info (*++p == ' '); check_aux_info (*++p == '/'); check_aux_info (*++p == '*'); check_aux_info (*++p == ' '); check_aux_info (*++p == '('); { const char *kr_names_start = ++p; /* Point just inside '('. */ while (*p++ != ')') continue; p--; /* point to closing right paren */ /* Make a copy of the K&R parameter names list. */ def_dec_p->formal_names = dupnstr (kr_names_start, (size_t) (p - kr_names_start)); } check_aux_info (*++p == ' '); p++; /* p now points to the first character of the K&R style declarations list (if there is one) or to the star-slash combination that ends the comment in which such lists get embedded. */ /* Make a copy of the K&R formal decls list and set the def_dec record to point to it. */ if (*p == '*') /* Are there no K&R declarations? */ { check_aux_info (*++p == '/'); def_dec_p->formal_decls = ""; } else { const char *kr_decls_start = p; while (p[0] != '*' || p[1] != '/') p++; p--; check_aux_info (*p == ' '); def_dec_p->formal_decls = dupnstr (kr_decls_start, (size_t) (p - kr_decls_start)); } /* Handle a special case. If we have a function definition marked as being in "old" style, and if it's formal names list is empty, then it may actually have the string "void" in its real formals list in the original source code. Just to make sure, we will get setup to convert such things anyway. This kludge only needs to be here because of an insurmountable problem with generating .X files. */ if (!def_dec_p->prototyped && !*def_dec_p->formal_names) def_dec_p->prototyped = 1; } /* Since we are unprotoizing, if this item is already in old (K&R) style, we can just ignore it. If that is true, throw away the itme now. */ if (!def_dec_p->prototyped) { free_def_dec (def_dec_p); return; }#endif /* defined (UNPROTOIZE) */ /* Add this record to the head of the list of records pertaining to this particular function name. */ def_dec_p->next_for_func = def_dec_p->hash_entry->ddip; def_dec_p->hash_entry->ddip = def_dec_p; /* Add this new def_dec_info record to the sorted list of def_dec_info records for this file. Note that we don't have to worry about duplicates (caused by multiple inclusions of header files) here because we have already eliminated duplicates above. */ if (!def_dec_p->file->defs_decs) { def_dec_p->file->defs_decs = def_dec_p; def_dec_p->next_in_file = NULL; } else { int line = def_dec_p->line; const def_dec_info *prev = NULL; const def_dec_info *curr = def_dec_p->file->defs_decs; const def_dec_info *next = curr->next_in_file; while (next && (line < curr->line)) { prev = curr; curr = next; next = next->next_in_file; } if (line >= curr->line) { def_dec_p->next_in_file = curr; if (prev) ((NONCONST def_dec_info *) prev)->next_in_file = def_dec_p; else def_dec_p->file->defs_decs = def_dec_p; } else /* assert (next == NULL); */ { ((NONCONST def_dec_info *) curr)->next_in_file = def_dec_p; /* assert (next == NULL); */ def_dec_p->next_in_file = next; } }}/* Set up the vector COMPILE_PARAMS which is the argument list for running GCC. Also set input_file_name_index and aux_info_file_name_index to the indices of the slots where the file names should go. *//* We initialize the vector by removing -g, -O, -S, -c, and -o options, and adding '-aux-info AUXFILE -S -o /dev/null INFILE' at the end. */static voidmunge_compile_params (params_list) const char *params_list;{ /* Build up the contents in a temporary vector that is so big that to has to be big enough. */ const char **temp_params = (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *)); int param_count = 0; const char *param; temp_params[param_count++] = compiler_file_name; for (;;) { while (isspace (*params_list)) params_list++; if (!*params_list) break; param = params_list; while (*params_list && !isspace (*params_list)) params_list++; if (param[0] != '-') temp_params[param_count++] = dupnstr (param, (size_t) (params_list - param)); else { switch (param[1]) { case 'g': case 'O': case 'S': case 'c': break; /* Don't copy these. */ case 'o': while (isspace (*params_list)) params_list++; while (*params_list && !isspace (*params_list)) params_list++; break; default: temp_params[param_count++] = dupnstr (param, (size_t) (params_list - param)); } } if (!*params_list) break; } temp_params[param_count++] = "-aux-info"; /* Leave room for the aux-info file name argument. */ aux_info_file_name_index = param_count; temp_params[param_count++] = NULL; temp_params[param_count++] = "-S"; temp_params[param_count++] = "-o"; temp_params[param_count++] = "/dev/null"; /* Leave room for the input file name argument. */ input_file_name_index = param_count; temp_params[param_count++] = NULL; /* Terminate the list. */ temp_params[param_count++] = NULL; /* Make a copy of the compile_params in heap space. */ compile_params = (const char **) xmalloc (sizeof (char *) * (param_count+1)); memcpy (compile_params, temp_params, sizeof (char *) * param_count);}/* Do a recompilation for the express purpose of generating a new aux_info file to go with a specific base source file. */static intgen_aux_info_file (base_filename) const char *base_filename;{ int child_pid; if (!input_file_name_index) munge_compile_params (""); /* Store the full source file name in the argument vector. */ compile_params[input_file_name_index] = shortpath (NULL, base_filename); /* Add .X to source file name to get aux-info file name. */ compile_params[aux_info_file_name_index] = savestring2 (compile_params[input_file_name_index], strlen (compile_params[input_file_name_index]), ".X", 2); if (!quiet_flag) fprintf (stderr, "%s: compiling `%s'\n", pname, compile_params[input_file_name_index]); if (child_pid = fork ()) { if (child_pid == -1) { fprintf (stderr, "%s: could not fork process: %s\n", pname, sys_errlist[errno]); return 0; }#if 0 /* Print out the command line that the other process is now executing. */ if (!quiet_flag) { const char **arg; fputs ("\t", stderr); for (arg = compile_params; *arg; arg++) { fputs (*arg, stderr); fputc (' ', stderr); } fputc ('\n', stderr); fflush (stderr); }#endif /* 0 */ { int wait_status; if (wait (&wait_status) == -1) { fprintf (stderr, "%s: wait failed: %s\n", pname, sys_errlist[errno]); return 0; } if ((wait_status & 0x7F) != 0) { fprintf (stderr, "%s: subprocess got fatal signal %d", pname, (wait_status & 0x7F)); return 0; } if (((wait_status & 0xFF00) >> 8) != 0) { fprintf (stderr, "%s: %s exited with status %d\n", pname, base_filename, ((wait_status & 0xFF00) >> 8)); return 0; } return 1; } } else { if (my_execvp (compile_params[0], (char *const *) compile_params)) { int e = errno, f = fileno (stderr); write (f, pname, strlen (pname)); write (f, ": ", 2); write (f, compile_params[0], strlen (compile_params[0])); write (f, ": ", 2); write (f, sys_errlist[e], strlen (sys_errlist[e])); write (f, "\n", 1); _exit (1); } return 1; /* Never executed. */ }}/* Read in all of the information contained in a single aux_info file. Save all of the important stuff for later. */static voidprocess_aux_info_file (base_source_filename, keep_it, is_syscalls) const char *base_source_filename; int keep_it; int is_syscalls;{ size_t base_len = strlen (base_source_filename); char * aux_info_filename = (char *) alloca (base_len + strlen (aux_info_suffix) + 1); char *aux_info_base; char *aux_info_limit; char *aux_info_relocated_name; const char *aux_info_second_line; time_t aux_info_mtime; size_t aux_info_size; int must_create; /* Construct the aux_info filename from the base source filename. */ strcpy (aux_info_filename, base_source_filename); strcat (aux_info_filename, aux_info_suffix); /* Check that the aux_info file exists and is readable. If it does not exist, try to create it (once only). */ /* If file doesn't exist, set must_create. Likewise if it exists and we can read it but it is obsolete. Otherwise, report an error. */ must_create = 0; /* Come here with must_create set to 1 if file is out of date. */start_over: ; if (my_access (aux_info_filename, R_OK) == -1) { if (errno == ENOENT) { if (is_syscalls) { fprintf (stderr, "%s: warning: missing SYSCALLS file `%s'\n", pname, aux_info_filename); return; } must_create = 1; } else { fprintf (stderr, "%s: can't read aux info file `%s': %s\n", pname, shortpath (NULL, aux_info_filename), sys_errlist[errno]); errors++; return; } }#if 0 /* There is code farther down to take care of this. */ else { struct stat s1, s2; stat (aux_info_file_name, &s1); stat (base_source_file_name, &s2); if (s2.st_mtime > s1.st_mtime) must_create = 1; }#endif /* 0 */ /* If we need a .X file, create it, and verify we can read it. */ if (must_create) { if (!gen_aux_info_file (base_source_filename)) { errors++; return; } if (my_access (aux_info_filename, R_OK) == -1) { fprintf (stderr, "%s: can't read aux info file `%s': %s\n", pname, shortpath (NULL, aux_info_filename), sys_errlist[errno]); errors++; return; } } { struct stat stat_buf; /* Get some status information about this aux_info file. */ if (my_stat (aux_info_filename, &stat_buf) == -1) { fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n", pname, shortpath (NULL, aux_info_filename), sys_errlist[errno]); errors++; return; } /* Check on whether or not this aux_info file is zero length. If it is, then just ignore it and return. */ if ((aux_info_size = stat_buf.st_size) == 0) return; /* Get the date/time of last modification for this aux_info file and remember it. We will have to check that any source files that it contains information about are at least this old or older. */ aux_info_mtime = stat_buf.st_mtime; if (!is_syscalls) { /* Compare mod time with the .c file; update .X file if obsolete. The code later on can fail to check the .c file if it did not directly define any functions. */ if (my_stat (base_source_filename, &stat_buf) == -1) { fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n", pname, shortpath (NULL, base_source_filename), sys_errlist[errno]); errors++; return; } if (stat_buf.st_mtime > aux_info_mtime) { must_create = 1; goto start_over; } } } { int aux_info_file; /* Open the aux_info file. */ if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1) { fprintf (stderr, "%s: can't open aux info file `%s' for reading: %s\n", pname, shortpath (NULL, aux_info_filename), sys_errlist[errno]); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -