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

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

Reworked FastDep.c.
Added .cvsignore.

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