]> andersk Git - moira.git/blob - util/makedepend/include.c
sync'ing files for RCS->CVS migration
[moira.git] / util / makedepend / include.c
1 /*
2  * $XConsortium: include.c,v 1.6 88/09/22 13:52:38 jim Exp $
3  */
4 #include "def.h"
5
6 extern struct   inclist inclist[ MAXFILES ],
7                         *inclistp;
8 extern char     *includedirs[ ];
9 extern char     *notdotdot[ ];
10 extern boolean show_where_not;
11
12 struct inclist *inc_path(file, include, dot)
13         register char   *file,
14                         *include;
15         boolean dot;
16 {
17         static char     path[ BUFSIZ ];
18         register char           **pp, *p;
19         register struct inclist *ip;
20         struct stat     st;
21         boolean found = FALSE;
22
23         /*
24          * Check all previously found include files for a path that
25          * has already been expanded.
26          */
27         for (ip = inclist; ip->i_file; ip++)
28             if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
29             {
30                 found = TRUE;
31                 break;
32             }
33
34         /*
35          * If the path was surrounded by "", then check the absolute
36          * path provided.
37          */
38         if (!found && dot) {
39                 if (stat(include, &st) == 0) {
40                         ip = newinclude(include, include);
41                         found = TRUE;
42                 }
43                 else if (show_where_not)
44                         log("\tnot in %s\n", include);
45         }
46
47         /*
48          * See if this include file is in the directory of the
49          * file being compiled.
50          */
51         if (!found) {
52                 for (p=file+strlen(file); p>file; p--)
53                         if (*p == '/')
54                                 break;
55                 if (p == file)
56                         strcpy(path, include);
57                 else {
58                         strncpy(path, file, (p-file) + 1);
59                         path[ (p-file) + 1 ] = '\0';
60                         strcpy(path + (p-file) + 1, include);
61                 }
62                 remove_dotdot(path);
63                 if (stat(path, &st) == 0) {
64                         ip = newinclude(path, include);
65                         found = TRUE;
66                 }
67                 else if (show_where_not)
68                         log("\tnot in %s\n", path);
69         }
70
71         /*
72          * Check the include directories specified. (standard include dir
73          * should be at the end.)
74          */
75         if (!found)
76                 for (pp = includedirs; *pp; pp++) {
77                         sprintf(path, "%s/%s", *pp, include);
78                         remove_dotdot(path);
79                         if (stat(path, &st) == 0) {
80                                 ip = newinclude(path, include);
81                                 found = TRUE;
82                                 break;
83                         }
84                         else if (show_where_not)
85                                 log("\tnot in %s\n", path);
86                 }
87
88         if (!found) {
89                 /*
90                  * If we've announced where it's not include it anyway so
91                  * it gets on the dependency list.
92                  */
93                 if (show_where_not)
94                         ip = newinclude(include, include);
95                 else
96                         ip = NULL;
97         }
98         return(ip);
99 }
100
101 /*
102  * Ocaisionally, pathnames are created that look like ../x/../y
103  * Any of the 'x/..' sequences within the name can be eliminated.
104  * (but only if 'x' is not a symbolic link!!)
105  */
106 remove_dotdot(path)
107         char    *path;
108 {
109         register char   *end, *from, *to, **cp;
110         char            *components[ MAXFILES ],
111                         newpath[ BUFSIZ ];
112         boolean         component_copied;
113
114         /*
115          * slice path up into components.
116          */
117         to = newpath;
118         if (*path == '/')
119                 *to++ = '/';
120         *to = '\0';
121         cp = components;
122         for (from=end=path; *end; end++)
123                 if (*end == '/') {
124                         while (*end == '/')
125                                 *end++ = '\0';
126                         if (*from)
127                                 *cp++ = from;
128                         from = end;
129                 }
130         *cp++ = from;
131         *cp = NULL;
132
133         /*
134          * Now copy the path, removing all 'x/..' components.
135          */
136         cp = components;
137         component_copied = FALSE;
138         while(*cp) {
139                 if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
140                         if (issymbolic(newpath, *cp))
141                                 goto dont_remove;
142                         cp++;
143                 } else {
144                 dont_remove:
145                         if (component_copied)
146                                 *to++ = '/';
147                         component_copied = TRUE;
148                         for (from = *cp; *from; )
149                                 *to++ = *from++;
150                         *to = '\0';
151                 }
152                 cp++;
153         }
154         *to++ = '\0';
155
156         /*
157          * copy the reconstituted path back to our pointer.
158          */
159         strcpy(path, newpath);
160 }
161
162 isdot(p)
163         register char   *p;
164 {
165         if(p && *p++ == '.' && *p++ == '\0')
166                 return(TRUE);
167         return(FALSE);
168 }
169
170 isdotdot(p)
171         register char   *p;
172 {
173         if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
174                 return(TRUE);
175         return(FALSE);
176 }
177
178 issymbolic(dir, component)
179         register char   *dir, *component;
180 {
181         struct stat     st;
182         char    buf[ BUFSIZ ], **pp;
183
184         sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
185         for (pp=notdotdot; *pp; pp++)
186                 if (strcmp(*pp, buf) == 0)
187                         return (TRUE);
188         if (lstat(buf, &st) == 0
189         && (st.st_mode & S_IFMT) == S_IFLNK) {
190                 *pp++ = copy(buf);
191                 if (pp >= &notdotdot[ MAXDIRS ])
192                         log_fatal("out of .. dirs, increase MAXDIRS\n");
193                 return(TRUE);
194         }
195         return(FALSE);
196 }
197
198 /*
199  * Add an include file to the list of those included by 'file'.
200  */
201 struct inclist *newinclude(newfile, incstring)
202         register char   *newfile, *incstring;
203 {
204         register struct inclist *ip;
205
206         /*
207          * First, put this file on the global list of include files.
208          */
209         ip = inclistp++;
210         if (inclistp == inclist + MAXFILES - 1)
211                 log_fatal("out of space: increase MAXFILES\n");
212         ip->i_file = copy(newfile);
213         ip->i_included_sym = FALSE;
214         if (incstring == NULL)
215                 ip->i_incstring = ip->i_file;
216         else
217                 ip->i_incstring = copy(incstring);
218
219         return(ip);
220 }
221
222 included_by(ip, newfile)
223         register struct inclist *ip, *newfile;
224 {
225         register i;
226
227         if (ip == NULL)
228                 return;
229         /*
230          * Put this include file (newfile) on the list of files included
231          * by 'file'.  If 'file' is NULL, then it is not an include
232          * file itself (i.e. was probably mentioned on the command line).
233          * If it is already on the list, don't stick it on again.
234          */
235         if (ip->i_list == NULL)
236                 ip->i_list = (struct inclist **)
237                         malloc(sizeof(struct inclist *) * ++ip->i_listlen);
238         else {
239                 for (i=0; i<ip->i_listlen; i++)
240                         if (ip->i_list[ i ] == newfile) {
241                             if (!ip->i_included_sym)
242                             {
243                                 /* only bitch if ip has */
244                                 /* no #include SYMBOL lines  */
245                                 log("%s includes %s more than once!\n",
246                                         ip->i_file, newfile->i_file);
247                                 log("Already have\n");
248                                 for (i=0; i<ip->i_listlen; i++)
249                                         log("\t%s\n", ip->i_list[i]->i_file);
250                             }
251                             return;
252                         }
253                 ip->i_list = (struct inclist **) realloc(ip->i_list,
254                         sizeof(struct inclist *) * ++ip->i_listlen);
255         }
256         ip->i_list[ ip->i_listlen-1 ] = newfile;
257 }
258
259 inc_clean ()
260 {
261         register struct inclist *ip;
262
263         for (ip = inclist; ip < inclistp; ip++) {
264                 ip->i_marked = FALSE;
265         }
266 }
This page took 0.068787 seconds and 5 git commands to generate.