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

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

Some bugsfixes - Yield is disabled.
Added parameters.
Correcte moduleheaders.
Introduced a new base class for virtual lx modules + some elf sketches.

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