| |
| 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. |
| Do *NOT* specify test text for "wrap" or "replacement" fixes. |
| There is no real possibility that these fixes will fail. |
| If they do, you will surely know straight away. |
| |
| NOTE: "test_text" is interpreted by the shell as it gets |
| copied into the test header. THEREFORE you must quote |
| dollar sign characters and back quotes -- unless you mean |
| for them to be interpreted by the shell. |
| |
| e.g. the math_huge_val_from_dbl_max test_text needs to |
| put text into both float.h and math.h, so it includes a |
| back-quoted script to add text to float.h. |
| |
| 5. Go into the fixincludes 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, synchronize 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 |
| identify the files with "files = " entries. If you use fnmatch(3C) |
| wild card characters in a "files" entry, be certain that the first |
| "files" entry has no such character. Otherwise, the "make check" |
| machinery will attempt to create files with those characters in the |
| name. That is inconvenient. |
| |
| 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", "mach" |
| "sum", and "c-test" because they are performed internally: |
| |
| * select - Run a regex on the contents of the file being considered. |
| All such regex-es must match. Matching is done with |
| extended regular expressions. |
| |
| * bypass - Run a regex on the contents of the file being considered. |
| No such regex may match. |
| |
| * sum - Select a specific version of a file that has a matching |
| check sum. The BSD version of checksum ["sum(1BSD)"] |
| is used. Each "sum" entry should contain exactly three |
| space separated tokens: the sum, some number and the |
| basename of the file. The "some number" is ignored. |
| If there are multiple "sum" entries, only one needs to |
| match in order to pass. For example: |
| |
| sum = '1234 3 foobar.h'; |
| |
| specifies that the "foobar.h" header in any directory |
| will match if it has the checksum 1234. |
| |
| * c_test - call a function in fixtests.c. See that file. |
| |
| * files - the "fnmatch" pattern of the file(s) to examine for |
| the issue. There may be several copies of this attribute. |
| If the header lives in a /usr/include subdirectory, be |
| sure to include that subdirectory in the name. e.g. net/if.h |
| |
| * mach - Match the output of config.guess against a series of fnmatch |
| patterns. It must match at least one of the patterns, unless |
| "not-machine" has also been specified. In that case, the |
| config.guess output must not match any of the patterns. |
| |
| The next test is relatively slow because it must be handled in a |
| separate shell process. Some platforms do not support server shells, |
| so the whole process is even slower and more cumbersome there. |
| |
| * test - These should be arguments to the program, "/bin/test". |
| You may perform multiple commands, if you enclose them |
| in backquotes and echo out valid test arguments. For |
| example, you might echo out '0 -eq 1' if you want a false |
| result, or '0 -eq 0' for a true result. |
| |
| These tests are required to: |
| |
| 1. Be positive for all header files that require the fix. |
| |
| It is desirable 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). |
| |
| Each test must pass or the fix is not applied. For example, |
| all "select" expressions must be found and not one "bypass" |
| selection may be found. |
| |
| 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. Unless you |
| need to use multiple or complex sed expressions, please |
| use the "replacement text" method instead. |
| |
| 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 one line #define inside of a "#ifndef"/"#endif" |
| pair. The second "c_fix_arg" may be omitted *IF* there is at least |
| one select clause and the first one identifies the text you wish to |
| reformat. It will then be used as the second "c_fix_arg". You may |
| delete the selected text by supplying an empty string for the |
| replacement 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 include-fixed/ stmp-fixinc |
| make stmp-fixinc |
| |
| I would really recommend, however: |
| |
| cd ${top_builddir}/fixincludes |
| 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 exercise 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. |