1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2004, 2006, 2007 Free
4 Software Foundation, Inc.
6 This file is part of GNU M4.
8 GNU M4 is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU M4 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.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* Handling of path search of included files via the builtins "include"
29 struct includes
*next
; /* next directory to search */
30 const char *dir
; /* directory */
34 typedef struct includes includes
;
36 static includes
*dir_list
; /* the list of path directories */
37 static includes
*dir_list_end
; /* the end of same */
38 static int dir_max_length
; /* length of longest directory name */
50 include_env_init (void)
56 if (no_gnu_extensions
)
59 env_path
= getenv ("M4PATH");
63 env_path
= xstrdup (env_path
);
68 path_end
= strchr (path
, ':');
71 add_include_directory (path
);
79 add_include_directory (const char *dir
)
83 if (no_gnu_extensions
)
89 incl
= (includes
*) xmalloc (sizeof (struct includes
));
91 incl
->len
= strlen (dir
);
92 incl
->dir
= xstrdup (dir
);
94 if (incl
->len
> dir_max_length
) /* remember len of longest directory */
95 dir_max_length
= incl
->len
;
97 if (dir_list_end
== NULL
)
100 dir_list_end
->next
= incl
;
104 fprintf (stderr
, "add_include_directory (%s);\n", dir
);
108 /* Search for FILE, first in `.', then according to -I options. If
109 successful, return the open file, and if RESULT is not NULL, set
110 *RESULT to a malloc'd string that represents the file found with
111 respect to the current working directory. */
114 m4_path_search (const char *file
, char **result
)
118 char *name
; /* buffer for constructed name */
124 /* Reject empty file. */
131 /* Look in current working directory first. */
132 fp
= fopen (file
, "r");
135 if (set_cloexec_flag (fileno (fp
), true) != 0)
136 M4ERROR ((warning_status
, errno
,
137 "Warning: cannot protect input file across forks"));
139 *result
= xstrdup (file
);
143 /* If file not found, and filename absolute, fail. */
144 if (*file
== '/' || no_gnu_extensions
)
148 name
= (char *) xmalloc (dir_max_length
+ 1 + strlen (file
) + 1);
150 for (incl
= dir_list
; incl
!= NULL
; incl
= incl
->next
)
152 strncpy (name
, incl
->dir
, incl
->len
);
153 name
[incl
->len
] = '/';
154 strcpy (name
+ incl
->len
+ 1, file
);
157 fprintf (stderr
, "m4_path_search (%s) -- trying %s\n", file
, name
);
160 fp
= fopen (name
, "r");
163 if (debug_level
& DEBUG_TRACE_PATH
)
164 DEBUG_MESSAGE2 ("path search for `%s' found `%s'", file
, name
);
165 if (set_cloexec_flag (fileno (fp
), true) != 0)
166 M4ERROR ((warning_status
, errno
,
167 "Warning: cannot protect input file across forks"));
183 static void M4_GNUC_UNUSED
188 fprintf (stderr
, "include_dump:\n");
189 for (incl
= dir_list
; incl
!= NULL
; incl
= incl
->next
)
190 fprintf (stderr
, "\t%s\n", incl
->dir
);
193 #endif /* DEBUG_INCL */