source: trunk/src/win32k/fastdep.c@ 1330

Last change on this file since 1330 was 1329, checked in by bird, 26 years ago

Bugfixing in fastdep.c.
Corrected ilib3 and enabled a copy statement in the makefile.

File size: 22.6 KB
Line 
1/*
2 * Fast dependants. (Fast = Quick and Dirty!)
3 *
4 * Copyright (c) 1999 knut st. osmundsen
5 *
6 */
7
8/*******************************************************************************
9* Defined Constants And Macros *
10*******************************************************************************/
11#define INCL_DOSERRORS
12#define INCL_FILEMGR
13
14/*******************************************************************************
15* Header Files *
16*******************************************************************************/
17#include <os2.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21
22
23/*******************************************************************************
24* Structures and Typedefs *
25*******************************************************************************/
26typedef struct _Options
27{
28 const char * pszInclude;
29 const char * pszExclude;
30 BOOL fExcludeAll;
31 const char * pszObjectDir;
32 BOOL fObjRule;
33 BOOL fNoObjectPath;
34 BOOL fSrcWhenObj;
35} OPTIONS, *POPTIONS;
36
37
38/*******************************************************************************
39* Global Variables *
40*******************************************************************************/
41static const char pszDefaultDepFile[] = ".depend";
42
43/*******************************************************************************
44* Internal Functions *
45*******************************************************************************/
46static void syntax(void);
47static int makeDependent(FILE *phDep, const char *pszFilename, POPTIONS pOptions);
48static int getFullIncludename(char *pszFilename, const char *pszInclude);
49
50/* file operations */
51char *filePath(const char *pszFilename, char *pszBuffer);
52char *filePathSlash(const char *pszFilename, char *pszBuffer);
53char *fileName(const char *pszFilename, char *pszBuffer);
54char *fileNameNoExt(const char *pszFilename, char *pszBuffer);
55char *fileExt(const char *pszFilename, char *pszBuffer);
56
57char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer);
58
59
60/**
61 * Main function.
62 * @returns 0 on success.
63 * -n count of failiures.
64 * @param
65 * @param
66 * @equiv
67 * @precond
68 * @methdesc
69 * @result
70 * @time
71 * @sketch
72 * @algo
73 * @remark
74 */
75int main(int argc, char **argv)
76{
77 FILE *phDep;
78 int rc = 0;
79 int argi = 1;
80 const char *pszDepFile = pszDefaultDepFile;
81
82 static char szObjectDir[CCHMAXPATH] = {0};
83 static char szInclude[32768] = ";";
84 static char szExclude[32768] = ";";
85
86 OPTIONS options =
87 {
88 szInclude, /* pszInclude */
89 szExclude, /* pszExclude */
90 FALSE, /* fExcludeAll */
91 szObjectDir, /* pszObjectDir */
92 TRUE, /* fObjRule */
93 FALSE, /* fNoObjectPath */
94 TRUE /* fSrcWhenObj */
95 };
96
97 /* look for depend filename option "-d <filename>" */
98 if (argc >= 3 && strcmp(argv[1], "-d") == 0)
99 {
100 pszDepFile = argv[2];
101 argi = 3;
102 }
103
104 phDep = fopen(pszDepFile, "w");
105 if (phDep != NULL)
106 {
107 while (argi < argc)
108 {
109 if (argv[argi][0] == '-' || argv[argi][0] == '/')
110 {
111 /* parameters */
112 switch (argv[argi][1])
113 {
114 case 'E': /* list of paths. If a file is found in one of these directories the */
115 case 'e': /* filename will be used without the directory path. */
116 /* Eall<[+]|-> ? */
117 if (strlen(&argv[argi][1]) <= 5 && strnicmp(&argv[argi][1], "Eall", 4) == 0)
118 {
119 options.fExcludeAll = argv[argi][5] != '-';
120 break;
121 }
122 /* path or path list */
123 if (strlen(argv[argi]) > 2)
124 strcat(szExclude, &argv[argi][2]);
125 else
126 {
127 strcat(szExclude, argv[argi+1]);
128 argi++;
129 }
130 if (szExclude[strlen(szExclude)-1] != ';')
131 strcat(szExclude, ";");
132 break;
133
134 case 'I': /* optional include path. This has precedence over the INCLUDE environment variable. */
135 case 'i':
136 if (strlen(argv[argi]) > 2)
137 strcat(szInclude, &argv[argi][2]);
138 else
139 {
140 strcat(szInclude, argv[argi+1]);
141 argi++;
142 }
143 if (szInclude[strlen(szInclude)-1] != ';')
144 strcat(szInclude, ";");
145 break;
146
147 case 'n': /* no object path , -N<[+]|-> */
148 case 'N':
149 if (strlen(argv[argi]) <= 1+1+1)
150 options.fNoObjectPath = argv[argi][2] != '-';
151 else
152 {
153 fprintf(stderr, "error: invalid parameter!, '%s'\n", argv[argi]);
154 return -1;
155 }
156 break;
157
158 case 'o': /* object base directory or Obr<[+]|-> */
159 case 'O':
160 if (strlen(&argv[argi][1]) <= 4 && strnicmp(&argv[argi][1], "Obr", 3) == 0)
161 {
162 options.fObjRule = argv[argi][4] != '-';
163 break;
164 }
165
166 /* path */
167 if (strlen(argv[argi]) > 2)
168 strcpy(szObjectDir, argv[argi]+2);
169 else
170 {
171 strcpy(szObjectDir, argv[argi+1]);
172 argi++;
173 }
174 if (szObjectDir[strlen(szObjectDir)-1] != '\\'
175 && szObjectDir[strlen(szObjectDir)-1] != '/'
176 )
177 strcat(szObjectDir, "\\");
178 break;
179
180 case 'h':
181 case 'H':
182 case '?':
183 syntax();
184 return 1;
185
186 default:
187 fprintf(stderr, "error: invalid parameter! '%s'\n", argv[argi]);
188 return -1;
189 }
190
191 }
192 else
193 { /* not a parameter! */
194 ULONG ulRc;
195 FILEFINDBUF3 filebuf = {0};
196 HDIR hDir = HDIR_CREATE;
197 ULONG ulFound = 1;
198
199 ulRc = DosFindFirst(argv[argi], &hDir,
200 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED,
201 &filebuf, sizeof(FILEFINDBUF3), &ulFound, FIL_STANDARD);
202 while (ulRc == NO_ERROR)
203 {
204 char *psz;
205 char szSource[CCHMAXPATH];
206
207 if ((psz = strrchr(argv[argi], '\\')) || (psz = strrchr(argv[argi], '/')))
208 {
209 strncpy(szSource, argv[argi], psz - argv[argi] + 1);
210 szSource[psz - argv[argi] + 1] = '\0';
211 }
212 else
213 szSource[0] = '\0';
214
215 strcat(szSource, filebuf.achName);
216 rc -= makeDependent(phDep, &szSource[0], &options);
217 ulRc = DosFindNext(hDir, &filebuf, sizeof(filebuf), &ulFound);
218 }
219 DosFindClose(hDir);
220 }
221 /* next */
222 argi++;
223 }
224 } else
225 {
226 fprintf(stderr, "error opening outputfile '%s'.\n", pszDepFile);
227 rc = 1;
228 }
229
230 return rc;
231}
232
233
234/**
235 * Displays the syntax description for this util.
236 * @status completely implemented.
237 * @author knut st. osmundsen
238 */
239static void syntax(void)
240{
241 printf(
242 "FastDep v0.1\n"
243 "Quick and dirty dependant scanner. Creates a makefile readable depend file.\n"
244 "\n"
245 "Syntax: FastDep [-d <outputfn>] [-e <excludepath>] [-eall<[+]|->]\n"
246 " [-i <include>] [-n<[+]|->] [-o <objdir>] [-obr<[+]|->]\n"
247 "\n"
248 " -d <outputfn> Output filename. Default: %s\n"
249 " -e excludepath Exclude paths. If a filename is found in any\n"
250 " of these paths only the filename is used, not\n"
251 " the path+filename (which is default).\n"
252 " -eall<[+]|-> -eall+: No path are added to the filename.\n"
253 " -eall-: The filename is appended the include path\n"
254 " was found in.\n"
255 " Default: eall-\n"
256 " -i <include> Additional include paths. INCLUDE is searched after this.\n"
257 " -n<[+]|-> No path for object files in the rules.\n"
258 " -o <objdir> Path were object files are placed. This path replaces the\n"
259 " entire filename path\n"
260 " -obr<[+]|-> -obr+: Object rule.\n"
261 " -obr-: No object rule, rule for source filename is generated.\n"
262 "\n",
263 pszDefaultDepFile
264 );
265}
266
267
268/**
269 * Generates depend info on this file, and fwrites it to phDep.
270 * @returns
271 * @param phDep Pointer to file struct for outfile.
272 * @param pszFilename Pointer to source filename.
273 * @param pOptions Pointer to options struct.
274 * @status completely implemented.
275 * @author knut st. osmundsen
276 */
277static int makeDependent(FILE *phDep, const char *pszFilename, POPTIONS pOptions)
278{
279 FILE *phFile;
280
281 phFile = fopen(pszFilename, "r");
282 if (phFile != NULL)
283 {
284 char szBuffer[4096]; /* max line lenght */
285 int k = strlen(pszFilename) - 1;
286 int l;
287 int iLine;
288
289 /**********************************/
290 /* print file name to depend file */
291 /**********************************/
292 if (pOptions->fObjRule)
293 {
294 char szExt[CCHMAXPATH];
295 char szObj[CCHMAXPATH];
296
297 if (pOptions->fNoObjectPath)
298 fileNameNoExt(pszFilename, szObj);
299 else if (*pOptions->pszObjectDir != '\0')
300 {
301 fileNameNoExt(pszFilename, szExt);
302 strcpy(szObj, pOptions->pszObjectDir);
303 strcat(szObj, szExt);
304 }
305 else
306 {
307 filePathSlash(pszFilename, szObj);
308 fileNameNoExt(pszFilename, szObj + strlen(szObj));
309 }
310
311 fileExt(pszFilename, szExt);
312 if (!stricmp(szExt, "c") || !stricmp(szExt, "sqc")
313 || !stricmp(szExt, "cpp") || !stricmp(szExt, "asm")
314 || !stricmp(szExt, "rc"))
315 {
316 if (!stricmp(szExt, "rc"))
317 strcat(szObj, ".res");
318 else
319 strcat(szObj, ".obj");
320 fprintf(phDep, "%s:", szObj);
321
322 if (pOptions->fSrcWhenObj)
323 fprintf(phDep, " \\\n%6s %s", "", pszFilename);
324 }
325 else
326 fprintf(phDep, "%s:", pszFilename);
327 }
328 else
329 fprintf(phDep, "%s:", pszFilename);
330
331 /*******************/
332 /* find dependants */
333 /*******************/
334 iLine = 0;
335 while (!feof(phFile)) /* line loop */
336 {
337 if (fgets(szBuffer, sizeof(szBuffer), phFile) != NULL)
338 {
339 /* search for #include or RCINCLUDE */
340 int cbLen;
341 int i = 0;
342 iLine++;
343
344 cbLen = strlen(szBuffer);
345 while (i + 9 < cbLen && (szBuffer[i] == ' ' || szBuffer[i] == '\t'))
346 i++;
347
348 /* Found include! */
349 if (strncmp(&szBuffer[i], "#include", 8) == 0 || strncmp(&szBuffer[i], "RCINCLUDE", 9) == 0)
350 {
351 int f = 0;
352
353 /* extract info between "" or <> */
354 while (i < cbLen && !(f = (szBuffer[i] == '"' || szBuffer[i] == '<')))
355 i++;
356 i++; /* skip '"' or '<' */
357 if (f)
358 {
359 int j;
360 /* find end */
361 j = f = 0;
362 while (i + j < cbLen && j < CCHMAXPATH &&
363 !(f = (szBuffer[i+j] == '"' || szBuffer[i+j] == '>')))
364 j++;
365
366 if (f)
367 {
368 char szFullname[CCHMAXPATH];
369 char *psz;
370
371 /* copy filename */
372 strncpy(szFullname, &szBuffer[i], j);
373 szFullname[j] = '\0'; /* ensure terminatition. */
374
375 /* find include file! */
376 psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer);
377 if (psz == NULL)
378 psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer);
379
380 if (psz != NULL)
381 {
382 char szBuffer2[CCHMAXPATH];
383 if (pOptions->fExcludeAll ||
384 pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2) != NULL
385 )
386 strcpy(szBuffer, szFullname);
387 fprintf(phDep, " \\\n%6.s %s", "", szBuffer);
388 }
389 else
390 fprintf(stderr, "%s(%d): warning include file '%s' not found!\n",
391 pszFilename, iLine, szFullname);
392 }
393 }
394 }
395 }
396 /*
397 else
398 break;
399 */
400 } /*while*/
401 fputs("\n", phDep);
402 fclose(phFile);
403 }
404 else
405 {
406 fprintf(stderr, "failed to open '%s'\n", pszFilename);
407 return -1;
408 }
409
410 return 0;
411}
412
413
414
415
416/**
417 * Gets the fullpath include-filename.
418 * @returns 0 on success, -1 on error.
419 * @param pszFilename Input: Pointer to filename to be found, and buffer for output.
420 * Ouput: Buffer now contains fullpath include-filename.
421 * @param pszInclude Additional includepath.
422 */
423static int getFullIncludename(char *pszFilename, const char *pszInclude)
424{
425 const char *pszEnvInclude;
426 const char *psz;
427
428 pszEnvInclude = getenv("INCLUDE");
429 if ((pszEnvInclude == NULL && (pszInclude == NULL || strlen(pszInclude) == 0)) || strlen(pszFilename) == 0)
430 return -1;
431
432 psz = "";
433 while (psz != NULL && psz != '\0')
434 {
435 const char *pszNext;
436 int cbLen;
437 char szFileTmpIn[260];
438 FILEFINDBUF3 filebuf;
439 ULONG ulRc;
440 HDIR hDir = HDIR_CREATE;
441 ULONG ulFound = 1;
442
443 /* get addr of next ';' or '\0' */
444 pszNext = strchr(psz, ';');
445 if (pszNext == NULL)
446 pszNext = psz + strlen(psz);
447
448 /* add a '\\' and the pszFilename string to the include path part. */
449 cbLen = (int)pszNext - (int)psz;
450 if (cbLen > 0)
451 {
452 strncpy(szFileTmpIn, psz, (int)pszNext - (int)psz);
453 if (szFileTmpIn[cbLen - 1] != '\\' && szFileTmpIn[cbLen - 1] != '/')
454 szFileTmpIn[cbLen++] = '\\';
455 }
456 strcpy(&szFileTmpIn[cbLen], pszFilename);
457
458
459 /**************************/
460 /* check if file is found */
461 /**************************/
462 ulRc = DosFindFirst(&szFileTmpIn[0], &hDir,
463 FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED,
464 &filebuf, sizeof(FILEFINDBUF3), &ulFound, FIL_STANDARD);
465 if (ulRc == NO_ERROR)
466 {
467 strcpy(pszFilename, szFileTmpIn);
468 DosFindClose(hDir);
469 return 0;
470 }
471
472 /* next */
473 if (*pszNext == ';' && pszNext[1] != '\0')
474 psz = pszNext + 1;
475 else
476 {
477 psz = pszInclude;
478 pszInclude = NULL;
479
480 if (psz == NULL)
481 {
482 psz = pszEnvInclude;
483 pszEnvInclude = NULL;
484 }
485 }
486 }
487
488 return -1;
489}
490
491
492
493/**
494 * Copies the path part (excluding the slash) into pszBuffer and returns
495 * a pointer to the buffer.
496 * If no path is found "" is returned.
497 * @returns Pointer to pszBuffer with path.
498 * @param pszFilename Pointer to readonly filename.
499 * @param pszBuffer Pointer to output Buffer.
500 * @status completely implemented.
501 * @author knut st. osmundsen
502 */
503char *filePath(const char *pszFilename, char *pszBuffer)
504{
505 char *psz = strrchr(pszFilename, '\\');
506 if (psz == NULL)
507 psz = strrchr(pszFilename, '/');
508
509 if (psz == NULL)
510 *pszBuffer = '\0';
511 else
512 {
513 strncpy(pszBuffer, pszFilename, psz - pszFilename - 1);
514 pszBuffer[psz - pszFilename - 1] = '\0';
515 }
516
517 return pszBuffer;
518}
519
520
521/**
522 * Copies the path part including the slash into pszBuffer and returns
523 * a pointer to the buffer.
524 * If no path is found "" is returned.
525 * @returns Pointer to pszBuffer with path.
526 * @param pszFilename Pointer to readonly filename.
527 * @param pszBuffer Pointer to output Buffer.
528 * @status completely implemented.
529 * @author knut st. osmundsen
530 */
531char *filePathSlash(const char *pszFilename, char *pszBuffer)
532{
533 char *psz = strrchr(pszFilename, '\\');
534 if (psz == NULL)
535 psz = strrchr(pszFilename, '/');
536
537 if (psz == NULL)
538 *pszBuffer = '\0';
539 else
540 {
541 strncpy(pszBuffer, pszFilename, psz - pszFilename + 1);
542 pszBuffer[psz - pszFilename + 1] = '\0';
543 }
544
545 return pszBuffer;
546}
547
548
549/**
550 * Copies the path name (with extention) into pszBuffer and returns
551 * a pointer to the buffer.
552 * If no path is found "" is returned.
553 * @returns Pointer to pszBuffer with path.
554 * @param pszFilename Pointer to readonly filename.
555 * @param pszBuffer Pointer to output Buffer.
556 * @status completely implemented.
557 * @author knut st. osmundsen
558 */
559char *fileName(const char *pszFilename, char *pszBuffer)
560{
561 char *psz = strrchr(pszFilename, '\\');
562 if (psz == NULL)
563 psz = strrchr(pszFilename, '/');
564
565 strcpy(pszBuffer, psz == NULL ? pszFilename : psz + 1);
566
567 return pszBuffer;
568}
569
570
571/**
572 * Copies the name part with out extention into pszBuffer and returns
573 * a pointer to the buffer.
574 * If no name is found "" is returned.
575 * @returns Pointer to pszBuffer with path.
576 * @param pszFilename Pointer to readonly filename.
577 * @param pszBuffer Pointer to output Buffer.
578 * @status completely implemented.
579 * @author knut st. osmundsen
580 */
581char *fileNameNoExt(const char *pszFilename, char *pszBuffer)
582{
583 char *psz = strrchr(pszFilename, '\\');
584 if (psz == NULL)
585 psz = strrchr(pszFilename, '/');
586
587 strcpy(pszBuffer, psz == NULL ? pszFilename : psz + 1);
588
589 psz = strrchr(pszBuffer, '.');
590 if (psz > pszBuffer) /* an extetion on it's own (.depend) is a filename not an extetion! */
591 *psz = '\0';
592
593 return pszBuffer;
594}
595
596
597/**
598 * Copies the extention part into pszBuffer and returns
599 * a pointer to the buffer.
600 * If no extention is found "" is returned.
601 * The dot ('.') is not included!
602 * @returns Pointer to pszBuffer with path.
603 * @param pszFilename Pointer to readonly filename.
604 * @param pszBuffer Pointer to output Buffer.
605 * @status completely implemented.
606 * @author knut st. osmundsen
607 */
608char *fileExt(const char *pszFilename, char *pszBuffer)
609{
610 char *psz = strrchr(pszFilename, '.');
611 if (psz != NULL)
612 {
613 if (strchr(psz, '\\') != NULL || strchr(psz, '/') != NULL)
614 *pszBuffer = '\0';
615 else
616 strcpy(pszBuffer, psz + 1);
617 }
618 else
619 *pszBuffer = '\0';
620
621 return pszBuffer;
622}
623
624
625
626
627/**
628 * Finds a filename in a specified pathlist.
629 * @returns Pointer to a filename consiting of the path part + the given filename.
630 * (pointer into pszBuffer)
631 * NULL if file is not found. ("" in buffer)
632 * @param pszPathList Path list to search for filename.
633 * @parma pszFilename Filename to find.
634 * @parma pszBuffer Ouput Buffer.
635 * @status completely implemented.
636 * @author knut st. osmundsen
637 */
638char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer)
639{
640 const char *psz = pszPathList;
641 const char *pszNext = NULL;
642
643 *pszBuffer = '\0';
644
645 if (pszPathList == NULL)
646 return NULL;
647
648 while (*psz != '\0')
649 {
650 /* find end of this path */
651 pszNext = strchr(psz, ';');
652 if (pszNext == NULL)
653 pszNext = psz + strlen(psz);
654
655 if (pszNext - psz > 0)
656 {
657 HDIR hDir = HDIR_CREATE;
658 ULONG cFiles = 1UL;
659 FILEFINDBUF3 FileFindBuf;
660 APIRET rc;
661 char szFile[CCHMAXPATH];
662
663 /* make search statment */
664 strncpy(szFile, psz, pszNext - psz);
665 szFile[pszNext - psz] = '\0';
666 if (szFile[pszNext - psz - 1] != '\\' && szFile[pszNext - psz - 1] != '/')
667 strcpy(&szFile[pszNext - psz], "\\");
668 strcat(szFile, pszFilename);
669
670 /* search for file */
671 rc = DosFindFirst(szFile, &hDir, FILE_NORMAL, &FileFindBuf, sizeof(FileFindBuf),
672 &cFiles, FIL_STANDARD);
673 DosFindClose(hDir);
674 if (rc == NO_ERROR)
675 {
676 strncpy(pszBuffer, psz, pszNext - psz);
677 pszBuffer[pszNext - psz] = '\0';
678 if (pszBuffer[pszNext - psz - 1] != '\\' && pszBuffer[pszNext - psz - 1] != '/')
679 strcpy(&pszBuffer[pszNext - psz], "\\");
680 strcat(pszBuffer, pszFilename);
681 break;
682 }
683 }
684
685 /* next */
686 if (*pszNext != ';')
687 break;
688 psz = pszNext + 1;
689 }
690
691 return *pszBuffer == '\0' ? NULL : pszBuffer;
692}
693
Note: See TracBrowser for help on using the repository browser.