📄 protoize.c
字号:
(f_list_chain_item *) xmalloc (sizeof (f_list_chain_item)); cip->formals_list = dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1))); /* Add the new chain item at the head of the current list. */ cip->chain_next = def_dec_p->f_list_chain; def_dec_p->f_list_chain = cip; }#endif /* !defined (UNPROTOIZE) */ def_dec_p->f_list_count++; p = left_paren_p - 2; /* p must now point either to another right paren, or to the last character of the name of the function that was declared/defined. If p points to another right paren, then this indicates that we are dealing with multiple formals lists. In that case, there really should be another right paren preceding this right paren. */ if (*p != ')') break; else check_aux_info (*--p == ')'); } { const char *past_fn = p + 1; check_aux_info (*past_fn == ' '); /* Scan leftwards over the identifier that names the function. */ while (is_id_char (*p)) p--; p++; /* p now points to the leftmost character of the function name. */ { char *fn_string = (char *) alloca (past_fn - p + 1); strncpy (fn_string, p, (size_t) (past_fn - p)); fn_string[past_fn-p] = '\0'; def_dec_p->hash_entry = lookup (function_name_primary, fn_string); } } /* Look at all of the defs and decs for this function name that we have collected so far. If there is already one which is at the same line number in the same file, then we can discard this new def_dec_info record. As an extra assurance that any such pair of (nominally) identical function declarations are in fact identical, we also compare the ansi_decl parts of the lines from the aux_info files just to be on the safe side. This comparison will fail if (for instance) the user was playing messy games with the preprocessor which ultimately causes one function declaration in one header file to look differently when that file is included by two (or more) other files. */ { const def_dec_info *other; for (other = def_dec_p->hash_entry->ddip; other; other = other->next_for_func) { if (def_dec_p->line == other->line && def_dec_p->file == other->file) { if (strcmp (def_dec_p->ansi_decl, other->ansi_decl)) { fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n", def_dec_p->file->hash_entry->symbol, def_dec_p->line, def_dec_p->hash_entry->symbol); exit (1); } free_def_dec (def_dec_p); return; } } }#ifdef UNPROTOIZE /* If we are doing unprotoizing, we must now setup the pointers that will point to the K&R name list and to the K&R argument declarations list. Note that if this is only a function declaration, then we should not expect to find any K&R style formals list following the ANSI-style formals list. This is because GCC knows that such information is useless in the case of function declarations (function definitions are a different story however). Since we are unprotoizing, we don't need any such lists anyway. All we plan to do is to delete all characters between ()'s in any case. */ def_dec_p->formal_names = NULL; 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, my_strerror(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, my_strerror(errno)); return 0; } if (WIFSIGNALED (wait_status)) { fprintf (stderr, "%s: subprocess got fatal signal %d", pname, WTERMSIG (wait_status)); return 0; } if (WIFEXITED (wait_status) && WEXITSTATUS (wait_status) != 0) { fprintf (stderr, "%s: %s exited with status %d\n", pname, base_filename, WEXITSTATUS (wait_status)); 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);#ifdef HAVE_STRERROR { char *p = strerror(e); write (f, p, strlen (p)); }#else write (f, sys_errlist[e], strlen (sys_errlist[e]));#endif 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -