1 /* GNU m4 -- A simple macro processor
3 Copyright (C) 1989, 1990, 1991, 1992, 1993, 2004, 2006 Free Software
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
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)
55 if (no_gnu_extensions
)
58 path
= getenv ("M4PATH");
64 path_end
= strchr (path
, ':');
67 add_include_directory (path
);
74 add_include_directory (const char *dir
)
78 if (no_gnu_extensions
)
84 incl
= (includes
*) xmalloc (sizeof (struct includes
));
86 incl
->len
= strlen (dir
);
87 incl
->dir
= xstrdup (dir
);
89 if (incl
->len
> dir_max_length
) /* remember len of longest directory */
90 dir_max_length
= incl
->len
;
92 if (dir_list_end
== NULL
)
95 dir_list_end
->next
= incl
;
99 fprintf (stderr
, "add_include_directory (%s);\n", dir
);
103 /* Search for FILE, first in `.', then according to -I options. If
104 successful, return the open file, and if RESULT is not NULL, set
105 *RESULT to a malloc'd string that represents the file found with
106 respect to the current working directory. */
109 path_search (const char *file
, const char **result
)
113 char *name
; /* buffer for constructed name */
119 /* Reject empty file. */
126 /* Look in current working directory first. */
127 fp
= fopen (file
, "r");
130 if (set_cloexec_flag (fileno (fp
), true) != 0)
131 M4ERROR ((warning_status
, errno
,
132 "Warning: cannot protect input file across forks"));
134 *result
= xstrdup (file
);
138 /* If file not found, and filename absolute, fail. */
139 if (*file
== '/' || no_gnu_extensions
)
143 name
= (char *) xmalloc (dir_max_length
+ 1 + strlen (file
) + 1);
145 for (incl
= dir_list
; incl
!= NULL
; incl
= incl
->next
)
147 strncpy (name
, incl
->dir
, incl
->len
);
148 name
[incl
->len
] = '/';
149 strcpy (name
+ incl
->len
+ 1, file
);
152 fprintf (stderr
, "path_search (%s) -- trying %s\n", file
, name
);
155 fp
= fopen (name
, "r");
158 if (debug_level
& DEBUG_TRACE_PATH
)
159 DEBUG_MESSAGE2 ("path search for `%s' found `%s'", file
, name
);
160 if (set_cloexec_flag (fileno (fp
), true) != 0)
161 M4ERROR ((warning_status
, errno
,
162 "Warning: cannot protect input file across forks"));
178 static void M4_GNUC_UNUSED
183 fprintf (stderr
, "include_dump:\n");
184 for (incl
= dir_list
; incl
!= NULL
; incl
= incl
->next
)
185 fprintf (stderr
, "\t%s\n", incl
->dir
);
188 #endif /* DEBUG_INCL */