📄 fixincl.c
字号:
If it is not retryable, then break out of this loop. */ if (dead_kid == NOPROCESS) { switch (errno) { case EINTR: case EAGAIN: break; default: fprintf (stderr, "Error %d (%s) waiting for %d to finish\n", errno, strerror( errno ), child ); /* FALLTHROUGH */ case ECHILD: /* no children to wait for?? */ return; } } } done_waiting:;}/* * * * * * * * * * * * * load_file loads all the contents of a file into malloc-ed memory. Its argument is the name of the file to read in; the returned result is the NUL terminated contents of the file. The file is presumed to be an ASCII text file containing no NULs. */char *load_file (pz_file_name) const char *pz_file_name;{ char *pz_data; size_t file_size; { struct stat stbf; if (stat (pz_file_name, &stbf) != 0) { fprintf (stderr, "error %d (%s) stat-ing %s\n", errno, strerror (errno), pz_file_name); return (char *) NULL; } file_size = stbf.st_size; } if (file_size == 0) return (char *) NULL; pz_data = (char *) malloc ((file_size + 16) & ~0x00F); if (pz_data == (char *) NULL) { fprintf (stderr, "error: could not malloc %d bytes\n", file_size); exit (EXIT_FAILURE); } { FILE *fp = fopen (pz_file_name, "r"); size_t size_left = file_size; char *read_ptr = pz_data; if (fp == (FILE *) NULL) { fprintf (stderr, "error %d (%s) opening %s\n", errno, strerror (errno), pz_file_name); free ((void *) pz_data); return (char *) NULL; } do { size_t sizeRead = fread ((void *) read_ptr, 1, size_left, fp); if (sizeRead == 0) { if (feof (fp)) break; if (ferror (fp)) { int err = errno; if (err != EISDIR) fprintf (stderr, "error %d (%s) reading %s\n", err, strerror (err), pz_file_name); free ((void *) pz_data); fclose (fp); return (char *) NULL; } } read_ptr += sizeRead; size_left -= sizeRead; } while (size_left != 0); *read_ptr = '\0'; fclose (fp); } return pz_data;}/* * * * * * * * * * * * * run_compiles run all the regexp compiles for all the fixes once. */voidrun_compiles (){ tSCC z_bad_comp[] = "fixincl ERROR: cannot compile %s regex for %s\n\\texpr = `%s'\n\terror %s\n"; tFixDesc *p_fixd = fixDescList; int fix_ct = FIX_COUNT; tTestDesc *p_test; int test_ct; int re_ct = REGEX_COUNT; const char *pz_err; regex_t *p_re = (regex_t *) malloc (REGEX_COUNT * sizeof (regex_t)); if (p_re == (regex_t *) NULL) { fprintf (stderr, "fixincl ERROR: cannot allocate %d bytes for regex\n", REGEX_COUNT * sizeof (regex_t)); exit (EXIT_FAILURE); } /* Make sure re_compile_pattern does not stumble across invalid data */ memset ( (void*)p_re, '\0', REGEX_COUNT * sizeof (regex_t) ); memset ( (void*)&incl_quote_re, '\0', sizeof (regex_t) ); /* The patterns we search for are all egrep patterns. In the shell version of this program, we invoke egrep with the supplied pattern. Here, we will run re_compile_pattern, but it must be using the same rules. */ re_set_syntax (RE_SYNTAX_EGREP); pz_err = re_compile_pattern (incl_quote_pat, sizeof (incl_quote_pat)-1, &incl_quote_re); if (pz_err != (char *) NULL) { fprintf (stderr, z_bad_comp, "quoted include", "run_compiles", incl_quote_pat, pz_err); exit (EXIT_FAILURE); } /* FOR every fixup, ... */ do { p_test = p_fixd->p_test_desc; test_ct = p_fixd->test_ct; /* IF the machine type pointer is not NULL (we are not in test mode) AND this test is for or not done on particular machines THEN ... */ if ( (pz_machine != NULL) && (p_fixd->papz_machs != (const char**) NULL) ) { const char **papz_machs = p_fixd->papz_machs; char *pz = file_name_buf; char *pz_sep = ""; tCC *pz_if_true; tCC *pz_if_false; tSCC skip[] = "skip"; tSCC run[] = "run"; /* Construct a shell script that looks like this: case our-cpu-platform-os in tests-cpu-platform-os-pattern ) echo run ;; * ) echo skip ;; esac where 'run' and 'skip' may be reversed, depending on the sense of the test. */ sprintf (pz, "case %s in\n", pz_machine); pz += strlen (pz); if (p_fixd->fd_flags & FD_MACH_IFNOT) { pz_if_true = skip; pz_if_false = run; } else { pz_if_true = run; pz_if_false = skip; } /* FOR any additional machine names to test for, insert the " | \\\n" glue and the machine pattern. */ for (;;) { const char* pz_mach = *(papz_machs++); if (pz_mach == (const char*) NULL) break; sprintf (pz, "%s %s", pz_sep, pz_mach); pz += strlen (pz); pz_sep = " | \\\n"; } sprintf (pz, " )\n echo %s ;;\n * )\n echo %s ;;\nesac", pz_if_true, pz_if_false); /* Run the script. The result will start either with 's' or 'r'. */ { int skip; pz = run_shell (file_name_buf); skip = (*pz == 's'); free ( (void*)pz ); if (skip) { p_fixd->fd_flags |= FD_SKIP_TEST; continue; } } } /* FOR every test for the fixup, ... */ while (--test_ct >= 0) { switch (p_test->type) { case TT_EGREP: case TT_NEGREP: /* You might consider putting the following under #ifdef. The number of re's used is computed by autogen. So, it is static and known at compile time. */ if (--re_ct < 0) { fputs ("out of RE's\n", stderr); exit (EXIT_FAILURE); } p_test->p_test_regex = p_re++; pz_err = re_compile_pattern (p_test->pz_test_text, strlen (p_test->pz_test_text), p_test->p_test_regex); if (pz_err != (char *) NULL) { fprintf (stderr, z_bad_comp, "select test", p_fixd->fix_name, p_test->pz_test_text, pz_err); exit (EXIT_FAILURE); } } p_test++; } } while (p_fixd++, --fix_ct > 0);}/* * * * * * * * * * * * * create_file Create the output modified file. Input: the name of the file to create Returns: a file pointer to the new, open file */#define S_IRALL (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)FILE *create_file (pz_file_name) const char *pz_file_name;{ int fd; FILE *pf; char fname[MAXPATHLEN];#ifdef DEBUG if (strncmp( pz_file_name, pz_find_base, find_base_len ) != 0) { fprintf (stderr, "Error: input file %s does not match %s/*\n", pz_file_name, pz_find_base ); exit (1); }#endif sprintf (fname, "%s/%s", pz_dest_dir, pz_file_name + find_base_len); fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL); /* We may need to create the directories needed... */ if ((fd < 0) && (errno == ENOENT)) { char *pz_dir = strchr (fname + 1, '/'); struct stat stbf; while (pz_dir != (char *) NULL) { *pz_dir = NUL; if (stat (fname, &stbf) < 0) { mkdir (fname, S_IFDIR | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } *pz_dir = '/'; pz_dir = strchr (pz_dir + 1, '/'); } /* Now, lets try the open again... */ fd = open (fname, O_WRONLY | O_CREAT | O_TRUNC, S_IRALL); } if (fd < 0) { fprintf (stderr, "Error %d (%s) creating %s\n", errno, strerror (errno), fname); exit (EXIT_FAILURE); } fprintf (stderr, "Fixed: %s\n", pz_file_name); pf = fdopen (fd, "w");#ifdef LATER { static const char hdr[] = "/* DO NOT EDIT THIS FILE.\n\n" " It has been auto-edited by fixincludes from /usr/include/%s\n" " This had to be done to correct non-standard usages in the\n" " original, manufacturer supplied header file. */\n\n"; fprintf (pf, hdr, pz_file_name); }#endif return pf;}/* * * * * * * * * * * * * test_test make sure a shell-style test expression passes. Input: a pointer to the descriptor of the test to run and the name of the file that we might want to fix Result: SUCCESS or FAILURE, depending on the result of the shell script we run. */t_successtest_test (p_test, pz_file_name) tTestDesc *p_test; char* pz_file_name;{ tSCC cmd_fmt[] ="file=%s\n\if ( test %s ) > /dev/null 2>&1\n\then echo TRUE\n\else echo FALSE\n\fi"; char *pz_res; t_success res = FAILURE; static char cmd_buf[4096]; sprintf (cmd_buf, cmd_fmt, pz_file_name, p_test->pz_test_text); pz_res = run_shell (cmd_buf); if (*pz_res == 'T') res = SUCCESS; free ((void *) pz_res); return res;}/* * * * * * * * * * * * * egrep_test make sure an egrep expression is found in the file text. Input: a pointer to the descriptor of the test to run and the pointer to the contents of the file under suspicion Result: SUCCESS if the pattern is found, FAILURE otherwise The caller may choose 'FAILURE' as 'SUCCESS' if the sense of the test is inverted. */t_successegrep_test (pz_data, p_test) char *pz_data; tTestDesc *p_test;{ regmatch_t match;#ifndef NO_BOGOSITY if (p_test->p_test_regex == 0) fprintf (stderr, "fixincl ERROR RE not compiled: `%s'\n", p_test->pz_test_text);#endif if (regexec (p_test->p_test_regex, pz_data, 1, &match, 0) == 0) return SUCCESS; return FAILURE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -