Zack Weinberg | 5538ada | 1999-02-04 06:36:54 -0500 | [diff] [blame] | 1 | /* CPP Library. |
Jeff Law | 5e7b4e2 | 2000-02-25 22:59:31 -0700 | [diff] [blame] | 2 | Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, |
Graham Stott | 745b26b | 2002-01-03 03:55:19 +0000 | [diff] [blame] | 3 | 1999, 2000, 2001, 2002 Free Software Foundation, Inc. |
Zack Weinberg | 5538ada | 1999-02-04 06:36:54 -0500 | [diff] [blame] | 4 | Contributed by Per Bothner, 1994-95. |
| 5 | Based on CCCP program by Paul Rubin, June 1986 |
| 6 | Adapted to ANSI C, Richard Stallman, Jan 1987 |
| 7 | |
| 8 | This program is free software; you can redistribute it and/or modify it |
| 9 | under the terms of the GNU General Public License as published by the |
| 10 | Free Software Foundation; either version 2, or (at your option) any |
| 11 | later version. |
| 12 | |
| 13 | This program is distributed in the hope that it will be useful, |
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | GNU General Public License for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License |
| 19 | along with this program; if not, write to the Free Software |
| 20 | Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
| 21 | |
Zack Weinberg | 5538ada | 1999-02-04 06:36:54 -0500 | [diff] [blame] | 22 | #include "config.h" |
| 23 | #include "system.h" |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 24 | #include "cpplib.h" |
| 25 | #include "cpphash.h" |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 26 | #include "prefix.h" |
| 27 | #include "intl.h" |
Kaveh R. Ghazi | 9f8f4ef | 2000-02-15 16:36:35 +0000 | [diff] [blame] | 28 | #include "version.h" |
Zack Weinberg | 49e6c08 | 2000-03-04 19:42:04 +0000 | [diff] [blame] | 29 | #include "mkdeps.h" |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 30 | #include "cppdefault.h" |
Zack Weinberg | 0d24f4d | 2002-01-08 19:03:20 +0000 | [diff] [blame] | 31 | #include "except.h" /* for USING_SJLJ_EXCEPTIONS */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 32 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 33 | /* Predefined symbols, built-in macros, and the default include path. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 34 | |
| 35 | #ifndef GET_ENV_PATH_LIST |
| 36 | #define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) |
| 37 | #endif |
| 38 | |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 39 | /* Windows does not natively support inodes, and neither does MSDOS. |
| 40 | Cygwin's emulation can generate non-unique inodes, so don't use it. |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 41 | VMS has non-numeric inodes. */ |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 42 | #ifdef VMS |
Douglas B Rupp | ca47c89 | 2001-11-21 16:55:36 -0500 | [diff] [blame] | 43 | # define INO_T_EQ(A, B) (!memcmp (&(A), &(B), sizeof (A))) |
| 44 | # define INO_T_COPY(DEST, SRC) memcpy(&(DEST), &(SRC), sizeof (SRC)) |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 45 | #else |
Michael Sokolov | 3943e75 | 2001-01-21 02:26:27 +0000 | [diff] [blame] | 46 | # if (defined _WIN32 && ! defined (_UWIN)) || defined __MSDOS__ |
Douglas B Rupp | ca47c89 | 2001-11-21 16:55:36 -0500 | [diff] [blame] | 47 | # define INO_T_EQ(A, B) 0 |
Michael Sokolov | 3943e75 | 2001-01-21 02:26:27 +0000 | [diff] [blame] | 48 | # else |
Douglas B Rupp | ca47c89 | 2001-11-21 16:55:36 -0500 | [diff] [blame] | 49 | # define INO_T_EQ(A, B) ((A) == (B)) |
Michael Sokolov | 3943e75 | 2001-01-21 02:26:27 +0000 | [diff] [blame] | 50 | # endif |
Douglas B Rupp | ca47c89 | 2001-11-21 16:55:36 -0500 | [diff] [blame] | 51 | # define INO_T_COPY(DEST, SRC) (DEST) = (SRC) |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 52 | #endif |
| 53 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 54 | /* Internal structures and prototypes. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 55 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 56 | /* A `struct pending_option' remembers one -D, -A, -U, -include, or |
| 57 | -imacros switch. */ |
Kaveh R. Ghazi | 8be1ddc | 2000-03-12 13:55:52 +0000 | [diff] [blame] | 58 | typedef void (* cl_directive_handler) PARAMS ((cpp_reader *, const char *)); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 59 | struct pending_option |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 60 | { |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 61 | struct pending_option *next; |
Neil Booth | 7ceb359 | 2000-03-11 00:49:44 +0000 | [diff] [blame] | 62 | const char *arg; |
Neil Booth | 40eac64 | 2000-03-11 09:13:00 +0000 | [diff] [blame] | 63 | cl_directive_handler handler; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 64 | }; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 65 | |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 66 | /* The `pending' structure accumulates all the options that are not |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 67 | actually processed until we hit cpp_read_main_file. It consists of |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 68 | several lists, one for each type of option. We keep both head and |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 69 | tail pointers for quick insertion. */ |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 70 | struct cpp_pending |
| 71 | { |
Neil Booth | 40eac64 | 2000-03-11 09:13:00 +0000 | [diff] [blame] | 72 | struct pending_option *directive_head, *directive_tail; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 73 | |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 74 | struct search_path *quote_head, *quote_tail; |
| 75 | struct search_path *brack_head, *brack_tail; |
| 76 | struct search_path *systm_head, *systm_tail; |
| 77 | struct search_path *after_head, *after_tail; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 78 | |
| 79 | struct pending_option *imacros_head, *imacros_tail; |
| 80 | struct pending_option *include_head, *include_tail; |
| 81 | }; |
| 82 | |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 83 | #ifdef __STDC__ |
| 84 | #define APPEND(pend, list, elt) \ |
| 85 | do { if (!(pend)->list##_head) (pend)->list##_head = (elt); \ |
| 86 | else (pend)->list##_tail->next = (elt); \ |
| 87 | (pend)->list##_tail = (elt); \ |
| 88 | } while (0) |
| 89 | #else |
| 90 | #define APPEND(pend, list, elt) \ |
| 91 | do { if (!(pend)->list/**/_head) (pend)->list/**/_head = (elt); \ |
| 92 | else (pend)->list/**/_tail->next = (elt); \ |
| 93 | (pend)->list/**/_tail = (elt); \ |
| 94 | } while (0) |
| 95 | #endif |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 96 | |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 97 | static void print_help PARAMS ((void)); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 98 | static void path_include PARAMS ((cpp_reader *, |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 99 | char *, int)); |
Neil Booth | 674c3b4 | 2001-01-08 18:52:09 +0000 | [diff] [blame] | 100 | static void init_library PARAMS ((void)); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 101 | static void init_builtins PARAMS ((cpp_reader *)); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 102 | static void append_include_chain PARAMS ((cpp_reader *, |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 103 | char *, int, int)); |
Nathan Sidwell | 002ee64 | 2001-07-20 10:30:47 +0000 | [diff] [blame] | 104 | static struct search_path * remove_dup_dir PARAMS ((cpp_reader *, |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 105 | struct search_path *)); |
Nathan Sidwell | 002ee64 | 2001-07-20 10:30:47 +0000 | [diff] [blame] | 106 | static struct search_path * remove_dup_dirs PARAMS ((cpp_reader *, |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 107 | struct search_path *)); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 108 | static void merge_include_chains PARAMS ((cpp_reader *)); |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 109 | static bool push_include PARAMS ((cpp_reader *, |
| 110 | struct pending_option *)); |
| 111 | static void free_chain PARAMS ((struct pending_option *)); |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 112 | static void set_lang PARAMS ((cpp_reader *, enum c_lang)); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 113 | static void init_dependency_output PARAMS ((cpp_reader *)); |
| 114 | static void init_standard_includes PARAMS ((cpp_reader *)); |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 115 | static void read_original_filename PARAMS ((cpp_reader *)); |
Zack Weinberg | 2c0accc | 2000-07-15 19:29:14 +0000 | [diff] [blame] | 116 | static void new_pending_directive PARAMS ((struct cpp_pending *, |
Neil Booth | 40eac64 | 2000-03-11 09:13:00 +0000 | [diff] [blame] | 117 | const char *, |
| 118 | cl_directive_handler)); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 119 | static void output_deps PARAMS ((cpp_reader *)); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 120 | static int parse_option PARAMS ((const char *)); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 121 | |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 122 | /* Fourth argument to append_include_chain: chain to use. |
| 123 | Note it's never asked to append to the quote chain. */ |
| 124 | enum { BRACKET = 0, SYSTEM, AFTER }; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 125 | |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 126 | /* If we have designated initializers (GCC >2.7) these tables can be |
| 127 | initialized, constant data. Otherwise, they have to be filled in at |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 128 | runtime. */ |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 129 | #if HAVE_DESIGNATED_INITIALIZERS |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 130 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 131 | #define init_trigraph_map() /* Nothing. */ |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 132 | #define TRIGRAPH_MAP \ |
Neil Booth | 562a5c2 | 2002-04-21 18:46:42 +0000 | [diff] [blame^] | 133 | __extension__ const uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 134 | |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 135 | #define END }; |
Zack Weinberg | 455d258 | 2000-03-04 01:42:56 +0000 | [diff] [blame] | 136 | #define s(p, v) [p] = v, |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 137 | |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 138 | #else |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 139 | |
Neil Booth | 562a5c2 | 2002-04-21 18:46:42 +0000 | [diff] [blame^] | 140 | #define TRIGRAPH_MAP uchar _cpp_trigraph_map[UCHAR_MAX + 1] = { 0 }; \ |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 141 | static void init_trigraph_map PARAMS ((void)) { \ |
| 142 | unsigned char *x = _cpp_trigraph_map; |
| 143 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 144 | #define END } |
Zack Weinberg | 455d258 | 2000-03-04 01:42:56 +0000 | [diff] [blame] | 145 | #define s(p, v) x[p] = v; |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 146 | |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 147 | #endif |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 148 | |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 149 | TRIGRAPH_MAP |
| 150 | s('=', '#') s(')', ']') s('!', '|') |
| 151 | s('(', '[') s('\'', '^') s('>', '}') |
| 152 | s('/', '\\') s('<', '{') s('-', '~') |
| 153 | END |
| 154 | |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 155 | #undef s |
Zack Weinberg | 455d258 | 2000-03-04 01:42:56 +0000 | [diff] [blame] | 156 | #undef END |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 157 | #undef TRIGRAPH_MAP |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 158 | |
| 159 | /* Given a colon-separated list of file names PATH, |
| 160 | add all the names to the search path for include files. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 161 | static void |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 162 | path_include (pfile, list, path) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 163 | cpp_reader *pfile; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 164 | char *list; |
| 165 | int path; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 166 | { |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 167 | char *p, *q, *name; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 168 | |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 169 | p = list; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 170 | |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 171 | do |
| 172 | { |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 173 | /* Find the end of this name. */ |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 174 | q = p; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 175 | while (*q != 0 && *q != PATH_SEPARATOR) q++; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 176 | if (q == p) |
| 177 | { |
| 178 | /* An empty name in the path stands for the current directory. */ |
| 179 | name = (char *) xmalloc (2); |
| 180 | name[0] = '.'; |
| 181 | name[1] = 0; |
| 182 | } |
| 183 | else |
| 184 | { |
| 185 | /* Otherwise use the directory that is named. */ |
| 186 | name = (char *) xmalloc (q - p + 1); |
| 187 | memcpy (name, p, q - p); |
| 188 | name[q - p] = 0; |
| 189 | } |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 190 | |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 191 | append_include_chain (pfile, name, path, 0); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 192 | |
| 193 | /* Advance past this name. */ |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 194 | if (*q == 0) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 195 | break; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 196 | p = q + 1; |
| 197 | } |
| 198 | while (1); |
| 199 | } |
| 200 | |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 201 | /* Append DIR to include path PATH. DIR must be allocated on the |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 202 | heap; this routine takes responsibility for freeing it. CXX_AWARE |
| 203 | is non-zero if the header contains extern "C" guards for C++, |
| 204 | otherwise it is zero. */ |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 205 | static void |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 206 | append_include_chain (pfile, dir, path, cxx_aware) |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 207 | cpp_reader *pfile; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 208 | char *dir; |
| 209 | int path; |
Zack Weinberg | 7d4918a | 2001-02-07 18:32:42 +0000 | [diff] [blame] | 210 | int cxx_aware ATTRIBUTE_UNUSED; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 211 | { |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 212 | struct cpp_pending *pend = CPP_OPTION (pfile, pending); |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 213 | struct search_path *new; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 214 | struct stat st; |
| 215 | unsigned int len; |
| 216 | |
Neil Booth | f9200da | 2001-04-06 07:22:01 +0000 | [diff] [blame] | 217 | if (*dir == '\0') |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 218 | { |
| 219 | free (dir); |
| 220 | dir = xstrdup ("."); |
| 221 | } |
Zack Weinberg | b0699da | 2000-03-07 20:58:47 +0000 | [diff] [blame] | 222 | _cpp_simplify_pathname (dir); |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 223 | |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 224 | if (stat (dir, &st)) |
| 225 | { |
Neil Booth | f9200da | 2001-04-06 07:22:01 +0000 | [diff] [blame] | 226 | /* Dirs that don't exist are silently ignored. */ |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 227 | if (errno != ENOENT) |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 228 | cpp_errno (pfile, DL_ERROR, dir); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 229 | else if (CPP_OPTION (pfile, verbose)) |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 230 | fprintf (stderr, _("ignoring nonexistent directory \"%s\"\n"), dir); |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 231 | free (dir); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 232 | return; |
| 233 | } |
| 234 | |
| 235 | if (!S_ISDIR (st.st_mode)) |
| 236 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 237 | cpp_error_with_line (pfile, DL_ERROR, 0, 0, "%s: Not a directory", dir); |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 238 | free (dir); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 239 | return; |
| 240 | } |
| 241 | |
| 242 | len = strlen (dir); |
| 243 | if (len > pfile->max_include_len) |
| 244 | pfile->max_include_len = len; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 245 | |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 246 | new = (struct search_path *) xmalloc (sizeof (struct search_path)); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 247 | new->name = dir; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 248 | new->len = len; |
Douglas B Rupp | ca47c89 | 2001-11-21 16:55:36 -0500 | [diff] [blame] | 249 | INO_T_COPY (new->ino, st.st_ino); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 250 | new->dev = st.st_dev; |
Christopher Faylor | 4737b27 | 2001-03-02 17:20:30 +0000 | [diff] [blame] | 251 | /* Both systm and after include file lists should be treated as system |
| 252 | include files since these two lists are really just a concatenation |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 253 | of one "system" list. */ |
Christopher Faylor | 4737b27 | 2001-03-02 17:20:30 +0000 | [diff] [blame] | 254 | if (path == SYSTEM || path == AFTER) |
Jakub Jelinek | 52b357e | 2001-02-03 21:48:32 +0100 | [diff] [blame] | 255 | #ifdef NO_IMPLICIT_EXTERN_C |
| 256 | new->sysp = 1; |
| 257 | #else |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 258 | new->sysp = cxx_aware ? 1 : 2; |
Jakub Jelinek | 52b357e | 2001-02-03 21:48:32 +0100 | [diff] [blame] | 259 | #endif |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 260 | else |
| 261 | new->sysp = 0; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 262 | new->name_map = NULL; |
Dave Brolley | 503cb43 | 1999-09-13 16:58:44 +0000 | [diff] [blame] | 263 | new->next = NULL; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 264 | |
| 265 | switch (path) |
| 266 | { |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 267 | case BRACKET: APPEND (pend, brack, new); break; |
| 268 | case SYSTEM: APPEND (pend, systm, new); break; |
| 269 | case AFTER: APPEND (pend, after, new); break; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 270 | } |
| 271 | } |
| 272 | |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 273 | /* Handle a duplicated include path. PREV is the link in the chain |
| 274 | before the duplicate. The duplicate is removed from the chain and |
| 275 | freed. Returns PREV. */ |
Nathan Sidwell | 002ee64 | 2001-07-20 10:30:47 +0000 | [diff] [blame] | 276 | static struct search_path * |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 277 | remove_dup_dir (pfile, prev) |
| 278 | cpp_reader *pfile; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 279 | struct search_path *prev; |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 280 | { |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 281 | struct search_path *cur = prev->next; |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 282 | |
| 283 | if (CPP_OPTION (pfile, verbose)) |
| 284 | fprintf (stderr, _("ignoring duplicate directory \"%s\"\n"), cur->name); |
| 285 | |
| 286 | prev->next = cur->next; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 287 | free ((PTR) cur->name); |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 288 | free (cur); |
| 289 | |
| 290 | return prev; |
| 291 | } |
| 292 | |
| 293 | /* Remove duplicate directories from a chain. Returns the tail of the |
| 294 | chain, or NULL if the chain is empty. This algorithm is quadratic |
| 295 | in the number of -I switches, which is acceptable since there |
| 296 | aren't usually that many of them. */ |
Nathan Sidwell | 002ee64 | 2001-07-20 10:30:47 +0000 | [diff] [blame] | 297 | static struct search_path * |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 298 | remove_dup_dirs (pfile, head) |
| 299 | cpp_reader *pfile; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 300 | struct search_path *head; |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 301 | { |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 302 | struct search_path *prev = NULL, *cur, *other; |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 303 | |
| 304 | for (cur = head; cur; cur = cur->next) |
| 305 | { |
| 306 | for (other = head; other != cur; other = other->next) |
| 307 | if (INO_T_EQ (cur->ino, other->ino) && cur->dev == other->dev) |
| 308 | { |
Nathan Sidwell | 002ee64 | 2001-07-20 10:30:47 +0000 | [diff] [blame] | 309 | if (cur->sysp && !other->sysp) |
Nathan Sidwell | dbead49 | 2001-07-04 20:06:27 +0000 | [diff] [blame] | 310 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 311 | cpp_error (pfile, DL_WARNING, |
| 312 | "changing search order for system directory \"%s\"", |
| 313 | cur->name); |
Nathan Sidwell | dbead49 | 2001-07-04 20:06:27 +0000 | [diff] [blame] | 314 | if (strcmp (cur->name, other->name)) |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 315 | cpp_error (pfile, DL_WARNING, |
| 316 | " as it is the same as non-system directory \"%s\"", |
| 317 | other->name); |
Nathan Sidwell | dbead49 | 2001-07-04 20:06:27 +0000 | [diff] [blame] | 318 | else |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 319 | cpp_error (pfile, DL_WARNING, |
| 320 | " as it has already been specified as a non-system directory"); |
Nathan Sidwell | dbead49 | 2001-07-04 20:06:27 +0000 | [diff] [blame] | 321 | } |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 322 | cur = remove_dup_dir (pfile, prev); |
| 323 | break; |
| 324 | } |
| 325 | prev = cur; |
| 326 | } |
| 327 | |
| 328 | return prev; |
| 329 | } |
| 330 | |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 331 | /* Merge the four include chains together in the order quote, bracket, |
| 332 | system, after. Remove duplicate dirs (as determined by |
| 333 | INO_T_EQ()). The system_include and after_include chains are never |
| 334 | referred to again after this function; all access is through the |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 335 | bracket_include path. */ |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 336 | static void |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 337 | merge_include_chains (pfile) |
| 338 | cpp_reader *pfile; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 339 | { |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 340 | struct search_path *quote, *brack, *systm, *qtail; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 341 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 342 | struct cpp_pending *pend = CPP_OPTION (pfile, pending); |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 343 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 344 | quote = pend->quote_head; |
| 345 | brack = pend->brack_head; |
| 346 | systm = pend->systm_head; |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 347 | qtail = pend->quote_tail; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 348 | |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 349 | /* Paste together bracket, system, and after include chains. */ |
| 350 | if (systm) |
| 351 | pend->systm_tail->next = pend->after_head; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 352 | else |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 353 | systm = pend->after_head; |
| 354 | |
| 355 | if (brack) |
| 356 | pend->brack_tail->next = systm; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 357 | else |
| 358 | brack = systm; |
| 359 | |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 360 | /* This is a bit tricky. First we drop dupes from the quote-include |
| 361 | list. Then we drop dupes from the bracket-include list. |
| 362 | Finally, if qtail and brack are the same directory, we cut out |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 363 | brack and move brack up to point to qtail. |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 364 | |
| 365 | We can't just merge the lists and then uniquify them because |
| 366 | then we may lose directories from the <> search path that should |
| 367 | be there; consider -Ifoo -Ibar -I- -Ifoo -Iquux. It is however |
| 368 | safe to treat -Ibar -Ifoo -I- -Ifoo -Iquux as if written |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 369 | -Ibar -I- -Ifoo -Iquux. */ |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 370 | |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 371 | remove_dup_dirs (pfile, brack); |
| 372 | qtail = remove_dup_dirs (pfile, quote); |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 373 | |
| 374 | if (quote) |
| 375 | { |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 376 | qtail->next = brack; |
| 377 | |
| 378 | /* If brack == qtail, remove brack as it's simpler. */ |
Zack Weinberg | afb5828 | 2002-02-17 02:54:20 +0000 | [diff] [blame] | 379 | if (brack && INO_T_EQ (qtail->ino, brack->ino) |
| 380 | && qtail->dev == brack->dev) |
Neil Booth | dd69c71 | 2000-08-17 18:03:59 +0000 | [diff] [blame] | 381 | brack = remove_dup_dir (pfile, qtail); |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 382 | } |
| 383 | else |
Neil Booth | bef985f | 2001-08-11 12:37:19 +0000 | [diff] [blame] | 384 | quote = brack; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 385 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 386 | CPP_OPTION (pfile, quote_include) = quote; |
| 387 | CPP_OPTION (pfile, bracket_include) = brack; |
Zack Weinberg | 88ae23e | 2000-03-08 23:35:19 +0000 | [diff] [blame] | 388 | } |
| 389 | |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 390 | /* A set of booleans indicating what CPP features each source language |
| 391 | requires. */ |
Zack Weinberg | a01eb54 | 2001-07-02 18:55:35 +0000 | [diff] [blame] | 392 | struct lang_flags |
| 393 | { |
| 394 | char c99; |
| 395 | char objc; |
| 396 | char cplusplus; |
| 397 | char extended_numbers; |
| 398 | char trigraphs; |
| 399 | char dollars_in_ident; |
| 400 | char cplusplus_comments; |
| 401 | char digraphs; |
| 402 | }; |
| 403 | |
| 404 | /* ??? Enable $ in identifiers in assembly? */ |
| 405 | static const struct lang_flags lang_defaults[] = |
| 406 | { /* c99 objc c++ xnum trig dollar c++comm digr */ |
| 407 | /* GNUC89 */ { 0, 0, 0, 1, 0, 1, 1, 1 }, |
| 408 | /* GNUC99 */ { 1, 0, 0, 1, 0, 1, 1, 1 }, |
| 409 | /* STDC89 */ { 0, 0, 0, 0, 1, 0, 0, 0 }, |
| 410 | /* STDC94 */ { 0, 0, 0, 0, 1, 0, 0, 1 }, |
| 411 | /* STDC99 */ { 1, 0, 0, 1, 1, 0, 1, 1 }, |
| 412 | /* GNUCXX */ { 0, 0, 1, 1, 0, 1, 1, 1 }, |
| 413 | /* CXX98 */ { 0, 0, 1, 1, 1, 0, 1, 1 }, |
| 414 | /* OBJC */ { 0, 1, 0, 1, 0, 1, 1, 1 }, |
| 415 | /* OBJCXX */ { 0, 1, 1, 1, 0, 1, 1, 1 }, |
| 416 | /* ASM */ { 0, 0, 0, 1, 0, 0, 1, 0 } |
| 417 | }; |
| 418 | |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 419 | /* Sets internal flags correctly for a given language. */ |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 420 | static void |
| 421 | set_lang (pfile, lang) |
| 422 | cpp_reader *pfile; |
| 423 | enum c_lang lang; |
| 424 | { |
Zack Weinberg | a01eb54 | 2001-07-02 18:55:35 +0000 | [diff] [blame] | 425 | const struct lang_flags *l = &lang_defaults[(int) lang]; |
| 426 | |
Neil Booth | bdb05a7 | 2000-11-26 17:31:13 +0000 | [diff] [blame] | 427 | CPP_OPTION (pfile, lang) = lang; |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 428 | |
Zack Weinberg | a01eb54 | 2001-07-02 18:55:35 +0000 | [diff] [blame] | 429 | CPP_OPTION (pfile, c99) = l->c99; |
| 430 | CPP_OPTION (pfile, objc) = l->objc; |
| 431 | CPP_OPTION (pfile, cplusplus) = l->cplusplus; |
| 432 | CPP_OPTION (pfile, extended_numbers) = l->extended_numbers; |
| 433 | CPP_OPTION (pfile, trigraphs) = l->trigraphs; |
| 434 | CPP_OPTION (pfile, dollars_in_ident) = l->dollars_in_ident; |
| 435 | CPP_OPTION (pfile, cplusplus_comments) = l->cplusplus_comments; |
| 436 | CPP_OPTION (pfile, digraphs) = l->digraphs; |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 437 | } |
| 438 | |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 439 | #ifdef HOST_EBCDIC |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 440 | static int opt_comp PARAMS ((const void *, const void *)); |
| 441 | |
| 442 | /* Run-time sorting of options array. */ |
| 443 | static int |
| 444 | opt_comp (p1, p2) |
| 445 | const void *p1, *p2; |
| 446 | { |
| 447 | return strcmp (((struct cl_option *) p1)->opt_text, |
| 448 | ((struct cl_option *) p2)->opt_text); |
| 449 | } |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 450 | #endif |
| 451 | |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 452 | /* init initializes library global state. It might not need to |
| 453 | do anything depending on the platform and compiler. */ |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 454 | static void |
Neil Booth | 674c3b4 | 2001-01-08 18:52:09 +0000 | [diff] [blame] | 455 | init_library () |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 456 | { |
| 457 | static int initialized = 0; |
| 458 | |
| 459 | if (! initialized) |
| 460 | { |
| 461 | initialized = 1; |
| 462 | |
| 463 | #ifdef HOST_EBCDIC |
| 464 | /* For non-ASCII hosts, the cl_options array needs to be sorted at |
| 465 | runtime. */ |
| 466 | qsort (cl_options, N_OPTS, sizeof (struct cl_option), opt_comp); |
| 467 | #endif |
| 468 | |
| 469 | /* Set up the trigraph map. This doesn't need to do anything if |
| 470 | we were compiled with a compiler that supports C99 designated |
| 471 | initializers. */ |
| 472 | init_trigraph_map (); |
| 473 | } |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 474 | } |
| 475 | |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 476 | /* Initialize a cpp_reader structure. */ |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 477 | cpp_reader * |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 478 | cpp_create_reader (lang) |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 479 | enum c_lang lang; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 480 | { |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 481 | cpp_reader *pfile; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 482 | |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 483 | /* Initialise this instance of the library if it hasn't been already. */ |
Neil Booth | 674c3b4 | 2001-01-08 18:52:09 +0000 | [diff] [blame] | 484 | init_library (); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 485 | |
| 486 | pfile = (cpp_reader *) xcalloc (1, sizeof (cpp_reader)); |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 487 | |
Neil Booth | c740cee | 2001-02-20 22:52:11 +0000 | [diff] [blame] | 488 | set_lang (pfile, lang); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 489 | CPP_OPTION (pfile, warn_import) = 1; |
| 490 | CPP_OPTION (pfile, discard_comments) = 1; |
Jason Thorpe | 477cdac | 2002-04-07 03:12:23 +0000 | [diff] [blame] | 491 | CPP_OPTION (pfile, discard_comments_in_macro_exp) = 1; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 492 | CPP_OPTION (pfile, show_column) = 1; |
Neil Booth | 6ab3e7d | 2000-05-18 11:09:27 +0000 | [diff] [blame] | 493 | CPP_OPTION (pfile, tabstop) = 8; |
Jakub Jelinek | be76805 | 2000-12-15 16:49:28 +0100 | [diff] [blame] | 494 | CPP_OPTION (pfile, operator_names) = 1; |
Phil Edwards | 909de5d | 2002-03-22 21:59:04 +0000 | [diff] [blame] | 495 | CPP_OPTION (pfile, warn_endif_labels) = 1; |
Neil Booth | 0fef3fd | 2002-02-02 18:56:37 +0000 | [diff] [blame] | 496 | #if DEFAULT_SIGNED_CHAR |
| 497 | CPP_OPTION (pfile, signed_char) = 1; |
| 498 | #else |
| 499 | CPP_OPTION (pfile, signed_char) = 0; |
| 500 | #endif |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 501 | |
| 502 | CPP_OPTION (pfile, pending) = |
| 503 | (struct cpp_pending *) xcalloc (1, sizeof (struct cpp_pending)); |
| 504 | |
Neil Booth | f7114e1 | 2001-01-06 00:15:29 +0000 | [diff] [blame] | 505 | /* It's simplest to just create this struct whether or not it will |
| 506 | be needed. */ |
| 507 | pfile->deps = deps_init (); |
| 508 | |
Neil Booth | 5041042 | 2001-09-15 10:18:03 +0000 | [diff] [blame] | 509 | /* Initialise the line map. Start at logical line 1, so we can use |
| 510 | a line number of zero for special states. */ |
Neil Booth | d82fc10 | 2001-08-02 23:03:31 +0000 | [diff] [blame] | 511 | init_line_maps (&pfile->line_maps); |
Neil Booth | 5041042 | 2001-09-15 10:18:03 +0000 | [diff] [blame] | 512 | pfile->line = 1; |
Neil Booth | d82fc10 | 2001-08-02 23:03:31 +0000 | [diff] [blame] | 513 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 514 | /* Initialize lexer state. */ |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 515 | pfile->state.save_comments = ! CPP_OPTION (pfile, discard_comments); |
Zack Weinberg | 3cb553b | 2000-08-20 21:36:18 +0000 | [diff] [blame] | 516 | |
Neil Booth | 4ed5bcf | 2001-09-24 22:53:12 +0000 | [diff] [blame] | 517 | /* Set up static tokens. */ |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 518 | pfile->date.type = CPP_EOF; |
Neil Booth | 4ed5bcf | 2001-09-24 22:53:12 +0000 | [diff] [blame] | 519 | pfile->avoid_paste.type = CPP_PADDING; |
| 520 | pfile->avoid_paste.val.source = NULL; |
| 521 | pfile->eof.type = CPP_EOF; |
| 522 | pfile->eof.flags = 0; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 523 | |
Neil Booth | 5fddcff | 2001-09-11 07:00:12 +0000 | [diff] [blame] | 524 | /* Create a token buffer for the lexer. */ |
| 525 | _cpp_init_tokenrun (&pfile->base_run, 250); |
| 526 | pfile->cur_run = &pfile->base_run; |
| 527 | pfile->cur_token = pfile->base_run.base; |
Neil Booth | 5fddcff | 2001-09-11 07:00:12 +0000 | [diff] [blame] | 528 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 529 | /* Initialise the base context. */ |
| 530 | pfile->context = &pfile->base_context; |
| 531 | pfile->base_context.macro = 0; |
| 532 | pfile->base_context.prev = pfile->base_context.next = 0; |
| 533 | |
Neil Booth | 8c3b269 | 2001-09-30 10:03:11 +0000 | [diff] [blame] | 534 | /* Aligned and unaligned storage. */ |
| 535 | pfile->a_buff = _cpp_get_buff (pfile, 0); |
Neil Booth | ece54d5 | 2001-09-28 09:40:22 +0000 | [diff] [blame] | 536 | pfile->u_buff = _cpp_get_buff (pfile, 0); |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 537 | |
Neil Booth | 2a967f3 | 2001-05-20 06:26:45 +0000 | [diff] [blame] | 538 | /* Initialise the buffer obstack. */ |
| 539 | gcc_obstack_init (&pfile->buffer_ob); |
| 540 | |
Zack Weinberg | c71f835 | 2000-07-05 05:33:57 +0000 | [diff] [blame] | 541 | _cpp_init_includes (pfile); |
Neil Booth | cf44ea5 | 2000-11-28 21:13:35 +0000 | [diff] [blame] | 542 | |
| 543 | return pfile; |
Zack Weinberg | f2d5f0c | 2000-04-14 23:29:45 +0000 | [diff] [blame] | 544 | } |
| 545 | |
Neil Booth | 400023a | 2001-01-14 22:00:20 +0000 | [diff] [blame] | 546 | /* Free resources used by PFILE. Accessing PFILE after this function |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 547 | returns leads to undefined behaviour. Returns the error count. */ |
Neil Booth | 400023a | 2001-01-14 22:00:20 +0000 | [diff] [blame] | 548 | int |
| 549 | cpp_destroy (pfile) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 550 | cpp_reader *pfile; |
| 551 | { |
Neil Booth | 400023a | 2001-01-14 22:00:20 +0000 | [diff] [blame] | 552 | int result; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 553 | struct search_path *dir, *dirn; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 554 | cpp_context *context, *contextn; |
Neil Booth | 5041042 | 2001-09-15 10:18:03 +0000 | [diff] [blame] | 555 | tokenrun *run, *runn; |
Neil Booth | 709e9e5 | 2000-08-17 18:01:43 +0000 | [diff] [blame] | 556 | |
Zack Weinberg | 38b24ee | 2000-03-08 20:37:23 +0000 | [diff] [blame] | 557 | while (CPP_BUFFER (pfile) != NULL) |
Neil Booth | ef6e958 | 2001-08-04 12:01:59 +0000 | [diff] [blame] | 558 | _cpp_pop_buffer (pfile); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 559 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 560 | if (pfile->macro_buffer) |
Alexandre Oliva | 4b49c36 | 2001-01-09 09:30:43 +0000 | [diff] [blame] | 561 | { |
| 562 | free ((PTR) pfile->macro_buffer); |
| 563 | pfile->macro_buffer = NULL; |
| 564 | pfile->macro_buffer_len = 0; |
| 565 | } |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 566 | |
Neil Booth | f7114e1 | 2001-01-06 00:15:29 +0000 | [diff] [blame] | 567 | deps_free (pfile->deps); |
Neil Booth | 2a967f3 | 2001-05-20 06:26:45 +0000 | [diff] [blame] | 568 | obstack_free (&pfile->buffer_ob, 0); |
Zack Weinberg | 49e6c08 | 2000-03-04 19:42:04 +0000 | [diff] [blame] | 569 | |
Neil Booth | 2a967f3 | 2001-05-20 06:26:45 +0000 | [diff] [blame] | 570 | _cpp_destroy_hashtable (pfile); |
Zack Weinberg | bfb9dc7 | 2000-07-08 19:00:39 +0000 | [diff] [blame] | 571 | _cpp_cleanup_includes (pfile); |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 572 | |
Neil Booth | 8c3b269 | 2001-09-30 10:03:11 +0000 | [diff] [blame] | 573 | _cpp_free_buff (pfile->a_buff); |
Neil Booth | ece54d5 | 2001-09-28 09:40:22 +0000 | [diff] [blame] | 574 | _cpp_free_buff (pfile->u_buff); |
Neil Booth | b8af0ca | 2001-09-26 17:52:50 +0000 | [diff] [blame] | 575 | _cpp_free_buff (pfile->free_buffs); |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 576 | |
Neil Booth | 5041042 | 2001-09-15 10:18:03 +0000 | [diff] [blame] | 577 | for (run = &pfile->base_run; run; run = runn) |
| 578 | { |
| 579 | runn = run->next; |
| 580 | free (run->base); |
| 581 | if (run != &pfile->base_run) |
| 582 | free (run); |
| 583 | } |
| 584 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 585 | for (dir = CPP_OPTION (pfile, quote_include); dir; dir = dirn) |
Neil Booth | 709e9e5 | 2000-08-17 18:01:43 +0000 | [diff] [blame] | 586 | { |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 587 | dirn = dir->next; |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 588 | free ((PTR) dir->name); |
Neil Booth | 709e9e5 | 2000-08-17 18:01:43 +0000 | [diff] [blame] | 589 | free (dir); |
| 590 | } |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 591 | |
| 592 | for (context = pfile->base_context.next; context; context = contextn) |
| 593 | { |
| 594 | contextn = context->next; |
| 595 | free (context); |
| 596 | } |
Neil Booth | 400023a | 2001-01-14 22:00:20 +0000 | [diff] [blame] | 597 | |
Neil Booth | d82fc10 | 2001-08-02 23:03:31 +0000 | [diff] [blame] | 598 | free_line_maps (&pfile->line_maps); |
| 599 | |
Neil Booth | 400023a | 2001-01-14 22:00:20 +0000 | [diff] [blame] | 600 | result = pfile->errors; |
| 601 | free (pfile); |
| 602 | |
| 603 | return result; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 604 | } |
| 605 | |
| 606 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 607 | /* This structure defines one built-in identifier. A node will be |
| 608 | entered in the hash table under the name NAME, with value VALUE (if |
| 609 | any). If flags has OPERATOR, the node's operator field is used; if |
Neil Booth | 618cdda | 2001-02-25 09:43:03 +0000 | [diff] [blame] | 610 | flags has BUILTIN the node's builtin field is used. Macros that are |
| 611 | known at build time should not be flagged BUILTIN, as then they do |
| 612 | not appear in macro dumps with e.g. -dM or -dD. |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 613 | |
| 614 | Two values are not compile time constants, so we tag |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 615 | them in the FLAGS field instead: |
Zack Weinberg | 8c389f8 | 2000-04-10 03:27:21 +0000 | [diff] [blame] | 616 | VERS value is the global version_string, quoted |
| 617 | ULP value is the global user_label_prefix |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 618 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 619 | Also, macros with CPLUS set in the flags field are entered only for C++. */ |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 620 | struct builtin |
| 621 | { |
Neil Booth | 562a5c2 | 2002-04-21 18:46:42 +0000 | [diff] [blame^] | 622 | const uchar *name; |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 623 | const char *value; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 624 | unsigned char builtin; |
| 625 | unsigned char operator; |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 626 | unsigned short flags; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 627 | unsigned short len; |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 628 | }; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 629 | #define VERS 0x01 |
| 630 | #define ULP 0x02 |
| 631 | #define CPLUS 0x04 |
| 632 | #define BUILTIN 0x08 |
| 633 | #define OPERATOR 0x10 |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 634 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 635 | #define B(n, t) { U n, 0, t, 0, BUILTIN, sizeof n - 1 } |
| 636 | #define C(n, v) { U n, v, 0, 0, 0, sizeof n - 1 } |
| 637 | #define X(n, f) { U n, 0, 0, 0, f, sizeof n - 1 } |
| 638 | #define O(n, c, f) { U n, 0, 0, c, OPERATOR | f, sizeof n - 1 } |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 639 | static const struct builtin builtin_array[] = |
| 640 | { |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 641 | B("__TIME__", BT_TIME), |
| 642 | B("__DATE__", BT_DATE), |
| 643 | B("__FILE__", BT_FILE), |
| 644 | B("__BASE_FILE__", BT_BASE_FILE), |
| 645 | B("__LINE__", BT_SPECLINE), |
| 646 | B("__INCLUDE_LEVEL__", BT_INCLUDE_LEVEL), |
Neil Booth | 644edda | 2001-10-02 12:57:24 +0000 | [diff] [blame] | 647 | B("_Pragma", BT_PRAGMA), |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 648 | |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 649 | X("__VERSION__", VERS), |
| 650 | X("__USER_LABEL_PREFIX__", ULP), |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 651 | C("__REGISTER_PREFIX__", REGISTER_PREFIX), |
| 652 | C("__HAVE_BUILTIN_SETJMP__", "1"), |
Zack Weinberg | 0d24f4d | 2002-01-08 19:03:20 +0000 | [diff] [blame] | 653 | #if USING_SJLJ_EXCEPTIONS |
| 654 | /* libgcc needs to know this. */ |
| 655 | C("__USING_SJLJ_EXCEPTIONS__","1"), |
| 656 | #endif |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 657 | #ifndef NO_BUILTIN_SIZE_TYPE |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 658 | C("__SIZE_TYPE__", SIZE_TYPE), |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 659 | #endif |
| 660 | #ifndef NO_BUILTIN_PTRDIFF_TYPE |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 661 | C("__PTRDIFF_TYPE__", PTRDIFF_TYPE), |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 662 | #endif |
Zack Weinberg | 0209c34 | 2000-02-28 21:09:54 +0000 | [diff] [blame] | 663 | #ifndef NO_BUILTIN_WCHAR_TYPE |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 664 | C("__WCHAR_TYPE__", WCHAR_TYPE), |
Zack Weinberg | 0209c34 | 2000-02-28 21:09:54 +0000 | [diff] [blame] | 665 | #endif |
Joseph Myers | d677797 | 2000-08-04 13:45:57 +0100 | [diff] [blame] | 666 | #ifndef NO_BUILTIN_WINT_TYPE |
| 667 | C("__WINT_TYPE__", WINT_TYPE), |
| 668 | #endif |
Neil Booth | 618cdda | 2001-02-25 09:43:03 +0000 | [diff] [blame] | 669 | #ifdef STDC_0_IN_SYSTEM_HEADERS |
| 670 | B("__STDC__", BT_STDC), |
| 671 | #else |
| 672 | C("__STDC__", "1"), |
| 673 | #endif |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 674 | |
| 675 | /* Named operators known to the preprocessor. These cannot be #defined |
| 676 | and always have their stated meaning. They are treated like normal |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 677 | identifiers except for the type code and the meaning. Most of them |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 678 | are only for C++ (but see iso646.h). */ |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 679 | O("and", CPP_AND_AND, CPLUS), |
| 680 | O("and_eq", CPP_AND_EQ, CPLUS), |
| 681 | O("bitand", CPP_AND, CPLUS), |
| 682 | O("bitor", CPP_OR, CPLUS), |
| 683 | O("compl", CPP_COMPL, CPLUS), |
| 684 | O("not", CPP_NOT, CPLUS), |
| 685 | O("not_eq", CPP_NOT_EQ, CPLUS), |
| 686 | O("or", CPP_OR_OR, CPLUS), |
| 687 | O("or_eq", CPP_OR_EQ, CPLUS), |
| 688 | O("xor", CPP_XOR, CPLUS), |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 689 | O("xor_eq", CPP_XOR_EQ, CPLUS) |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 690 | }; |
Zack Weinberg | 12cf91f | 2000-05-04 04:38:01 +0000 | [diff] [blame] | 691 | #undef B |
| 692 | #undef C |
| 693 | #undef X |
Jakub Jelinek | be76805 | 2000-12-15 16:49:28 +0100 | [diff] [blame] | 694 | #undef O |
Kaveh R. Ghazi | ca7558f | 2002-03-03 14:07:39 +0000 | [diff] [blame] | 695 | #define builtin_array_end (builtin_array + ARRAY_SIZE (builtin_array)) |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 696 | |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 697 | /* Subroutine of cpp_read_main_file; reads the builtins table above and |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 698 | enters them, and language-specific macros, into the hash table. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 699 | static void |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 700 | init_builtins (pfile) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 701 | cpp_reader *pfile; |
| 702 | { |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 703 | const struct builtin *b; |
Neil Booth | 771c4df | 2000-09-07 20:31:06 +0000 | [diff] [blame] | 704 | |
Zack Weinberg | 8c389f8 | 2000-04-10 03:27:21 +0000 | [diff] [blame] | 705 | for(b = builtin_array; b < builtin_array_end; b++) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 706 | { |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 707 | if ((b->flags & CPLUS) && ! CPP_OPTION (pfile, cplusplus)) |
Zack Weinberg | 92936ec | 2000-07-19 20:18:08 +0000 | [diff] [blame] | 708 | continue; |
| 709 | |
Jakub Jelinek | be76805 | 2000-12-15 16:49:28 +0100 | [diff] [blame] | 710 | if ((b->flags & OPERATOR) && ! CPP_OPTION (pfile, operator_names)) |
| 711 | continue; |
| 712 | |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 713 | if (b->flags & (OPERATOR | BUILTIN)) |
| 714 | { |
| 715 | cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len); |
| 716 | if (b->flags & OPERATOR) |
| 717 | { |
| 718 | hp->flags |= NODE_OPERATOR; |
| 719 | hp->value.operator = b->operator; |
| 720 | } |
| 721 | else |
| 722 | { |
| 723 | hp->type = NT_MACRO; |
Neil Booth | 618cdda | 2001-02-25 09:43:03 +0000 | [diff] [blame] | 724 | hp->flags |= NODE_BUILTIN | NODE_WARN; |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 725 | hp->value.builtin = b->builtin; |
| 726 | } |
| 727 | } |
| 728 | else /* A standard macro of some kind. */ |
Zack Weinberg | 8c389f8 | 2000-04-10 03:27:21 +0000 | [diff] [blame] | 729 | { |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 730 | const char *val; |
| 731 | char *str; |
| 732 | |
| 733 | if (b->flags & VERS) |
| 734 | { |
Zack Weinberg | 2c8f051 | 2000-08-29 18:37:37 +0000 | [diff] [blame] | 735 | /* Allocate enough space for 'name "value"\n\0'. */ |
| 736 | str = alloca (b->len + strlen (version_string) + 5); |
| 737 | sprintf (str, "%s \"%s\"\n", b->name, version_string); |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 738 | } |
| 739 | else |
| 740 | { |
| 741 | if (b->flags & ULP) |
Neil Booth | 771c4df | 2000-09-07 20:31:06 +0000 | [diff] [blame] | 742 | val = CPP_OPTION (pfile, user_label_prefix); |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 743 | else |
| 744 | val = b->value; |
| 745 | |
Zack Weinberg | 2c8f051 | 2000-08-29 18:37:37 +0000 | [diff] [blame] | 746 | /* Allocate enough space for "name value\n\0". */ |
| 747 | str = alloca (b->len + strlen (val) + 3); |
| 748 | sprintf(str, "%s %s\n", b->name, val); |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 749 | } |
Neil Booth | c154ba6 | 2000-08-17 17:52:48 +0000 | [diff] [blame] | 750 | |
Zack Weinberg | 2c8f051 | 2000-08-29 18:37:37 +0000 | [diff] [blame] | 751 | _cpp_define_builtin (pfile, str); |
Zack Weinberg | 8c389f8 | 2000-04-10 03:27:21 +0000 | [diff] [blame] | 752 | } |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 753 | } |
Neil Booth | c740cee | 2001-02-20 22:52:11 +0000 | [diff] [blame] | 754 | |
| 755 | if (CPP_OPTION (pfile, cplusplus)) |
Neil Booth | 618cdda | 2001-02-25 09:43:03 +0000 | [diff] [blame] | 756 | { |
| 757 | _cpp_define_builtin (pfile, "__cplusplus 1"); |
| 758 | if (SUPPORTS_ONE_ONLY) |
| 759 | _cpp_define_builtin (pfile, "__GXX_WEAK__ 1"); |
| 760 | else |
| 761 | _cpp_define_builtin (pfile, "__GXX_WEAK__ 0"); |
| 762 | } |
Neil Booth | c740cee | 2001-02-20 22:52:11 +0000 | [diff] [blame] | 763 | if (CPP_OPTION (pfile, objc)) |
| 764 | _cpp_define_builtin (pfile, "__OBJC__ 1"); |
| 765 | |
| 766 | if (CPP_OPTION (pfile, lang) == CLK_STDC94) |
| 767 | _cpp_define_builtin (pfile, "__STDC_VERSION__ 199409L"); |
| 768 | else if (CPP_OPTION (pfile, c99)) |
| 769 | _cpp_define_builtin (pfile, "__STDC_VERSION__ 199901L"); |
| 770 | |
Neil Booth | 0fef3fd | 2002-02-02 18:56:37 +0000 | [diff] [blame] | 771 | if (CPP_OPTION (pfile, signed_char) == 0) |
| 772 | _cpp_define_builtin (pfile, "__CHAR_UNSIGNED__ 1"); |
| 773 | |
Neil Booth | c740cee | 2001-02-20 22:52:11 +0000 | [diff] [blame] | 774 | if (CPP_OPTION (pfile, lang) == CLK_STDC89 |
| 775 | || CPP_OPTION (pfile, lang) == CLK_STDC94 |
| 776 | || CPP_OPTION (pfile, lang) == CLK_STDC99) |
| 777 | _cpp_define_builtin (pfile, "__STRICT_ANSI__ 1"); |
| 778 | else if (CPP_OPTION (pfile, lang) == CLK_ASM) |
| 779 | _cpp_define_builtin (pfile, "__ASSEMBLER__ 1"); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 780 | } |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 781 | #undef BUILTIN |
| 782 | #undef OPERATOR |
Zack Weinberg | 6feb772 | 2000-03-13 00:10:13 +0000 | [diff] [blame] | 783 | #undef VERS |
Zack Weinberg | a9ae448 | 1999-10-29 04:31:14 +0000 | [diff] [blame] | 784 | #undef ULP |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 785 | #undef CPLUS |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 786 | #undef builtin_array_end |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 787 | |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 788 | /* And another subroutine. This one sets up the standard include path. */ |
| 789 | static void |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 790 | init_standard_includes (pfile) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 791 | cpp_reader *pfile; |
| 792 | { |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 793 | char *path; |
Zack Weinberg | 455d258 | 2000-03-04 01:42:56 +0000 | [diff] [blame] | 794 | const struct default_include *p; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 795 | const char *specd_prefix = CPP_OPTION (pfile, include_prefix); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 796 | |
| 797 | /* Several environment variables may add to the include search path. |
| 798 | CPATH specifies an additional list of directories to be searched |
| 799 | as if specified with -I, while C_INCLUDE_PATH, CPLUS_INCLUDE_PATH, |
| 800 | etc. specify an additional list of directories to be searched as |
| 801 | if specified with -isystem, for the language indicated. */ |
| 802 | |
| 803 | GET_ENV_PATH_LIST (path, "CPATH"); |
| 804 | if (path != 0 && *path != 0) |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 805 | path_include (pfile, path, BRACKET); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 806 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 807 | switch ((CPP_OPTION (pfile, objc) << 1) + CPP_OPTION (pfile, cplusplus)) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 808 | { |
| 809 | case 0: |
| 810 | GET_ENV_PATH_LIST (path, "C_INCLUDE_PATH"); |
| 811 | break; |
| 812 | case 1: |
| 813 | GET_ENV_PATH_LIST (path, "CPLUS_INCLUDE_PATH"); |
| 814 | break; |
| 815 | case 2: |
| 816 | GET_ENV_PATH_LIST (path, "OBJC_INCLUDE_PATH"); |
| 817 | break; |
| 818 | case 3: |
| 819 | GET_ENV_PATH_LIST (path, "OBJCPLUS_INCLUDE_PATH"); |
| 820 | break; |
| 821 | } |
| 822 | if (path != 0 && *path != 0) |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 823 | path_include (pfile, path, SYSTEM); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 824 | |
| 825 | /* Search "translated" versions of GNU directories. |
| 826 | These have /usr/local/lib/gcc... replaced by specd_prefix. */ |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 827 | if (specd_prefix != 0 && cpp_GCC_INCLUDE_DIR_len) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 828 | { |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 829 | /* Remove the `include' from /usr/local/lib/gcc.../include. |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 830 | GCC_INCLUDE_DIR will always end in /include. */ |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 831 | int default_len = cpp_GCC_INCLUDE_DIR_len; |
| 832 | char *default_prefix = (char *) alloca (default_len + 1); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 833 | int specd_len = strlen (specd_prefix); |
| 834 | |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 835 | memcpy (default_prefix, cpp_GCC_INCLUDE_DIR, default_len); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 836 | default_prefix[default_len] = '\0'; |
| 837 | |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 838 | for (p = cpp_include_defaults; p->fname; p++) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 839 | { |
| 840 | /* Some standard dirs are only for C++. */ |
| 841 | if (!p->cplusplus |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 842 | || (CPP_OPTION (pfile, cplusplus) |
| 843 | && !CPP_OPTION (pfile, no_standard_cplusplus_includes))) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 844 | { |
| 845 | /* Does this dir start with the prefix? */ |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 846 | if (!memcmp (p->fname, default_prefix, default_len)) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 847 | { |
| 848 | /* Yes; change prefix and add to search list. */ |
| 849 | int flen = strlen (p->fname); |
| 850 | int this_len = specd_len + flen - default_len; |
| 851 | char *str = (char *) xmalloc (this_len + 1); |
| 852 | memcpy (str, specd_prefix, specd_len); |
| 853 | memcpy (str + specd_len, |
| 854 | p->fname + default_len, |
| 855 | flen - default_len + 1); |
| 856 | |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 857 | append_include_chain (pfile, str, SYSTEM, p->cxx_aware); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 858 | } |
| 859 | } |
| 860 | } |
| 861 | } |
| 862 | |
| 863 | /* Search ordinary names for GNU include directories. */ |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 864 | for (p = cpp_include_defaults; p->fname; p++) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 865 | { |
| 866 | /* Some standard dirs are only for C++. */ |
| 867 | if (!p->cplusplus |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 868 | || (CPP_OPTION (pfile, cplusplus) |
| 869 | && !CPP_OPTION (pfile, no_standard_cplusplus_includes))) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 870 | { |
Neil Booth | 51c0425 | 2001-08-20 06:14:53 +0000 | [diff] [blame] | 871 | char *str = update_path (p->fname, p->component); |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 872 | append_include_chain (pfile, str, SYSTEM, p->cxx_aware); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 873 | } |
| 874 | } |
| 875 | } |
| 876 | |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 877 | /* Pushes a command line -imacro and -include file indicated by P onto |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 878 | the buffer stack. Returns non-zero if successful. */ |
| 879 | static bool |
| 880 | push_include (pfile, p) |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 881 | cpp_reader *pfile; |
| 882 | struct pending_option *p; |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 883 | { |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 884 | cpp_token header; |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 885 | |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 886 | /* Later: maybe update this to use the #include "" search path |
| 887 | if cpp_read_file fails. */ |
| 888 | header.type = CPP_STRING; |
| 889 | header.val.str.text = (const unsigned char *) p->arg; |
| 890 | header.val.str.len = strlen (p->arg); |
| 891 | /* Make the command line directive take up a line. */ |
Neil Booth | 5041042 | 2001-09-15 10:18:03 +0000 | [diff] [blame] | 892 | pfile->line++; |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 893 | |
| 894 | return _cpp_execute_include (pfile, &header, IT_CMDLINE); |
| 895 | } |
| 896 | |
| 897 | /* Frees a pending_option chain. */ |
| 898 | static void |
| 899 | free_chain (head) |
| 900 | struct pending_option *head; |
| 901 | { |
| 902 | struct pending_option *next; |
| 903 | |
| 904 | while (head) |
| 905 | { |
| 906 | next = head->next; |
| 907 | free (head); |
| 908 | head = next; |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 909 | } |
| 910 | } |
| 911 | |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 912 | /* This is called after options have been parsed, and partially |
| 913 | processed. Setup for processing input from the file named FNAME, |
| 914 | or stdin if it is the empty string. Return the original filename |
| 915 | on success (e.g. foo.i->foo.c), or NULL on failure. */ |
| 916 | const char * |
| 917 | cpp_read_main_file (pfile, fname, table) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 918 | cpp_reader *pfile; |
Neil Booth | 7ceb359 | 2000-03-11 00:49:44 +0000 | [diff] [blame] | 919 | const char *fname; |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 920 | hash_table *table; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 921 | { |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 922 | /* The front ends don't set up the hash table until they have |
| 923 | finished processing the command line options, so initializing the |
| 924 | hashtable is deferred until now. */ |
| 925 | _cpp_init_hashtable (pfile, table); |
| 926 | |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 927 | /* Set up the include search path now. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 928 | if (! CPP_OPTION (pfile, no_standard_includes)) |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 929 | init_standard_includes (pfile); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 930 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 931 | merge_include_chains (pfile); |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 932 | |
| 933 | /* With -v, print the list of dirs to search. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 934 | if (CPP_OPTION (pfile, verbose)) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 935 | { |
Neil Booth | 591e15a | 2001-03-02 07:35:12 +0000 | [diff] [blame] | 936 | struct search_path *l; |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 937 | fprintf (stderr, _("#include \"...\" search starts here:\n")); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 938 | for (l = CPP_OPTION (pfile, quote_include); l; l = l->next) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 939 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 940 | if (l == CPP_OPTION (pfile, bracket_include)) |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 941 | fprintf (stderr, _("#include <...> search starts here:\n")); |
| 942 | fprintf (stderr, " %s\n", l->name); |
| 943 | } |
| 944 | fprintf (stderr, _("End of search list.\n")); |
| 945 | } |
| 946 | |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 947 | if (CPP_OPTION (pfile, print_deps)) |
Jakub Jelinek | 7855db7 | 2001-01-24 19:44:40 +0100 | [diff] [blame] | 948 | /* Set the default target (if there is none already). */ |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 949 | deps_add_default_target (pfile->deps, fname); |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 950 | |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 951 | /* Open the main input file. */ |
Neil Booth | 614c7d3 | 2000-12-04 07:32:04 +0000 | [diff] [blame] | 952 | if (!_cpp_read_file (pfile, fname)) |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 953 | return NULL; |
Zack Weinberg | c45da1c | 2000-03-02 20:14:32 +0000 | [diff] [blame] | 954 | |
Neil Booth | 5993019 | 2001-08-21 21:17:48 +0000 | [diff] [blame] | 955 | /* Set this after cpp_post_options so the client can change the |
| 956 | option if it wishes, and after stacking the main file so we don't |
| 957 | trace the main file. */ |
| 958 | pfile->line_maps.trace_includes = CPP_OPTION (pfile, print_include_names); |
| 959 | |
Neil Booth | f5e9945 | 2001-11-15 10:01:10 +0000 | [diff] [blame] | 960 | /* For foo.i, read the original filename foo.c now, for the benefit |
| 961 | of the front ends. */ |
| 962 | if (CPP_OPTION (pfile, preprocessed)) |
| 963 | read_original_filename (pfile); |
| 964 | |
| 965 | return pfile->map->to_file; |
| 966 | } |
| 967 | |
| 968 | /* For preprocessed files, if the first tokens are of the form # NUM. |
| 969 | handle the directive so we know the original file name. This will |
| 970 | generate file_change callbacks, which the front ends must handle |
| 971 | appropriately given their state of initialization. */ |
| 972 | static void |
| 973 | read_original_filename (pfile) |
| 974 | cpp_reader *pfile; |
| 975 | { |
| 976 | const cpp_token *token, *token1; |
| 977 | |
| 978 | /* Lex ahead; if the first tokens are of the form # NUM, then |
| 979 | process the directive, otherwise back up. */ |
| 980 | token = _cpp_lex_direct (pfile); |
| 981 | if (token->type == CPP_HASH) |
| 982 | { |
| 983 | token1 = _cpp_lex_direct (pfile); |
| 984 | _cpp_backup_tokens (pfile, 1); |
| 985 | |
| 986 | /* If it's a #line directive, handle it. */ |
| 987 | if (token1->type == CPP_NUMBER) |
| 988 | { |
| 989 | _cpp_handle_directive (pfile, token->flags & PREV_WHITE); |
| 990 | return; |
| 991 | } |
| 992 | } |
| 993 | |
| 994 | /* Backup as if nothing happened. */ |
| 995 | _cpp_backup_tokens (pfile, 1); |
| 996 | } |
| 997 | |
| 998 | /* Handle pending command line options: -D, -U, -A, -imacros and |
| 999 | -include. This should be called after debugging has been properly |
| 1000 | set up in the front ends. */ |
| 1001 | void |
| 1002 | cpp_finish_options (pfile) |
| 1003 | cpp_reader *pfile; |
| 1004 | { |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1005 | /* Install builtins and process command line macros etc. in the order |
| 1006 | they appeared, but only if not already preprocessed. */ |
Neil Booth | 05e8172 | 2001-01-11 21:30:16 +0000 | [diff] [blame] | 1007 | if (! CPP_OPTION (pfile, preprocessed)) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1008 | { |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1009 | struct pending_option *p; |
| 1010 | |
Joseph Myers | b0287a9 | 2001-12-15 20:31:07 +0000 | [diff] [blame] | 1011 | _cpp_do_file_change (pfile, LC_RENAME, _("<built-in>"), 1, 0); |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1012 | init_builtins (pfile); |
| 1013 | _cpp_do_file_change (pfile, LC_RENAME, _("<command line>"), 1, 0); |
| 1014 | for (p = CPP_OPTION (pfile, pending)->directive_head; p; p = p->next) |
Neil Booth | 05e8172 | 2001-01-11 21:30:16 +0000 | [diff] [blame] | 1015 | (*p->handler) (pfile, p->arg); |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1016 | |
| 1017 | /* Scan -imacros files after command line defines, but before |
| 1018 | files given with -include. */ |
Neil Booth | 53aabfb | 2001-09-01 10:22:17 +0000 | [diff] [blame] | 1019 | while ((p = CPP_OPTION (pfile, pending)->imacros_head) != NULL) |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1020 | { |
| 1021 | if (push_include (pfile, p)) |
| 1022 | { |
| 1023 | pfile->buffer->return_at_eof = true; |
| 1024 | cpp_scan_nooutput (pfile); |
| 1025 | } |
Neil Booth | 53aabfb | 2001-09-01 10:22:17 +0000 | [diff] [blame] | 1026 | CPP_OPTION (pfile, pending)->imacros_head = p->next; |
| 1027 | free (p); |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1028 | } |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1029 | } |
Neil Booth | 05e8172 | 2001-01-11 21:30:16 +0000 | [diff] [blame] | 1030 | |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1031 | free_chain (CPP_OPTION (pfile, pending)->directive_head); |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1032 | _cpp_push_next_buffer (pfile); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1033 | } |
| 1034 | |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1035 | /* Called to push the next buffer on the stack given by -include. If |
| 1036 | there are none, free the pending structure and restore the line map |
| 1037 | for the main file. */ |
| 1038 | bool |
| 1039 | _cpp_push_next_buffer (pfile) |
| 1040 | cpp_reader *pfile; |
| 1041 | { |
| 1042 | bool pushed = false; |
| 1043 | |
Neil Booth | 53aabfb | 2001-09-01 10:22:17 +0000 | [diff] [blame] | 1044 | /* This is't pretty; we'd rather not be relying on this as a boolean |
| 1045 | for reverting the line map. Further, we only free the chains in |
| 1046 | this conditional, so an early call to cpp_finish / cpp_destroy |
| 1047 | will leak that memory. */ |
| 1048 | if (CPP_OPTION (pfile, pending) |
| 1049 | && CPP_OPTION (pfile, pending)->imacros_head == NULL) |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1050 | { |
| 1051 | while (!pushed) |
| 1052 | { |
| 1053 | struct pending_option *p = CPP_OPTION (pfile, pending)->include_head; |
| 1054 | |
| 1055 | if (p == NULL) |
| 1056 | break; |
| 1057 | if (! CPP_OPTION (pfile, preprocessed)) |
| 1058 | pushed = push_include (pfile, p); |
| 1059 | CPP_OPTION (pfile, pending)->include_head = p->next; |
| 1060 | free (p); |
| 1061 | } |
| 1062 | |
| 1063 | if (!pushed) |
| 1064 | { |
| 1065 | free (CPP_OPTION (pfile, pending)); |
| 1066 | CPP_OPTION (pfile, pending) = NULL; |
| 1067 | |
| 1068 | /* Restore the line map for the main file. */ |
| 1069 | if (! CPP_OPTION (pfile, preprocessed)) |
| 1070 | _cpp_do_file_change (pfile, LC_RENAME, |
| 1071 | pfile->line_maps.maps[0].to_file, 1, 0); |
| 1072 | } |
| 1073 | } |
| 1074 | |
| 1075 | return pushed; |
| 1076 | } |
| 1077 | |
Neil Booth | 2f638f9 | 2001-01-10 23:28:00 +0000 | [diff] [blame] | 1078 | /* Use mkdeps.c to output dependency information. */ |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1079 | static void |
| 1080 | output_deps (pfile) |
| 1081 | cpp_reader *pfile; |
| 1082 | { |
| 1083 | /* Stream on which to print the dependency information. */ |
| 1084 | FILE *deps_stream = 0; |
Kaveh R. Ghazi | 27c38fb | 2001-09-12 17:18:03 +0000 | [diff] [blame] | 1085 | const char *const deps_mode = |
| 1086 | CPP_OPTION (pfile, print_deps_append) ? "a" : "w"; |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1087 | |
Neil Booth | 56cd5b9 | 2002-02-20 07:24:10 +0000 | [diff] [blame] | 1088 | if (CPP_OPTION (pfile, deps_file)[0] == '\0') |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1089 | deps_stream = stdout; |
| 1090 | else |
| 1091 | { |
| 1092 | deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode); |
| 1093 | if (deps_stream == 0) |
| 1094 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1095 | cpp_errno (pfile, DL_ERROR, CPP_OPTION (pfile, deps_file)); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1096 | return; |
| 1097 | } |
| 1098 | } |
| 1099 | |
| 1100 | deps_write (pfile->deps, deps_stream, 72); |
| 1101 | |
| 1102 | if (CPP_OPTION (pfile, deps_phony_targets)) |
| 1103 | deps_phony_targets (pfile->deps, deps_stream); |
| 1104 | |
| 1105 | /* Don't close stdout. */ |
Neil Booth | ab8e222 | 2002-02-23 13:42:40 +0000 | [diff] [blame] | 1106 | if (deps_stream != stdout) |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1107 | { |
| 1108 | if (ferror (deps_stream) || fclose (deps_stream) != 0) |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1109 | cpp_error (pfile, DL_FATAL, "I/O error on output"); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1110 | } |
| 1111 | } |
| 1112 | |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1113 | /* This is called at the end of preprocessing. It pops the |
| 1114 | last buffer and writes dependency output. It should also |
| 1115 | clear macro definitions, such that you could call cpp_start_read |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1116 | with a new filename to restart processing. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1117 | void |
Neil Booth | 93c80368 | 2000-10-28 17:59:06 +0000 | [diff] [blame] | 1118 | cpp_finish (pfile) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1119 | cpp_reader *pfile; |
| 1120 | { |
Neil Booth | 7364fdd | 2001-08-07 20:37:26 +0000 | [diff] [blame] | 1121 | /* cpplex.c leaves the final buffer on the stack. This it so that |
| 1122 | it returns an unending stream of CPP_EOFs to the client. If we |
Joseph Myers | a1f300c | 2001-11-23 02:05:19 +0000 | [diff] [blame] | 1123 | popped the buffer, we'd dereference a NULL buffer pointer and |
Neil Booth | 7364fdd | 2001-08-07 20:37:26 +0000 | [diff] [blame] | 1124 | segfault. It's nice to allow the client to do worry-free excess |
| 1125 | cpp_get_token calls. */ |
| 1126 | while (pfile->buffer) |
| 1127 | _cpp_pop_buffer (pfile); |
Zack Weinberg | c1212d2 | 2000-02-06 23:46:18 +0000 | [diff] [blame] | 1128 | |
Zack Weinberg | 49e6c08 | 2000-03-04 19:42:04 +0000 | [diff] [blame] | 1129 | /* Don't write the deps file if preprocessing has failed. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1130 | if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0) |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1131 | output_deps (pfile); |
Zack Weinberg | 3caee4a | 1999-04-26 16:41:02 +0000 | [diff] [blame] | 1132 | |
Zack Weinberg | d450696 | 2000-06-28 19:03:08 +0000 | [diff] [blame] | 1133 | /* Report on headers that could use multiple include guards. */ |
| 1134 | if (CPP_OPTION (pfile, print_include_names)) |
Zack Weinberg | c71f835 | 2000-07-05 05:33:57 +0000 | [diff] [blame] | 1135 | _cpp_report_missing_guards (pfile); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1136 | } |
| 1137 | |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 1138 | /* Add a directive to be handled later in the initialization phase. */ |
Richard Henderson | 223dca6 | 1999-12-14 08:05:23 -0800 | [diff] [blame] | 1139 | static void |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1140 | new_pending_directive (pend, text, handler) |
| 1141 | struct cpp_pending *pend; |
Richard Henderson | 223dca6 | 1999-12-14 08:05:23 -0800 | [diff] [blame] | 1142 | const char *text; |
Neil Booth | 40eac64 | 2000-03-11 09:13:00 +0000 | [diff] [blame] | 1143 | cl_directive_handler handler; |
Richard Henderson | 223dca6 | 1999-12-14 08:05:23 -0800 | [diff] [blame] | 1144 | { |
| 1145 | struct pending_option *o = (struct pending_option *) |
| 1146 | xmalloc (sizeof (struct pending_option)); |
| 1147 | |
Neil Booth | 7ceb359 | 2000-03-11 00:49:44 +0000 | [diff] [blame] | 1148 | o->arg = text; |
Richard Henderson | 223dca6 | 1999-12-14 08:05:23 -0800 | [diff] [blame] | 1149 | o->next = NULL; |
Neil Booth | 40eac64 | 2000-03-11 09:13:00 +0000 | [diff] [blame] | 1150 | o->handler = handler; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1151 | APPEND (pend, directive, o); |
Richard Henderson | 223dca6 | 1999-12-14 08:05:23 -0800 | [diff] [blame] | 1152 | } |
| 1153 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1154 | /* Irix6 "cc -n32" and OSF4 cc have problems with char foo[] = ("string"); |
| 1155 | I.e. a const string initializer with parens around it. That is |
| 1156 | what N_("string") resolves to, so we make no_* be macros instead. */ |
Neil Booth | c725bd7 | 2001-12-03 19:15:19 +0000 | [diff] [blame] | 1157 | #define no_arg N_("argument missing after %s") |
| 1158 | #define no_ass N_("assertion missing after %s") |
| 1159 | #define no_dir N_("directory name missing after %s") |
| 1160 | #define no_fil N_("file name missing after %s") |
| 1161 | #define no_mac N_("macro name missing after %s") |
| 1162 | #define no_pth N_("path name missing after %s") |
| 1163 | #define no_num N_("number missing after %s") |
| 1164 | #define no_tgt N_("target missing after %s") |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1165 | |
| 1166 | /* This is the list of all command line options, with the leading |
| 1167 | "-" removed. It must be sorted in ASCII collating order. */ |
| 1168 | #define COMMAND_LINE_OPTIONS \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1169 | DEF_OPT("$", 0, OPT_dollar) \ |
| 1170 | DEF_OPT("+", 0, OPT_plus) \ |
| 1171 | DEF_OPT("-help", 0, OPT__help) \ |
Chandra Chavva | 91606ce | 2000-11-14 12:06:06 -0500 | [diff] [blame] | 1172 | DEF_OPT("-target-help", 0, OPT_target__help) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1173 | DEF_OPT("-version", 0, OPT__version) \ |
| 1174 | DEF_OPT("A", no_ass, OPT_A) \ |
| 1175 | DEF_OPT("C", 0, OPT_C) \ |
Jason Thorpe | 477cdac | 2002-04-07 03:12:23 +0000 | [diff] [blame] | 1176 | DEF_OPT("CC", 0, OPT_CC) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1177 | DEF_OPT("D", no_mac, OPT_D) \ |
| 1178 | DEF_OPT("H", 0, OPT_H) \ |
| 1179 | DEF_OPT("I", no_dir, OPT_I) \ |
| 1180 | DEF_OPT("M", 0, OPT_M) \ |
Neil Booth | b3124fa | 2002-03-16 14:03:36 +0000 | [diff] [blame] | 1181 | DEF_OPT("MD", no_fil, OPT_MD) \ |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1182 | DEF_OPT("MF", no_fil, OPT_MF) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1183 | DEF_OPT("MG", 0, OPT_MG) \ |
| 1184 | DEF_OPT("MM", 0, OPT_MM) \ |
Neil Booth | b3124fa | 2002-03-16 14:03:36 +0000 | [diff] [blame] | 1185 | DEF_OPT("MMD", no_fil, OPT_MMD) \ |
Neil Booth | a5a4ce3 | 2001-01-05 07:50:24 +0000 | [diff] [blame] | 1186 | DEF_OPT("MP", 0, OPT_MP) \ |
Neil Booth | f7114e1 | 2001-01-06 00:15:29 +0000 | [diff] [blame] | 1187 | DEF_OPT("MQ", no_tgt, OPT_MQ) \ |
Neil Booth | 03b9ab4 | 2001-01-04 10:25:55 +0000 | [diff] [blame] | 1188 | DEF_OPT("MT", no_tgt, OPT_MT) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1189 | DEF_OPT("P", 0, OPT_P) \ |
| 1190 | DEF_OPT("U", no_mac, OPT_U) \ |
| 1191 | DEF_OPT("W", no_arg, OPT_W) /* arg optional */ \ |
| 1192 | DEF_OPT("d", no_arg, OPT_d) \ |
| 1193 | DEF_OPT("fleading-underscore", 0, OPT_fleading_underscore) \ |
| 1194 | DEF_OPT("fno-leading-underscore", 0, OPT_fno_leading_underscore) \ |
Jakub Jelinek | be76805 | 2000-12-15 16:49:28 +0100 | [diff] [blame] | 1195 | DEF_OPT("fno-operator-names", 0, OPT_fno_operator_names) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1196 | DEF_OPT("fno-preprocessed", 0, OPT_fno_preprocessed) \ |
| 1197 | DEF_OPT("fno-show-column", 0, OPT_fno_show_column) \ |
| 1198 | DEF_OPT("fpreprocessed", 0, OPT_fpreprocessed) \ |
| 1199 | DEF_OPT("fshow-column", 0, OPT_fshow_column) \ |
Neil Booth | 0fef3fd | 2002-02-02 18:56:37 +0000 | [diff] [blame] | 1200 | DEF_OPT("fsigned-char", 0, OPT_fsigned_char) \ |
Neil Booth | 6ab3e7d | 2000-05-18 11:09:27 +0000 | [diff] [blame] | 1201 | DEF_OPT("ftabstop=", no_num, OPT_ftabstop) \ |
Neil Booth | 0fef3fd | 2002-02-02 18:56:37 +0000 | [diff] [blame] | 1202 | DEF_OPT("funsigned-char", 0, OPT_funsigned_char) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1203 | DEF_OPT("h", 0, OPT_h) \ |
| 1204 | DEF_OPT("idirafter", no_dir, OPT_idirafter) \ |
| 1205 | DEF_OPT("imacros", no_fil, OPT_imacros) \ |
| 1206 | DEF_OPT("include", no_fil, OPT_include) \ |
| 1207 | DEF_OPT("iprefix", no_pth, OPT_iprefix) \ |
| 1208 | DEF_OPT("isystem", no_dir, OPT_isystem) \ |
| 1209 | DEF_OPT("iwithprefix", no_dir, OPT_iwithprefix) \ |
| 1210 | DEF_OPT("iwithprefixbefore", no_dir, OPT_iwithprefixbefore) \ |
| 1211 | DEF_OPT("lang-asm", 0, OPT_lang_asm) \ |
| 1212 | DEF_OPT("lang-c", 0, OPT_lang_c) \ |
| 1213 | DEF_OPT("lang-c++", 0, OPT_lang_cplusplus) \ |
| 1214 | DEF_OPT("lang-c89", 0, OPT_lang_c89) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1215 | DEF_OPT("lang-objc", 0, OPT_lang_objc) \ |
| 1216 | DEF_OPT("lang-objc++", 0, OPT_lang_objcplusplus) \ |
| 1217 | DEF_OPT("nostdinc", 0, OPT_nostdinc) \ |
| 1218 | DEF_OPT("nostdinc++", 0, OPT_nostdincplusplus) \ |
| 1219 | DEF_OPT("o", no_fil, OPT_o) \ |
| 1220 | DEF_OPT("pedantic", 0, OPT_pedantic) \ |
| 1221 | DEF_OPT("pedantic-errors", 0, OPT_pedantic_errors) \ |
| 1222 | DEF_OPT("remap", 0, OPT_remap) \ |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 1223 | DEF_OPT("std=c++98", 0, OPT_std_cplusplus98) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1224 | DEF_OPT("std=c89", 0, OPT_std_c89) \ |
| 1225 | DEF_OPT("std=c99", 0, OPT_std_c99) \ |
| 1226 | DEF_OPT("std=c9x", 0, OPT_std_c9x) \ |
| 1227 | DEF_OPT("std=gnu89", 0, OPT_std_gnu89) \ |
| 1228 | DEF_OPT("std=gnu99", 0, OPT_std_gnu99) \ |
| 1229 | DEF_OPT("std=gnu9x", 0, OPT_std_gnu9x) \ |
| 1230 | DEF_OPT("std=iso9899:1990", 0, OPT_std_iso9899_1990) \ |
| 1231 | DEF_OPT("std=iso9899:199409", 0, OPT_std_iso9899_199409) \ |
| 1232 | DEF_OPT("std=iso9899:1999", 0, OPT_std_iso9899_1999) \ |
| 1233 | DEF_OPT("std=iso9899:199x", 0, OPT_std_iso9899_199x) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1234 | DEF_OPT("trigraphs", 0, OPT_trigraphs) \ |
| 1235 | DEF_OPT("v", 0, OPT_v) \ |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1236 | DEF_OPT("version", 0, OPT_version) \ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1237 | DEF_OPT("w", 0, OPT_w) |
| 1238 | |
| 1239 | #define DEF_OPT(text, msg, code) code, |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1240 | enum opt_code |
| 1241 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1242 | COMMAND_LINE_OPTIONS |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1243 | N_OPTS |
| 1244 | }; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1245 | #undef DEF_OPT |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1246 | |
| 1247 | struct cl_option |
| 1248 | { |
| 1249 | const char *opt_text; |
| 1250 | const char *msg; |
| 1251 | size_t opt_len; |
| 1252 | enum opt_code opt_code; |
| 1253 | }; |
| 1254 | |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1255 | #define DEF_OPT(text, msg, code) { text, msg, sizeof(text) - 1, code }, |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1256 | #ifdef HOST_EBCDIC |
| 1257 | static struct cl_option cl_options[] = |
| 1258 | #else |
| 1259 | static const struct cl_option cl_options[] = |
| 1260 | #endif |
| 1261 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1262 | COMMAND_LINE_OPTIONS |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1263 | }; |
| 1264 | #undef DEF_OPT |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1265 | #undef COMMAND_LINE_OPTIONS |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1266 | |
| 1267 | /* Perform a binary search to find which, if any, option the given |
| 1268 | command-line matches. Returns its index in the option array, |
| 1269 | negative on failure. Complications arise since some options can be |
| 1270 | suffixed with an argument, and multiple complete matches can occur, |
Neil Booth | 05e8172 | 2001-01-11 21:30:16 +0000 | [diff] [blame] | 1271 | e.g. -iwithprefix and -iwithprefixbefore. Moreover, we need to |
| 1272 | accept options beginning with -W that we do not recognise, but not |
| 1273 | to swallow any subsequent command line argument; this is handled as |
| 1274 | special cases in cpp_handle_option. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1275 | static int |
| 1276 | parse_option (input) |
| 1277 | const char *input; |
| 1278 | { |
| 1279 | unsigned int md, mn, mx; |
| 1280 | size_t opt_len; |
| 1281 | int comp; |
| 1282 | |
| 1283 | mn = 0; |
| 1284 | mx = N_OPTS; |
| 1285 | |
| 1286 | while (mx > mn) |
| 1287 | { |
| 1288 | md = (mn + mx) / 2; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1289 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1290 | opt_len = cl_options[md].opt_len; |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 1291 | comp = memcmp (input, cl_options[md].opt_text, opt_len); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1292 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1293 | if (comp > 0) |
| 1294 | mn = md + 1; |
| 1295 | else if (comp < 0) |
| 1296 | mx = md; |
| 1297 | else |
| 1298 | { |
| 1299 | if (input[opt_len] == '\0') |
| 1300 | return md; |
| 1301 | /* We were passed more text. If the option takes an argument, |
| 1302 | we may match a later option or we may have been passed the |
| 1303 | argument. The longest possible option match succeeds. |
| 1304 | If the option takes no arguments we have not matched and |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1305 | continue the search (e.g. input="stdc++" match was "stdc"). */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1306 | mn = md + 1; |
| 1307 | if (cl_options[md].msg) |
| 1308 | { |
| 1309 | /* Scan forwards. If we get an exact match, return it. |
| 1310 | Otherwise, return the longest option-accepting match. |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1311 | This loops no more than twice with current options. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1312 | mx = md; |
John David Anglin | 37b8524 | 2001-03-02 01:11:50 +0000 | [diff] [blame] | 1313 | for (; mn < (unsigned int) N_OPTS; mn++) |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1314 | { |
| 1315 | opt_len = cl_options[mn].opt_len; |
Neil Booth | 61d0346 | 2000-08-18 17:35:58 +0000 | [diff] [blame] | 1316 | if (memcmp (input, cl_options[mn].opt_text, opt_len)) |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1317 | break; |
| 1318 | if (input[opt_len] == '\0') |
| 1319 | return mn; |
| 1320 | if (cl_options[mn].msg) |
| 1321 | mx = mn; |
| 1322 | } |
| 1323 | return mx; |
| 1324 | } |
| 1325 | } |
| 1326 | } |
| 1327 | |
| 1328 | return -1; |
| 1329 | } |
| 1330 | |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1331 | /* Handle one command-line option in (argc, argv). |
| 1332 | Can be called multiple times, to handle multiple sets of options. |
Jakub Jelinek | ffdeea4 | 2002-01-29 13:09:37 +0100 | [diff] [blame] | 1333 | If ignore is non-zero, this will ignore unrecognized -W* options. |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1334 | Returns number of strings consumed. */ |
Zack Weinberg | 2c0accc | 2000-07-15 19:29:14 +0000 | [diff] [blame] | 1335 | int |
Jakub Jelinek | ffdeea4 | 2002-01-29 13:09:37 +0100 | [diff] [blame] | 1336 | cpp_handle_option (pfile, argc, argv, ignore) |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1337 | cpp_reader *pfile; |
| 1338 | int argc; |
| 1339 | char **argv; |
Jakub Jelinek | ffdeea4 | 2002-01-29 13:09:37 +0100 | [diff] [blame] | 1340 | int ignore; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1341 | { |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1342 | int i = 0; |
Zack Weinberg | f8f769e | 2000-05-28 05:56:38 +0000 | [diff] [blame] | 1343 | struct cpp_pending *pend = CPP_OPTION (pfile, pending); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1344 | |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 1345 | /* Interpret "-" or a non-option as a file name. */ |
| 1346 | if (argv[i][0] != '-' || argv[i][1] == '\0') |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1347 | { |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 1348 | if (CPP_OPTION (pfile, in_fname) == NULL) |
| 1349 | CPP_OPTION (pfile, in_fname) = argv[i]; |
| 1350 | else if (CPP_OPTION (pfile, out_fname) == NULL) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1351 | CPP_OPTION (pfile, out_fname) = argv[i]; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1352 | else |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1353 | cpp_error (pfile, DL_FATAL, |
| 1354 | "too many filenames. Type %s --help for usage info", |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 1355 | progname); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1356 | } |
| 1357 | else |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1358 | { |
| 1359 | enum opt_code opt_code; |
| 1360 | int opt_index; |
Neil Booth | 7ceb359 | 2000-03-11 00:49:44 +0000 | [diff] [blame] | 1361 | const char *arg = 0; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1362 | |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1363 | /* Skip over '-'. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1364 | opt_index = parse_option (&argv[i][1]); |
| 1365 | if (opt_index < 0) |
| 1366 | return i; |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1367 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1368 | opt_code = cl_options[opt_index].opt_code; |
| 1369 | if (cl_options[opt_index].msg) |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1370 | { |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1371 | arg = &argv[i][cl_options[opt_index].opt_len + 1]; |
| 1372 | |
Neil Booth | 5c5d1ea | 2001-01-10 21:32:15 +0000 | [diff] [blame] | 1373 | /* Yuk. Special case for -W as it must not swallow |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1374 | up any following argument. If this becomes common, add |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1375 | another field to the cl_options table. */ |
Neil Booth | 5c5d1ea | 2001-01-10 21:32:15 +0000 | [diff] [blame] | 1376 | if (arg[0] == '\0' && opt_code != OPT_W) |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1377 | { |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1378 | arg = argv[++i]; |
| 1379 | if (!arg) |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1380 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1381 | cpp_error (pfile, DL_FATAL, |
| 1382 | cl_options[opt_index].msg, argv[i - 1]); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1383 | return argc; |
| 1384 | } |
| 1385 | } |
| 1386 | } |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1387 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1388 | switch (opt_code) |
| 1389 | { |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1390 | case N_OPTS: /* Shut GCC up. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1391 | break; |
| 1392 | case OPT_fleading_underscore: |
Neil Booth | 771c4df | 2000-09-07 20:31:06 +0000 | [diff] [blame] | 1393 | CPP_OPTION (pfile, user_label_prefix) = "_"; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1394 | break; |
| 1395 | case OPT_fno_leading_underscore: |
Neil Booth | 771c4df | 2000-09-07 20:31:06 +0000 | [diff] [blame] | 1396 | CPP_OPTION (pfile, user_label_prefix) = ""; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1397 | break; |
Jakub Jelinek | be76805 | 2000-12-15 16:49:28 +0100 | [diff] [blame] | 1398 | case OPT_fno_operator_names: |
| 1399 | CPP_OPTION (pfile, operator_names) = 0; |
| 1400 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1401 | case OPT_fpreprocessed: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1402 | CPP_OPTION (pfile, preprocessed) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1403 | break; |
| 1404 | case OPT_fno_preprocessed: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1405 | CPP_OPTION (pfile, preprocessed) = 0; |
| 1406 | break; |
| 1407 | case OPT_fshow_column: |
| 1408 | CPP_OPTION (pfile, show_column) = 1; |
| 1409 | break; |
| 1410 | case OPT_fno_show_column: |
| 1411 | CPP_OPTION (pfile, show_column) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1412 | break; |
Neil Booth | 0fef3fd | 2002-02-02 18:56:37 +0000 | [diff] [blame] | 1413 | case OPT_fsigned_char: |
| 1414 | CPP_OPTION (pfile, signed_char) = 1; |
| 1415 | break; |
| 1416 | case OPT_funsigned_char: |
| 1417 | CPP_OPTION (pfile, signed_char) = 0; |
| 1418 | break; |
Neil Booth | 6ab3e7d | 2000-05-18 11:09:27 +0000 | [diff] [blame] | 1419 | case OPT_ftabstop: |
| 1420 | /* Silently ignore empty string, non-longs and silly values. */ |
| 1421 | if (arg[0] != '\0') |
| 1422 | { |
| 1423 | char *endptr; |
| 1424 | long tabstop = strtol (arg, &endptr, 10); |
| 1425 | if (*endptr == '\0' && tabstop >= 1 && tabstop <= 100) |
| 1426 | CPP_OPTION (pfile, tabstop) = tabstop; |
| 1427 | } |
| 1428 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1429 | case OPT_w: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1430 | CPP_OPTION (pfile, inhibit_warnings) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1431 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1432 | case OPT_h: |
| 1433 | case OPT__help: |
| 1434 | print_help (); |
Neil Booth | 7e96d76 | 2001-01-13 01:00:01 +0000 | [diff] [blame] | 1435 | CPP_OPTION (pfile, help_only) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1436 | break; |
Chandra Chavva | 91606ce | 2000-11-14 12:06:06 -0500 | [diff] [blame] | 1437 | case OPT_target__help: |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1438 | /* Print if any target specific options. cpplib has none, but |
| 1439 | make sure help_only gets set. */ |
Neil Booth | 7e96d76 | 2001-01-13 01:00:01 +0000 | [diff] [blame] | 1440 | CPP_OPTION (pfile, help_only) = 1; |
Chandra Chavva | 91606ce | 2000-11-14 12:06:06 -0500 | [diff] [blame] | 1441 | break; |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1442 | |
| 1443 | /* --version inhibits compilation, -version doesn't. -v means |
| 1444 | verbose and -version. Historical reasons, don't ask. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1445 | case OPT__version: |
Neil Booth | 7e96d76 | 2001-01-13 01:00:01 +0000 | [diff] [blame] | 1446 | CPP_OPTION (pfile, help_only) = 1; |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 1447 | pfile->print_version = 1; |
| 1448 | break; |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1449 | case OPT_v: |
| 1450 | CPP_OPTION (pfile, verbose) = 1; |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 1451 | pfile->print_version = 1; |
| 1452 | break; |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1453 | case OPT_version: |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 1454 | pfile->print_version = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1455 | break; |
Zack Weinberg | f4cdc36 | 2001-01-05 23:41:00 +0000 | [diff] [blame] | 1456 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1457 | case OPT_C: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1458 | CPP_OPTION (pfile, discard_comments) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1459 | break; |
Jason Thorpe | 477cdac | 2002-04-07 03:12:23 +0000 | [diff] [blame] | 1460 | case OPT_CC: |
| 1461 | CPP_OPTION (pfile, discard_comments) = 0; |
| 1462 | CPP_OPTION (pfile, discard_comments_in_macro_exp) = 0; |
| 1463 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1464 | case OPT_P: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1465 | CPP_OPTION (pfile, no_line_commands) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1466 | break; |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1467 | case OPT_dollar: /* Don't include $ in identifiers. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1468 | CPP_OPTION (pfile, dollars_in_ident) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1469 | break; |
| 1470 | case OPT_H: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1471 | CPP_OPTION (pfile, print_include_names) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1472 | break; |
| 1473 | case OPT_D: |
Zack Weinberg | f8f769e | 2000-05-28 05:56:38 +0000 | [diff] [blame] | 1474 | new_pending_directive (pend, arg, cpp_define); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1475 | break; |
| 1476 | case OPT_pedantic_errors: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1477 | CPP_OPTION (pfile, pedantic_errors) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1478 | /* fall through */ |
| 1479 | case OPT_pedantic: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1480 | CPP_OPTION (pfile, pedantic) = 1; |
Neil Booth | 2784528 | 2002-03-24 12:52:28 +0000 | [diff] [blame] | 1481 | CPP_OPTION (pfile, warn_endif_labels) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1482 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1483 | case OPT_trigraphs: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1484 | CPP_OPTION (pfile, trigraphs) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1485 | break; |
| 1486 | case OPT_plus: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1487 | CPP_OPTION (pfile, cplusplus) = 1; |
| 1488 | CPP_OPTION (pfile, cplusplus_comments) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1489 | break; |
| 1490 | case OPT_remap: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1491 | CPP_OPTION (pfile, remap) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1492 | break; |
| 1493 | case OPT_iprefix: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1494 | CPP_OPTION (pfile, include_prefix) = arg; |
| 1495 | CPP_OPTION (pfile, include_prefix_len) = strlen (arg); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1496 | break; |
| 1497 | case OPT_lang_c: |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 1498 | set_lang (pfile, CLK_GNUC89); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1499 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1500 | case OPT_lang_cplusplus: |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 1501 | set_lang (pfile, CLK_GNUCXX); |
| 1502 | break; |
| 1503 | case OPT_lang_objc: |
| 1504 | set_lang (pfile, CLK_OBJC); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1505 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1506 | case OPT_lang_objcplusplus: |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 1507 | set_lang (pfile, CLK_OBJCXX); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1508 | break; |
| 1509 | case OPT_lang_asm: |
Neil Booth | dd07b88 | 2000-11-20 18:27:32 +0000 | [diff] [blame] | 1510 | set_lang (pfile, CLK_ASM); |
| 1511 | break; |
| 1512 | case OPT_std_cplusplus98: |
| 1513 | set_lang (pfile, CLK_CXX98); |
| 1514 | break; |
| 1515 | case OPT_std_gnu89: |
| 1516 | set_lang (pfile, CLK_GNUC89); |
| 1517 | break; |
| 1518 | case OPT_std_gnu9x: |
| 1519 | case OPT_std_gnu99: |
| 1520 | set_lang (pfile, CLK_GNUC99); |
| 1521 | break; |
| 1522 | case OPT_std_iso9899_199409: |
| 1523 | set_lang (pfile, CLK_STDC94); |
| 1524 | break; |
| 1525 | case OPT_std_iso9899_1990: |
| 1526 | case OPT_std_c89: |
| 1527 | case OPT_lang_c89: |
| 1528 | set_lang (pfile, CLK_STDC89); |
| 1529 | break; |
| 1530 | case OPT_std_iso9899_199x: |
| 1531 | case OPT_std_iso9899_1999: |
| 1532 | case OPT_std_c9x: |
| 1533 | case OPT_std_c99: |
| 1534 | set_lang (pfile, CLK_STDC99); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1535 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1536 | case OPT_nostdinc: |
| 1537 | /* -nostdinc causes no default include directories. |
| 1538 | You must specify all include-file directories with -I. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1539 | CPP_OPTION (pfile, no_standard_includes) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1540 | break; |
| 1541 | case OPT_nostdincplusplus: |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 1542 | /* -nostdinc++ causes no default C++-specific include directories. */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1543 | CPP_OPTION (pfile, no_standard_cplusplus_includes) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1544 | break; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1545 | case OPT_o: |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 1546 | if (CPP_OPTION (pfile, out_fname) == NULL) |
| 1547 | CPP_OPTION (pfile, out_fname) = arg; |
| 1548 | else |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1549 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1550 | cpp_error (pfile, DL_FATAL, "output filename specified twice"); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1551 | return argc; |
| 1552 | } |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1553 | break; |
| 1554 | case OPT_d: |
| 1555 | /* Args to -d specify what parts of macros to dump. |
| 1556 | Silently ignore unrecognised options; they may |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1557 | be aimed at the compiler proper. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1558 | { |
| 1559 | char c; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1560 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1561 | while ((c = *arg++) != '\0') |
| 1562 | switch (c) |
| 1563 | { |
| 1564 | case 'M': |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1565 | CPP_OPTION (pfile, dump_macros) = dump_only; |
| 1566 | CPP_OPTION (pfile, no_output) = 1; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1567 | break; |
| 1568 | case 'N': |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1569 | CPP_OPTION (pfile, dump_macros) = dump_names; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1570 | break; |
| 1571 | case 'D': |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1572 | CPP_OPTION (pfile, dump_macros) = dump_definitions; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1573 | break; |
| 1574 | case 'I': |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1575 | CPP_OPTION (pfile, dump_includes) = 1; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1576 | break; |
| 1577 | } |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1578 | } |
| 1579 | break; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1580 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1581 | case OPT_MG: |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1582 | CPP_OPTION (pfile, print_deps_missing_files) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1583 | break; |
| 1584 | case OPT_M: |
Neil Booth | 3ddbb8a | 2002-03-24 21:01:00 +0000 | [diff] [blame] | 1585 | /* When doing dependencies with -M or -MM, suppress normal |
| 1586 | preprocessed output, but still do -dM etc. as software |
| 1587 | depends on this. Preprocessed output occurs if -MD, -MMD |
| 1588 | or environment var dependency generation is used. */ |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1589 | CPP_OPTION (pfile, print_deps) = 2; |
Neil Booth | 3ddbb8a | 2002-03-24 21:01:00 +0000 | [diff] [blame] | 1590 | CPP_OPTION (pfile, no_output) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1591 | break; |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1592 | case OPT_MM: |
| 1593 | CPP_OPTION (pfile, print_deps) = 1; |
Neil Booth | 3ddbb8a | 2002-03-24 21:01:00 +0000 | [diff] [blame] | 1594 | CPP_OPTION (pfile, no_output) = 1; |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1595 | break; |
| 1596 | case OPT_MF: |
| 1597 | CPP_OPTION (pfile, deps_file) = arg; |
| 1598 | break; |
| 1599 | case OPT_MP: |
Neil Booth | a5a4ce3 | 2001-01-05 07:50:24 +0000 | [diff] [blame] | 1600 | CPP_OPTION (pfile, deps_phony_targets) = 1; |
| 1601 | break; |
Neil Booth | f7114e1 | 2001-01-06 00:15:29 +0000 | [diff] [blame] | 1602 | case OPT_MQ: |
Neil Booth | 03b9ab4 | 2001-01-04 10:25:55 +0000 | [diff] [blame] | 1603 | case OPT_MT: |
Neil Booth | f7114e1 | 2001-01-06 00:15:29 +0000 | [diff] [blame] | 1604 | /* Add a target. -MQ quotes for Make. */ |
| 1605 | deps_add_target (pfile->deps, arg, opt_code == OPT_MQ); |
Neil Booth | 03b9ab4 | 2001-01-04 10:25:55 +0000 | [diff] [blame] | 1606 | break; |
| 1607 | |
Neil Booth | b3124fa | 2002-03-16 14:03:36 +0000 | [diff] [blame] | 1608 | case OPT_MD: |
| 1609 | CPP_OPTION (pfile, print_deps) = 2; |
| 1610 | CPP_OPTION (pfile, deps_file) = arg; |
| 1611 | break; |
| 1612 | case OPT_MMD: |
| 1613 | CPP_OPTION (pfile, print_deps) = 1; |
| 1614 | CPP_OPTION (pfile, deps_file) = arg; |
| 1615 | break; |
| 1616 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1617 | case OPT_A: |
Neil Booth | e1e97c4 | 2000-03-16 14:15:17 +0000 | [diff] [blame] | 1618 | if (arg[0] == '-') |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1619 | { |
Neil Booth | e1e97c4 | 2000-03-16 14:15:17 +0000 | [diff] [blame] | 1620 | /* -A with an argument beginning with '-' acts as |
| 1621 | #unassert on whatever immediately follows the '-'. |
| 1622 | If "-" is the whole argument, we eliminate all |
| 1623 | predefined macros and assertions, including those |
| 1624 | that were specified earlier on the command line. |
| 1625 | That way we can get rid of any that were passed |
| 1626 | automatically in from GCC. */ |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1627 | |
Neil Booth | e1e97c4 | 2000-03-16 14:15:17 +0000 | [diff] [blame] | 1628 | if (arg[1] == '\0') |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1629 | { |
Neil Booth | 29401c3 | 2001-08-22 20:37:20 +0000 | [diff] [blame] | 1630 | free_chain (pend->directive_head); |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1631 | pend->directive_head = NULL; |
| 1632 | pend->directive_tail = NULL; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1633 | } |
Neil Booth | e1e97c4 | 2000-03-16 14:15:17 +0000 | [diff] [blame] | 1634 | else |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1635 | new_pending_directive (pend, arg + 1, cpp_unassert); |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1636 | } |
Neil Booth | e1e97c4 | 2000-03-16 14:15:17 +0000 | [diff] [blame] | 1637 | else |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1638 | new_pending_directive (pend, arg, cpp_assert); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1639 | break; |
| 1640 | case OPT_U: |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1641 | new_pending_directive (pend, arg, cpp_undef); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1642 | break; |
| 1643 | case OPT_I: /* Add directory to path for includes. */ |
| 1644 | if (!strcmp (arg, "-")) |
| 1645 | { |
| 1646 | /* -I- means: |
| 1647 | Use the preceding -I directories for #include "..." |
| 1648 | but not #include <...>. |
| 1649 | Don't search the directory of the present file |
| 1650 | for #include "...". (Note that -I. -I- is not the same as |
| 1651 | the default setup; -I. uses the compiler's working dir.) */ |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1652 | if (! CPP_OPTION (pfile, ignore_srcdir)) |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1653 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1654 | pend->quote_head = pend->brack_head; |
| 1655 | pend->quote_tail = pend->brack_tail; |
| 1656 | pend->brack_head = 0; |
| 1657 | pend->brack_tail = 0; |
| 1658 | CPP_OPTION (pfile, ignore_srcdir) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1659 | } |
| 1660 | else |
| 1661 | { |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1662 | cpp_error (pfile, DL_FATAL, "-I- specified twice"); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1663 | return argc; |
| 1664 | } |
| 1665 | } |
| 1666 | else |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1667 | append_include_chain (pfile, xstrdup (arg), BRACKET, 0); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1668 | break; |
| 1669 | case OPT_isystem: |
| 1670 | /* Add directory to beginning of system include path, as a system |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1671 | include directory. */ |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1672 | append_include_chain (pfile, xstrdup (arg), SYSTEM, 0); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1673 | break; |
| 1674 | case OPT_include: |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1675 | case OPT_imacros: |
| 1676 | { |
| 1677 | struct pending_option *o = (struct pending_option *) |
| 1678 | xmalloc (sizeof (struct pending_option)); |
| 1679 | o->arg = arg; |
| 1680 | o->next = NULL; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1681 | |
Neil Booth | d7bc7a9 | 2001-08-21 06:20:18 +0000 | [diff] [blame] | 1682 | if (opt_code == OPT_include) |
| 1683 | APPEND (pend, include, o); |
| 1684 | else |
| 1685 | APPEND (pend, imacros, o); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1686 | } |
| 1687 | break; |
| 1688 | case OPT_iwithprefix: |
| 1689 | /* Add directory to end of path for includes, |
| 1690 | with the default prefix at the front of its name. */ |
| 1691 | /* fall through */ |
| 1692 | case OPT_iwithprefixbefore: |
| 1693 | /* Add directory to main path for includes, |
| 1694 | with the default prefix at the front of its name. */ |
| 1695 | { |
| 1696 | char *fname; |
| 1697 | int len; |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1698 | |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1699 | len = strlen (arg); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1700 | |
| 1701 | if (CPP_OPTION (pfile, include_prefix) != 0) |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1702 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1703 | size_t ipl = CPP_OPTION (pfile, include_prefix_len); |
| 1704 | fname = xmalloc (ipl + len + 1); |
| 1705 | memcpy (fname, CPP_OPTION (pfile, include_prefix), ipl); |
| 1706 | memcpy (fname + ipl, arg, len + 1); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1707 | } |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 1708 | else if (cpp_GCC_INCLUDE_DIR_len) |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1709 | { |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 1710 | fname = xmalloc (cpp_GCC_INCLUDE_DIR_len + len + 1); |
| 1711 | memcpy (fname, cpp_GCC_INCLUDE_DIR, cpp_GCC_INCLUDE_DIR_len); |
| 1712 | memcpy (fname + cpp_GCC_INCLUDE_DIR_len, arg, len + 1); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1713 | } |
Zack Weinberg | 60893f4 | 2000-07-06 22:52:03 +0000 | [diff] [blame] | 1714 | else |
| 1715 | fname = xstrdup (arg); |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1716 | |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1717 | append_include_chain (pfile, fname, |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1718 | opt_code == OPT_iwithprefix ? SYSTEM: BRACKET, 0); |
| 1719 | } |
| 1720 | break; |
| 1721 | case OPT_idirafter: |
| 1722 | /* Add directory to end of path for includes. */ |
Neil Booth | e33f625 | 2000-08-17 17:58:24 +0000 | [diff] [blame] | 1723 | append_include_chain (pfile, xstrdup (arg), AFTER, 0); |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1724 | break; |
| 1725 | case OPT_W: |
Neil Booth | 4a58aab | 2000-11-18 12:18:09 +0000 | [diff] [blame] | 1726 | /* Silently ignore unrecognised options. */ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1727 | if (!strcmp (argv[i], "-Wall")) |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1728 | { |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1729 | CPP_OPTION (pfile, warn_trigraphs) = 1; |
| 1730 | CPP_OPTION (pfile, warn_comments) = 1; |
Zack Weinberg | 0b22d65 | 1999-03-15 18:42:46 +0000 | [diff] [blame] | 1731 | } |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1732 | else if (!strcmp (argv[i], "-Wtraditional")) |
Zack Weinberg | 07aa0b0 | 2000-04-01 22:55:25 +0000 | [diff] [blame] | 1733 | CPP_OPTION (pfile, warn_traditional) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1734 | else if (!strcmp (argv[i], "-Wtrigraphs")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1735 | CPP_OPTION (pfile, warn_trigraphs) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1736 | else if (!strcmp (argv[i], "-Wcomment")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1737 | CPP_OPTION (pfile, warn_comments) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1738 | else if (!strcmp (argv[i], "-Wcomments")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1739 | CPP_OPTION (pfile, warn_comments) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1740 | else if (!strcmp (argv[i], "-Wundef")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1741 | CPP_OPTION (pfile, warn_undef) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1742 | else if (!strcmp (argv[i], "-Wimport")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1743 | CPP_OPTION (pfile, warn_import) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1744 | else if (!strcmp (argv[i], "-Werror")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1745 | CPP_OPTION (pfile, warnings_are_errors) = 1; |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1746 | else if (!strcmp (argv[i], "-Wsystem-headers")) |
| 1747 | CPP_OPTION (pfile, warn_system_headers) = 1; |
Phil Edwards | 909de5d | 2002-03-22 21:59:04 +0000 | [diff] [blame] | 1748 | else if (!strcmp (argv[i], "-Wendif-labels")) |
| 1749 | CPP_OPTION (pfile, warn_endif_labels) = 1; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1750 | else if (!strcmp (argv[i], "-Wno-traditional")) |
Zack Weinberg | 07aa0b0 | 2000-04-01 22:55:25 +0000 | [diff] [blame] | 1751 | CPP_OPTION (pfile, warn_traditional) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1752 | else if (!strcmp (argv[i], "-Wno-trigraphs")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1753 | CPP_OPTION (pfile, warn_trigraphs) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1754 | else if (!strcmp (argv[i], "-Wno-comment")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1755 | CPP_OPTION (pfile, warn_comments) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1756 | else if (!strcmp (argv[i], "-Wno-comments")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1757 | CPP_OPTION (pfile, warn_comments) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1758 | else if (!strcmp (argv[i], "-Wno-undef")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1759 | CPP_OPTION (pfile, warn_undef) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1760 | else if (!strcmp (argv[i], "-Wno-import")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1761 | CPP_OPTION (pfile, warn_import) = 0; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1762 | else if (!strcmp (argv[i], "-Wno-error")) |
Zack Weinberg | ae79697 | 2000-03-31 23:16:11 +0000 | [diff] [blame] | 1763 | CPP_OPTION (pfile, warnings_are_errors) = 0; |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1764 | else if (!strcmp (argv[i], "-Wno-system-headers")) |
| 1765 | CPP_OPTION (pfile, warn_system_headers) = 0; |
Phil Edwards | 909de5d | 2002-03-22 21:59:04 +0000 | [diff] [blame] | 1766 | else if (!strcmp (argv[i], "-Wno-endif-labels")) |
| 1767 | CPP_OPTION (pfile, warn_endif_labels) = 0; |
Jakub Jelinek | ffdeea4 | 2002-01-29 13:09:37 +0100 | [diff] [blame] | 1768 | else if (! ignore) |
| 1769 | return i; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1770 | break; |
| 1771 | } |
| 1772 | } |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1773 | return i + 1; |
| 1774 | } |
| 1775 | |
| 1776 | /* Handle command-line options in (argc, argv). |
| 1777 | Can be called multiple times, to handle multiple sets of options. |
| 1778 | Returns if an unrecognized option is seen. |
| 1779 | Returns number of strings consumed. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1780 | int |
| 1781 | cpp_handle_options (pfile, argc, argv) |
| 1782 | cpp_reader *pfile; |
| 1783 | int argc; |
| 1784 | char **argv; |
| 1785 | { |
| 1786 | int i; |
| 1787 | int strings_processed; |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1788 | |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1789 | for (i = 0; i < argc; i += strings_processed) |
| 1790 | { |
Jakub Jelinek | ffdeea4 | 2002-01-29 13:09:37 +0100 | [diff] [blame] | 1791 | strings_processed = cpp_handle_option (pfile, argc - i, argv + i, 1); |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1792 | if (strings_processed == 0) |
| 1793 | break; |
| 1794 | } |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1795 | |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1796 | return i; |
| 1797 | } |
| 1798 | |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1799 | /* Extra processing when all options are parsed, after all calls to |
| 1800 | cpp_handle_option[s]. Consistency checks etc. */ |
| 1801 | void |
| 1802 | cpp_post_options (pfile) |
| 1803 | cpp_reader *pfile; |
| 1804 | { |
Zack Weinberg | cb77384 | 2001-03-02 00:42:28 +0000 | [diff] [blame] | 1805 | if (pfile->print_version) |
| 1806 | { |
| 1807 | fprintf (stderr, _("GNU CPP version %s (cpplib)"), version_string); |
| 1808 | #ifdef TARGET_VERSION |
| 1809 | TARGET_VERSION; |
| 1810 | #endif |
| 1811 | fputc ('\n', stderr); |
| 1812 | } |
| 1813 | |
Neil Booth | 373e217 | 2001-02-21 07:29:56 +0000 | [diff] [blame] | 1814 | /* Canonicalize in_fname and out_fname. We guarantee they are not |
| 1815 | NULL, and that the empty string represents stdin / stdout. */ |
| 1816 | if (CPP_OPTION (pfile, in_fname) == NULL |
| 1817 | || !strcmp (CPP_OPTION (pfile, in_fname), "-")) |
| 1818 | CPP_OPTION (pfile, in_fname) = ""; |
| 1819 | |
| 1820 | if (CPP_OPTION (pfile, out_fname) == NULL |
| 1821 | || !strcmp (CPP_OPTION (pfile, out_fname), "-")) |
| 1822 | CPP_OPTION (pfile, out_fname) = ""; |
| 1823 | |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1824 | /* -Wtraditional is not useful in C++ mode. */ |
| 1825 | if (CPP_OPTION (pfile, cplusplus)) |
| 1826 | CPP_OPTION (pfile, warn_traditional) = 0; |
| 1827 | |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 1828 | /* Set this if it hasn't been set already. */ |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1829 | if (CPP_OPTION (pfile, user_label_prefix) == NULL) |
| 1830 | CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX; |
| 1831 | |
Zack Weinberg | 6d4587f | 2001-05-10 00:07:23 +0000 | [diff] [blame] | 1832 | /* Permanently disable macro expansion if we are rescanning |
| 1833 | preprocessed text. */ |
| 1834 | if (CPP_OPTION (pfile, preprocessed)) |
| 1835 | pfile->state.prevent_expansion = 1; |
| 1836 | |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1837 | /* We need to do this after option processing and before |
| 1838 | cpp_start_read, as cppmain.c relies on the options->no_output to |
| 1839 | set its callbacks correctly before calling cpp_start_read. */ |
| 1840 | init_dependency_output (pfile); |
| 1841 | |
Neil Booth | e582248 | 2001-01-09 14:45:44 +0000 | [diff] [blame] | 1842 | /* After checking the environment variables, check if -M or -MM has |
| 1843 | not been specified, but other -M options have. */ |
| 1844 | if (CPP_OPTION (pfile, print_deps) == 0 && |
| 1845 | (CPP_OPTION (pfile, print_deps_missing_files) |
| 1846 | || CPP_OPTION (pfile, deps_file) |
| 1847 | || CPP_OPTION (pfile, deps_phony_targets))) |
Neil Booth | ebef4e8 | 2002-04-14 18:42:47 +0000 | [diff] [blame] | 1848 | cpp_error (pfile, DL_FATAL, |
| 1849 | "you must additionally specify either -M or -MM"); |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1850 | } |
| 1851 | |
Neil Booth | 56cd5b9 | 2002-02-20 07:24:10 +0000 | [diff] [blame] | 1852 | /* Set up dependency-file output. On exit, if print_deps is non-zero |
| 1853 | then deps_file is not NULL; stdout is the empty string. */ |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1854 | static void |
| 1855 | init_dependency_output (pfile) |
| 1856 | cpp_reader *pfile; |
| 1857 | { |
| 1858 | char *spec, *s, *output_file; |
| 1859 | |
| 1860 | /* Either of two environment variables can specify output of deps. |
| 1861 | Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET", |
| 1862 | where OUTPUT_FILE is the file to write deps info to |
| 1863 | and DEPS_TARGET is the target to mention in the deps. */ |
| 1864 | |
| 1865 | if (CPP_OPTION (pfile, print_deps) == 0) |
| 1866 | { |
| 1867 | spec = getenv ("DEPENDENCIES_OUTPUT"); |
| 1868 | if (spec) |
| 1869 | CPP_OPTION (pfile, print_deps) = 1; |
| 1870 | else |
| 1871 | { |
| 1872 | spec = getenv ("SUNPRO_DEPENDENCIES"); |
| 1873 | if (spec) |
| 1874 | CPP_OPTION (pfile, print_deps) = 2; |
| 1875 | else |
| 1876 | return; |
| 1877 | } |
| 1878 | |
| 1879 | /* Find the space before the DEPS_TARGET, if there is one. */ |
| 1880 | s = strchr (spec, ' '); |
| 1881 | if (s) |
| 1882 | { |
| 1883 | /* Let the caller perform MAKE quoting. */ |
| 1884 | deps_add_target (pfile->deps, s + 1, 0); |
| 1885 | output_file = (char *) xmalloc (s - spec + 1); |
| 1886 | memcpy (output_file, spec, s - spec); |
| 1887 | output_file[s - spec] = 0; |
| 1888 | } |
| 1889 | else |
| 1890 | output_file = spec; |
| 1891 | |
Neil Booth | ab8e222 | 2002-02-23 13:42:40 +0000 | [diff] [blame] | 1892 | /* Command line -MF overrides environment variables and default. */ |
| 1893 | if (CPP_OPTION (pfile, deps_file) == 0) |
| 1894 | CPP_OPTION (pfile, deps_file) = output_file; |
| 1895 | |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1896 | CPP_OPTION (pfile, print_deps_append) = 1; |
| 1897 | } |
Neil Booth | ab8e222 | 2002-02-23 13:42:40 +0000 | [diff] [blame] | 1898 | else if (CPP_OPTION (pfile, deps_file) == 0) |
Neil Booth | 32810ba | 2002-03-10 21:10:21 +0000 | [diff] [blame] | 1899 | /* If -M or -MM was seen without -MF, default output to wherever |
| 1900 | was specified with -o. out_fname is non-NULL here. */ |
Neil Booth | ab8e222 | 2002-02-23 13:42:40 +0000 | [diff] [blame] | 1901 | CPP_OPTION (pfile, deps_file) = CPP_OPTION (pfile, out_fname); |
Neil Booth | 7ca3d2b | 2001-01-07 11:15:13 +0000 | [diff] [blame] | 1902 | } |
| 1903 | |
Neil Booth | 5d8ebbd | 2002-01-03 21:43:09 +0000 | [diff] [blame] | 1904 | /* Handle --help output. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1905 | static void |
| 1906 | print_help () |
| 1907 | { |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1908 | /* To keep the lines from getting too long for some compilers, limit |
Kazu Hirata | ec5c56d | 2001-08-01 17:57:27 +0000 | [diff] [blame] | 1909 | to about 500 characters (6 lines) per chunk. */ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1910 | fputs (_("\ |
| 1911 | Switches:\n\ |
| 1912 | -include <file> Include the contents of <file> before other files\n\ |
| 1913 | -imacros <file> Accept definition of macros in <file>\n\ |
| 1914 | -iprefix <path> Specify <path> as a prefix for next two options\n\ |
| 1915 | -iwithprefix <dir> Add <dir> to the end of the system include path\n\ |
| 1916 | -iwithprefixbefore <dir> Add <dir> to the end of the main include path\n\ |
| 1917 | -isystem <dir> Add <dir> to the start of the system include path\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1918 | "), stdout); |
| 1919 | fputs (_("\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1920 | -idirafter <dir> Add <dir> to the end of the system include path\n\ |
| 1921 | -I <dir> Add <dir> to the end of the main include path\n\ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1922 | -I- Fine-grained include path control; see info docs\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1923 | -nostdinc Do not search system include directories\n\ |
| 1924 | (dirs specified with -isystem will still be used)\n\ |
| 1925 | -nostdinc++ Do not search system include directories for C++\n\ |
| 1926 | -o <file> Put output into <file>\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1927 | "), stdout); |
| 1928 | fputs (_("\ |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 1929 | -pedantic Issue all warnings demanded by strict ISO C\n\ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 1930 | -pedantic-errors Issue -pedantic warnings as errors instead\n\ |
Zack Weinberg | 041c319 | 2000-07-04 01:58:21 +0000 | [diff] [blame] | 1931 | -trigraphs Support ISO C trigraphs\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1932 | -lang-c Assume that the input sources are in C\n\ |
| 1933 | -lang-c89 Assume that the input sources are in C89\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1934 | "), stdout); |
| 1935 | fputs (_("\ |
Zack Weinberg | f9a0e96 | 2000-07-13 02:32:41 +0000 | [diff] [blame] | 1936 | -lang-c++ Assume that the input sources are in C++\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1937 | -lang-objc Assume that the input sources are in ObjectiveC\n\ |
| 1938 | -lang-objc++ Assume that the input sources are in ObjectiveC++\n\ |
| 1939 | -lang-asm Assume that the input sources are in assembler\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1940 | "), stdout); |
| 1941 | fputs (_("\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1942 | -std=<std name> Specify the conformance standard; one of:\n\ |
Ulrich Drepper | 916269a | 2000-01-29 19:00:43 +0000 | [diff] [blame] | 1943 | gnu89, gnu99, c89, c99, iso9899:1990,\n\ |
| 1944 | iso9899:199409, iso9899:1999\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1945 | -+ Allow parsing of C++ style features\n\ |
| 1946 | -w Inhibit warning messages\n\ |
| 1947 | -Wtrigraphs Warn if trigraphs are encountered\n\ |
| 1948 | -Wno-trigraphs Do not warn about trigraphs\n\ |
| 1949 | -Wcomment{s} Warn if one comment starts inside another\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1950 | "), stdout); |
| 1951 | fputs (_("\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1952 | -Wno-comment{s} Do not warn about comments\n\ |
Zack Weinberg | f9a0e96 | 2000-07-13 02:32:41 +0000 | [diff] [blame] | 1953 | -Wtraditional Warn about features not present in traditional C\n\ |
| 1954 | -Wno-traditional Do not warn about traditional C\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1955 | -Wundef Warn if an undefined macro is used by #if\n\ |
| 1956 | -Wno-undef Do not warn about testing undefined macros\n\ |
| 1957 | -Wimport Warn about the use of the #import directive\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1958 | "), stdout); |
| 1959 | fputs (_("\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1960 | -Wno-import Do not warn about the use of #import\n\ |
| 1961 | -Werror Treat all warnings as errors\n\ |
| 1962 | -Wno-error Do not treat warnings as errors\n\ |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1963 | -Wsystem-headers Do not suppress warnings from system headers\n\ |
| 1964 | -Wno-system-headers Suppress warnings from system headers\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1965 | -Wall Enable all preprocessor warnings\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1966 | "), stdout); |
| 1967 | fputs (_("\ |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1968 | -M Generate make dependencies\n\ |
| 1969 | -MM As -M, but ignore system header files\n\ |
Neil Booth | 576786b | 2002-03-16 10:57:28 +0000 | [diff] [blame] | 1970 | -MD Generate make dependencies and compile\n\ |
| 1971 | -MMD As -MD, but ignore system header files\n\ |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1972 | -MF <file> Write dependency output to the given file\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1973 | -MG Treat missing header file as generated files\n\ |
Neil Booth | 9630243 | 2001-01-07 15:17:07 +0000 | [diff] [blame] | 1974 | "), stdout); |
| 1975 | fputs (_("\ |
| 1976 | -MP Generate phony targets for all headers\n\ |
| 1977 | -MQ <target> Add a MAKE-quoted target\n\ |
| 1978 | -MT <target> Add an unquoted target\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1979 | "), stdout); |
| 1980 | fputs (_("\ |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1981 | -D<macro> Define a <macro> with string '1' as its value\n\ |
| 1982 | -D<macro>=<val> Define a <macro> with <val> as its value\n\ |
Neil Booth | 576786b | 2002-03-16 10:57:28 +0000 | [diff] [blame] | 1983 | -A<question>=<answer> Assert the <answer> to <question>\n\ |
| 1984 | -A-<question>=<answer> Disable the <answer> to <question>\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1985 | -U<macro> Undefine <macro> \n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1986 | -v Display the version number\n\ |
Donn Terry | aaaf784 | 2000-07-08 06:21:13 +0000 | [diff] [blame] | 1987 | "), stdout); |
| 1988 | fputs (_("\ |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1989 | -H Print the name of header files as they are used\n\ |
| 1990 | -C Do not discard comments\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1991 | -dM Display a list of macro definitions active at end\n\ |
| 1992 | -dD Preserve macro definitions in output\n\ |
| 1993 | -dN As -dD except that only the names are preserved\n\ |
| 1994 | -dI Include #include directives in the output\n\ |
Branko Cibej | 317639a | 2000-09-26 00:54:04 +0200 | [diff] [blame] | 1995 | "), stdout); |
| 1996 | fputs (_("\ |
Neil Booth | 3bce8a0 | 2001-06-09 22:55:49 +0000 | [diff] [blame] | 1997 | -fpreprocessed Treat the input file as already preprocessed\n\ |
Neil Booth | 6ab3e7d | 2000-05-18 11:09:27 +0000 | [diff] [blame] | 1998 | -ftabstop=<number> Distance between tab stops for column reporting\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 1999 | -P Do not generate #line directives\n\ |
| 2000 | -$ Do not allow '$' in identifiers\n\ |
Neil Booth | 576786b | 2002-03-16 10:57:28 +0000 | [diff] [blame] | 2001 | -remap Remap file names when including files\n\ |
Zack Weinberg | e23c0ba | 2000-03-07 23:11:06 +0000 | [diff] [blame] | 2002 | --version Display version information\n\ |
Zack Weinberg | 6de1e2a | 1999-02-18 15:35:49 +0000 | [diff] [blame] | 2003 | -h or --help Display this information\n\ |
| 2004 | "), stdout); |
| 2005 | } |