Merge branch 'master' of ssh://opencfd@repo.or.cz/srv/git/OpenFOAM-1.5.x
[OpenFOAM-1.5.x.git] / wmake / src / wmkdep.l
blobba8554ef2c6a7e71f7331d5d25636f5c271309c4
1 %{
2 /*---------------------------------------------------------------------------*\
3  =========                   |
4  \\      /   F ield          | OpenFOAM: The Open Source CFD Toolbox
5   \\    /    O peration      |
6    \\  /     A nd            | Copyright (C) 1991-2008 OpenCFD Ltd.
7     \\/      M anipulation   |
8 ------------------------------------------------------------------------------
9 License
10     This file is part of OpenFOAM.
12     OpenFOAM is free software; you can redistribute it and/or modify it
13     under the terms of the GNU General Public License as published by the
14     Free Software Foundation; either version 2 of the License, or (at your
15     option) any later version.
17     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
18     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20     for more details.
22     You should have received a copy of the GNU General Public License
23     along with OpenFOAM; if not, write to the Free Software Foundation,
24     Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 Application
27     wmkdep
29 Description
30      A fast dependency list generator which emulates the behaviour and
31      output of cpp -M. However, the output contains no duplications and 
32      is ~40% faster than cpp.
34      The algorithm uses flex to scan for includes and searches the files
35      found.  Each file is entererd into a hash table so that files are
36      scaned only once.  This is why this program is faster than cpp.
38 Usage
39     wmkdep [ -Idirectory ... -Idirectory] filename
41 \*---------------------------------------------------------------------------*/
43 #define FILE_STACK_SIZE 300
44 #define HASH_TABLE_SIZE 500
46 #include <stdlib.h>
47 #include <string.h>
48 #include <sys/types.h>
49 #include <dirent.h>
51 void nextFile(const char* fileName);
52 void importFile(const char* fileName);
53 void importDirectory(const char* dirName);
55 #   undef yywrap        /* sometimes a macro by default */
59 %x CMNT CFNAME SCFNAME JFNAME FFNAME
62 "//".*\n                  ;            /* remove c++ style one line comments */
64 "/*"                      BEGIN(CMNT);    /* start removing c style comment */
65 <CMNT>.|\n                ;
66 <CMNT>"*/"                BEGIN(INITIAL); /* end removing c style comment */
68 ^[ \t]*#[ \t]*include[ \t]+\"   BEGIN(CFNAME);  /* c-file name */
69 <CFNAME>[^"\n ]*        { BEGIN(INITIAL); nextFile(yytext); } /*"*/
71 ^[ \t]*import[ \t]+       BEGIN(JFNAME);  /* java-file name */
72 <JFNAME>java.*;           BEGIN(INITIAL);
73 <JFNAME>org.*;            BEGIN(INITIAL);
74 <JFNAME>com.*;            BEGIN(INITIAL);
75 <JFNAME>sunw.*;           BEGIN(INITIAL);
76 <JFNAME>sun.*;            BEGIN(INITIAL);
77 <JFNAME>launcher.*;       BEGIN(INITIAL);
78 <JFNAME>[^"\n*]*;       { BEGIN(INITIAL); importFile(yytext); } /*"*/
79 <JFNAME>[^"\n]*\*;      { BEGIN(INITIAL); importDirectory(yytext); } /*"*/
81 "      "include[ \t]+\'   BEGIN(FFNAME);  /* FORTRAN-file name */
82 <FFNAME>[^']*           { BEGIN(INITIAL); nextFile(yytext); } /*'*/
84 .|\t|\n                   ;
89 int nDirectories;
90 char** directories;
91 char* sourceFile = NULL;
92 char* sourceExt = NULL;
93 char* objectFile = NULL;
94 char* classFile = NULL;
95 char* depFile = NULL;
97 int main(int argc, char* argv[])
99     char *dotPtr, *slashPtr;
100     int i;
102     if (argc == 1)
103     {
104         fprintf(stderr,"input file not supplied\n");
105         exit(1);
106     }
108     sourceFile = (char*)malloc(strlen(argv[argc-1]) + 1);
109     strcpy(sourceFile, argv[argc-1]);
110     fprintf(stderr,"Making dependency list for source file %s\n", sourceFile);
111     
112     
113     /* Get list of -I directories. */
114     nDirectories = 0;
116     for (i = 1; i < argc; i++)
117     {
118         if (strncmp(argv[i], "-I", 2) == 0)
119         {
120             nDirectories++;
121         }
122     }
124     directories = (char**)malloc(sizeof(char*)*nDirectories);
126     nDirectories = 0;
128     for (i = 1; i < argc; i++)
129     {
130         if (strncmp(argv[i], "-I", 2) == 0)
131         {
132             directories[nDirectories++] = strdup(argv[i] + 2);
133         }
134     }
138     if ((dotPtr = strrchr(sourceFile, '.')) == NULL)
139     {
140         fprintf
141         (
142             stderr,
143             "Cannot find extension in source file name %s\n",
144             sourceFile
145         );
146         exit(1);
147     }
149     if ((slashPtr = strrchr(sourceFile, '/')) == NULL)
150     {
151         slashPtr = sourceFile;
152     }
153     else
154     {
155         slashPtr++;
156     }
158     sourceExt = (char*)malloc(strlen(sourceFile));
159     sourceExt[0] = 0;
160     strncat
161     (
162         sourceExt,
163         dotPtr+1,
164         (&sourceFile[strlen(sourceFile) - 1] - dotPtr)/sizeof(char)
165     );
167     /* initialise depFile to zero and use strncat rather than strncpy
168        because there is a bug in the SGI strncat that if 0 preceeds the .
169        it inserts a space */
170     depFile = (char*)malloc(strlen(sourceFile) + 3);
171     depFile[0] = 0;
172     strncat(depFile, sourceFile, (dotPtr - sourceFile)/sizeof(char));
173     strcat(depFile, ".dep");
175     if (strcmp(sourceExt, "java") == 0)
176     {
177         classFile = (char*)malloc(strlen(sourceFile) + 17);
178         strcpy(classFile, "$(CLASSES_DIR)/");
179         strncat(classFile, sourceFile, (dotPtr - sourceFile)/sizeof(char));
180         strcat(classFile, ".class");
182         printf("%s: %s\n", classFile, depFile);
183     }
184     else
185     {
186         objectFile = (char*)malloc(strlen(sourceFile) + 16);
187         strcpy(objectFile, "$(OBJECTS_DIR)/");
188         strncat(objectFile, slashPtr, (dotPtr - slashPtr)/sizeof(char));
189         strcat(objectFile, ".o");
191         printf("%s: %s\n", objectFile, depFile);
192     }
194     nextFile(sourceFile);
195     yylex();
198     for (i = 0; i < nDirectories; i++)
199     {
200         free(directories[i]);
201     }
202     free(directories);
204     free(sourceFile);
205     free(sourceExt);
206     free(objectFile);
207     free(classFile);
208     free(depFile);
210     return 0;
214 int currentBuffer = 0;                     /* Buffer pointer stack counter */
215 YY_BUFFER_STATE buffers[FILE_STACK_SIZE];  /* Buffer pointer stack */
217 /* file name entry in hash table */
219 struct FileName
221     char* name;
222     struct FileName* next;
225 struct FileName* fileHashTable[HASH_TABLE_SIZE];   /* File hash table */
226 struct FileName* dirHashTable[HASH_TABLE_SIZE];    /* Directory hash table */
229 /* lookup name in hash table, if not found insert in table */
231 int lookUp(struct FileName** hashTable, const char* p)
233     int ii = 0;
234     struct FileName* n;
235     struct FileName* nn;
237     /* hash */
238     const char* pp = p;
239     while (*pp) ii = ii<<1 ^ *pp++;
240     if (ii < 0) ii = -ii;
241     ii %= HASH_TABLE_SIZE;
243     /* search */
244     for (n=hashTable[ii]; n; n=n->next)
245     {
246         if (strcmp(p, n->name) == 0)
247         {
248             /* entry found so return true */
249             return 1;
250         }
251     }
253     /* insert */
254     nn = (struct FileName*)malloc(sizeof(struct FileName));
255     nn->name = (char*)malloc(strlen(p)+1);
256     strcpy(nn->name, p);
257     nn->next = hashTable[ii];
258     hashTable[ii] = nn;
260     /* entry not found, and therefore added. return false */
261     return 0;
266 /* Add a directory name to the file name */
268 char* addDirectoryName(const char* directoryName, const char* fileName)
270     char* pathName;
271     pathName = (char*)malloc(strlen(directoryName) + strlen(fileName) + 2);
273     strcpy(pathName, directoryName);
275     if (directoryName[strlen(directoryName)-1] != '/')
276     {
277         strcat(pathName, "/");
278     }
280     strcat(pathName, fileName);
282     return pathName;
286 /* open a file and create buffer and put on stack stack */
288 void nextFile(const char* fileName)
290     int d;
291     char* pathName;
293     if (lookUp(fileHashTable, fileName)) return;
295     if (currentBuffer >= FILE_STACK_SIZE)
296     {
297         fprintf
298         (
299             stderr,
300             "depth of file search exceeds stack size %d "
301             "while opening %s for file %s\n",
302             FILE_STACK_SIZE, fileName, sourceFile
303         );
304         exit(1);
305     }
307     /* Pointer to new file which is set if the file is successfully opened */
308     FILE* newyyin = NULL;
310     if (!(newyyin = fopen(fileName, "r")))
311     {
312         for (d=0; d<nDirectories; d++)
313         {
314             pathName = addDirectoryName(directories[d], fileName);
316             if ((newyyin = fopen(pathName, "r")))
317             { 
318                 printf("%s: %s\n", depFile, pathName);
319                 buffers[currentBuffer++] = YY_CURRENT_BUFFER;
320                 yy_switch_to_buffer(yy_create_buffer(newyyin, YY_BUF_SIZE));
322                 free(pathName);
324                 return;
325             }
327             free(pathName);
328         }
330         fprintf
331         (
332             stderr, 
333             "could not open file %s for source file %s\n", 
334             fileName, sourceFile
335         );
337         fflush(stdout);
338     }
339     else
340     {
341         printf("%s: %s\n", depFile, fileName);
342         fflush(stdout);
344         buffers[currentBuffer++] = YY_CURRENT_BUFFER;
345         yy_switch_to_buffer(yy_create_buffer(newyyin, YY_BUF_SIZE));
346     }
350 void dotToSlash(char* fileName)
352     int i, len;
354     len = strlen(fileName);
356     for (i=0; i<len; i++)
357     {
358         if (fileName[i] == '.') fileName[i] = '/';
359     }
363 void importFile(const char* fileName)
365     char* javaFileName;
366     int fileNameLen;
368     fileNameLen = strlen(fileName);
369     javaFileName = (char*)malloc(fileNameLen + 6);
370     javaFileName[0] = 0;
371     strncat(javaFileName, fileName, fileNameLen - 1);
372     dotToSlash(javaFileName);
373     strcat(javaFileName, ".java");
375     nextFile(javaFileName);
377     free(javaFileName);
381 void importDirectory(const char* dirName)
383     int dirNameLen;
384     char *uDirName, *path;
385     DIR *source;
386     struct dirent *list;
388     if (lookUp(dirHashTable, dirName)) return;
390     dirNameLen = strlen(dirName);
391     uDirName = strdup(dirName);
392     dotToSlash(uDirName);
393     uDirName[dirNameLen-2] = 0;
395     if ((source = opendir(uDirName)) == NULL)
396     {
397         fprintf
398         (
399             stderr, 
400             "could not open directory %s\n", 
401             uDirName
402         );
403         free(uDirName);
405         return;
406     }
407     else
408     {
409         /* Read and parse all the entries in the directory */
410         while ((list = readdir(source)) != NULL)
411         {
412             if
413             (
414                 strstr(list->d_name, ".java")
415              && !strstr(list->d_name, ".java~")
416             )
417             {
418                 path = addDirectoryName(uDirName, list->d_name);
419                 nextFile(path);
420                 free(path);
421             }
422         }
424         closedir(source);
425         free(uDirName);
426     }
430 /* The lexer calls yywrap to handle EOF conditions */
432 int yywrap()
434     /* Close the file for the buffer which has just reached EOF */
435     /* This causes strange problems
436     fclose(yyin);
437     yyin = 0;
438     */
440     /* Delete the buffer */
441     yy_delete_buffer(YY_CURRENT_BUFFER);
443     /* Set buffer counter to previous buffer */
444     currentBuffer--;
446     if (currentBuffer >= 0) /* if buffer counter refers to a valid file */
447     {
448         /* reset input buffer to the previous buffer on the stack */
449         yy_switch_to_buffer(buffers[currentBuffer]);
451         /* Return to the normal state for the previous buffer on the stack */
452         BEGIN(INITIAL);
454         /* return 0 to inform lex to continue reading */
455         return 0;
456     }
457     else                 /* else there are no more buffers on the stack */
458     {
459         /* return 1 to inform lex finish now that all buffers have been read */
460         return 1;
461     }
465 /*****************************************************************************/