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

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

Temporary backup checkin.

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