| |
| FIXINCLUDES OPERATION |
| ===================== |
| |
| See also: http://autogen.SourceForge.net/fixinc.html |
| |
| The set of fixes required was distilled down to just the data required |
| to specify what needed to happen for each fix. Those data were edited |
| into a file named gcc/fixinc/inclhack.def. A program called AutoGen |
| (http://autogen.SourceForge.net) uses these definitions to instantiate |
| several different templates that then produces code for a fixinclude |
| program (fixincl.x) and a shell script to test its functioning. On |
| certain platforms (viz. those that do not have functional bidirectional |
| pipes), the fixincl program is split into two. This should only concern |
| you on DOS and BeOS. |
| |
| Regards, |
| Bruce <bkorb@gnu.org> |
| |
| |
| |
| GCC MAINTAINER INFORMATION |
| ========================== |
| |
| If you are having some problem with a system header that is either |
| broken by the manufacturer, or is broken by the fixinclude process, |
| then you will need to alter or add information to the include fix |
| definitions file, ``inclhack.def''. Please also send relevant |
| information to gcc-bugs@gcc.gnu.org, gcc-patches@gcc.gnu.org and, |
| please, to me: bkorb@gnu.org. |
| |
| To make your fix, you will need to do several things: |
| |
| 1. Obtain access to the AutoGen program on some platform. It does |
| not have to be your build platform, but it is more convenient. |
| |
| 2. Edit "inclhack.def" to reflect the changes you need to make. |
| See below for information on how to make those changes. |
| |
| 3. Run the "genfixes" shell script to produce a new copy of |
| the "fixincl.x" file. |
| |
| 4. Rebuild the compiler and check the header causing the issue. |
| Make sure it is now properly handled. Add tests to the |
| "test_text" entry(ies) that validate your fix. This will |
| help ensure that future fixes won't negate your work. |
| |
| 5. Go into the fixinc build directory and type, "make check". |
| You are guaranteed to have issues printed out as a result. |
| Look at the diffs produced. Make sure you have not clobbered |
| the proper functioning of a different fix. Make sure your |
| fix is properly tested and it does what it is supposed to do. |
| |
| 6. Now that you have the right things happening, syncronize the |
| $(srcdir)/tests/base directory with the $(builddir)/tests/res |
| directory. The output of "make check" will be some diffs that |
| should give you some hints about what to do. |
| |
| 7. Rerun "make check" and verify that there are no issues left. |
| |
| |
| MAKING CHANGES TO INCLHACK.DEF |
| ============================== |
| |
| 0. If you are not the fixincludes maintainer, please send that |
| person email about any changes you may want to make. Thanks! |
| |
| 1. Every fix must have a "hackname" that is compatible with C syntax |
| for variable names and is unique without regard to alphabetic case. |
| Please keep them alphabetical by this name. :-) |
| |
| 2. If the problem is known to exist only in certain files, |
| then name each such file with a "files = " entry. |
| |
| 3. It is relatively expensive to fire off a process to fix a source |
| file, therefore write apply tests to avoid unnecessary fix |
| processes. The preferred apply tests are "select", "bypass" and |
| "c_test" because they are performed internally. "test" sends |
| a command to a server shell that actually fires off one or more |
| processes to do the testing. Avoid it, if you can, but it is |
| still more efficient than a fix process. Also available is |
| "mach". If the target machine matches any of the named |
| globbing-style patterns, then the machine name test will pass. |
| It is desired, however, to limit the use of this test. |
| |
| These tests are required to: |
| |
| 1. Be positive for all header files that require the fix. |
| |
| It is desireable to: |
| |
| 2. Be negative as often as possible whenever the fix is not |
| required, avoiding the process overhead. |
| |
| It is nice if: |
| |
| 3. The expression is as simple as possible to both |
| process and understand by people. :-) |
| |
| Please take advantage of the fact AutoGen will glue |
| together string fragments. It helps. Also take note |
| that double quote strings and single quote strings have |
| different formation rules. Double quote strings are a |
| tiny superset of ANSI-C string syntax. Single quote |
| strings follow shell single quote string formation |
| rules, except that the backslash is processed before |
| '\\', '\'' and '#' characters (using C character syntax). |
| |
| Examples of test specifications: |
| |
| hackname = broken_assert_stdio; |
| files = assert.h; |
| select = stderr; |
| bypass = "include.*stdio.h"; |
| |
| The ``broken_assert_stdio'' fix will be applied only to a file |
| named "assert.h" if it contains the string "stderr" _and_ it |
| does _not_ contain the expression "include.*stdio.h". |
| |
| hackname = no_double_slash; |
| c_test = "double_slash"; |
| |
| The ``no_double_slash'' fix will be applied if the |
| ``double_slash_test()'' function says to. See ``fixtests.c'' |
| for documentation on how to include new functions into that |
| module. |
| |
| 4. There are currently four methods of fixing a file: |
| |
| 1. a series of sed expressions. Each will be an individual |
| "-e" argument to a single invocation of sed. |
| |
| 2. a shell script. These scripts are _required_ to read all |
| of stdin in order to avoid pipe stalls. They may choose to |
| discard the input. |
| |
| 3. Replacement text. If the replacement is empty, then no |
| fix is applied. Otherwise, the replacement text is |
| written to the output file and no further fixes are |
| applied. If you really want a no-op file, replace the |
| file with a comment. |
| |
| Replacement text "fixes" must be first in this file!! |
| |
| 4. A C language subroutine method for both tests and fixes. |
| See ``fixtests.c'' for instructions on writing C-language |
| applicability tests and ``fixfixes.c'' for C-language fixing. |
| These files also contain tables that describe the currently |
| implemented fixes and tests. |
| |
| If at all possible, you should try to use one of the C language |
| fixes as it is far more efficient. There are currently five |
| such fixes, three of which are very special purpose: |
| |
| i) char_macro_def - This function repairs the definition of an |
| ioctl macro that presumes CPP macro substitution within |
| pairs of single quote characters. |
| |
| ii) char_macro_use - This function repairs the usage of ioctl |
| macros that no longer can wrap an argument with single quotes. |
| |
| iii) machine_name - This function will look at "#if", "#ifdef", |
| "#ifndef" and "#elif" directive lines and replace the first |
| occurrence of a non-reserved name that is traditionally |
| pre-defined by the native compiler. |
| |
| The next two are for general use: |
| |
| iv) wrap - wraps the entire file with "#ifndef", "#define" and |
| "#endif" self-exclusionary text. It also, optionally, inserts |
| a prolog after the "#define" and an epilog just before the |
| "#endif". You can use this for a fix as follows: |
| |
| c_fix = wrap; |
| c_fix_arg = "/* prolog text */"; |
| c_fix_arg = "/* epilog text */"; |
| |
| If you want an epilog without a prolog, set the first "c_fix_arg" |
| to the empty string. Both or the second "c_fix_arg"s may be |
| omitted and the file will still be wrapped. |
| |
| THERE IS A SPECIAL EXCEPTION TO THIS, HOWEVER: |
| |
| If the regular expression '#if.*__need' is found, then it is |
| assumed that the file needs to be read and interpreted more |
| than once. However, the prolog and epilog text (if any) will |
| be inserted. |
| |
| v) format - Replaces text selected with a regular expression with |
| a specialized formating string. The formatting works as follows: |
| The format text is copied to the output until a '%' character |
| is found. If the character after the '%' is another '%', then |
| one '%' is output and processing continues. If the following |
| character is not a digit, then the '%' and that character are |
| copied and processing continues. Finally, if the '%' *is* |
| followed by a digit, that digit is used as an index into the |
| regmatch_t array to replace the two characters with the matched |
| text. i.e.: "%0" is replaced by the full matching text, "%1" |
| is the first matching sub-expression, etc. |
| |
| This is used as follows: |
| |
| c_fix = format; |
| c_fix_arg = "#ifndef %1\n%0\n#endif"; |
| c_fix_arg = "#define[ \t]+([A-Z][A-Z0-9a-z_]*).*"; |
| |
| This would wrap a traditional #define inside of a "#ifndef"/"#endif" |
| pair. The second "c_fix_arg" may be omitted *IF* there is |
| a select clause and the first one matches the text you want |
| replaced. You may delete text by supplying an empty string for |
| the format (the first "c_fix_arg"). |
| |
| Note: In general, a format c_fix may be used in place of one |
| sed expression. However, it will need to be rewritten by |
| hand. For example: |
| |
| sed = 's@^#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7$' |
| '@& || __GNUC__ >= 3@'; |
| |
| may be rewritten using a format c_fix as: |
| |
| c_fix = format; |
| c_fix_arg = '%0 || __GNUC__ >= 3'; |
| c_fix_arg = '^#if __GNUC__ == 2 && __GNUC_MINOR__ >= 7$'; |
| |
| Multiple sed substitution expressions probably ought to remain sed |
| expressions in order to maintain clarity. Also note that if the |
| second sed expression is the same as the first select expression, |
| then you may omit the second c_fix_arg. The select expression will |
| be picked up and used in its absence. |
| |
| EXAMPLES OF FIXES: |
| ================== |
| |
| hackname = AAA_ki_iface; |
| replace; /* empty replacement -> no fixing the file */ |
| |
| When this ``fix'' is invoked, it will prevent any fixes |
| from being applied. |
| |
| ------------------ |
| |
| hackname = AAB_svr4_no_varargs; |
| replace = "/* This file was generated by fixincludes. */\n" |
| "#ifndef _SYS_VARARGS_H\n" |
| "#define _SYS_VARARGS_H\n\n" |
| |
| "#ifdef __STDC__\n" |
| "#include <stdarg.h>\n" |
| "#else\n" |
| "#include <varargs.h>\n" |
| "#endif\n\n" |
| |
| "#endif /* _SYS_VARARGS_H */\n"; |
| |
| When this ``fix'' is invoked, the replacement text will be |
| emitted into the replacement include file. No further fixes |
| will be applied. |
| |
| ------------------ |
| |
| hackname = hpux11_fabsf; |
| files = math.h; |
| select = "^[ \t]*#[ \t]*define[ \t]+fabsf\\(.*"; |
| bypass = "__cplusplus"; |
| |
| c_fix = format; |
| c_fix_arg = "#ifndef __cplusplus\n%0\n#endif"; |
| |
| test_text = |
| "# define fabsf(x) ((float)fabs((double)(float)(x)))\n"; |
| |
| This fix will ensure that the #define for fabs is wrapped |
| with C++ protection, providing the header is not already |
| C++ aware. |
| |
| ------------------ |
| |
| 5. Testing fixes. |
| |
| The brute force method is, of course, to configure and build |
| GCC. But you can also: |
| |
| cd ${top_builddir}/gcc |
| rm -rf fixinc.sh include/ stmp-fixinc |
| make stmp-fixinc |
| |
| I would really recommend, however: |
| |
| cd ${top_builddir}/gcc/fixinc |
| make check |
| |
| To do this, you *must* have autogen installed on your system. |
| The "check" step will proceed to construct a shell script that |
| will exercize all the fixes, using the sample test_text |
| provided with each fix. Once done, the changes made will |
| be compared against the changes saved in the source directory. |
| If you are changing the tests or fixes, the change will likely |
| be highlighted. |