xref: /aoo42x/main/soltools/mkdepend/main.c (revision c56f8ff5)
1 /* $XConsortium: main.c,v 1.84 94/11/30 16:10:44 kaleb Exp $ */
2 /* $XFree86: xc/config/makedepend/main.c,v 3.4 1995/07/15 14:53:49 dawes Exp $ */
3 /*
4 
5 Copyright (c) 1993, 1994  X Consortium
6 
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
13 
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16 
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
27 
28 */
29 
30 #if defined(FREEBSD) || defined(MACOSX)
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #endif
34 
35 #ifdef _MSC_VER	    /* Define ssize_t */
36 
37 #if !defined(_W64)
38 #if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300
39 #define _W64 __w64
40 #else
41 #define _W64
42 #endif
43 #endif
44 
45 #ifdef  _WIN64
46 typedef __int64    ssize_t;
47 #else
48 typedef _W64 int   ssize_t;
49 #endif
50 
51 #endif
52 
53 #include "def.h"
54 #include <string.h>
55 #ifdef hpux
56 #define sigvec sigvector
57 #endif /* hpux */
58 
59 #ifdef X_POSIX_C_SOURCE
60 #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
61 #include <signal.h>
62 #undef _POSIX_C_SOURCE
63 #else
64 #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
65 #include <signal.h>
66 #else
67 #define _POSIX_SOURCE
68 #include <signal.h>
69 #undef _POSIX_SOURCE
70 #endif
71 #endif
72 
73 #include <stdarg.h>
74 
75 #ifdef MINIX
76 #define USE_CHMOD	1
77 #endif
78 
79 #ifdef DEBUG
80 int	_debugmask;
81 #endif
82 
83 char *ProgramName;
84 
85 #define OBJSUFFIX ".obj"
86 #define	INCLUDEDIR "."
87 
88 char	*directives[] = {
89 	"if",
90 	"ifdef",
91 	"ifndef",
92 	"else",
93 	"endif",
94 	"define",
95 	"undef",
96 	"include",
97 	"line",
98 	"pragma",
99 	"error",
100 	"ident",
101 	"sccs",
102 	"elif",
103 	"eject",
104 	NULL
105 };
106 
107 #define MAKEDEPEND
108 #include "imakemdep.h"	/* from config sources */
109 #undef MAKEDEPEND
110 
111 /*******   function declarations ********/
112 /*******   added by -Wall project *******/
113 void redirect(char * line, char * makefile );
114 
115 struct	inclist inclist[ MAXFILES ],
116 		*inclistp = inclist;
117 
118 struct symhash *maininclist = NULL;
119 
120 char	*filelist[ MAXFILES ];
121 char	*includedirs[ MAXDIRS + 1 ];
122 char	*notdotdot[ MAXDIRS ];
123 char	*objprefix = "";
124 char	*objsuffix = OBJSUFFIX;
125 char	*startat = "# DO NOT DELETE";
126 int	width = 78;
127 boolean	append = FALSE;
128 boolean	printed = FALSE;
129 boolean	verbose = FALSE;
130 boolean	show_where_not = FALSE;
131 boolean warn_multiple = FALSE;	/* Warn on multiple includes of same file */
132 
133 static
134 #ifdef SIGNALRETURNSINT
135 int
136 #else
137 void
138 #endif
139 catch (sig)
140     int sig;
141 {
142 	fflush (stdout);
143 	abort();
144 	fatalerr ("got signal %d\n", sig);
145 }
146 
147 #if defined(USG) || (defined(i386) && defined(SYSV)) || defined(WIN32) || defined(OS2) || defined(Lynx_22)
148 #define USGISH
149 #endif
150 
151 #ifndef USGISH
152 #ifndef _POSIX_SOURCE
153 #define sigaction sigvec
154 #define sa_handler sv_handler
155 #define sa_mask sv_mask
156 #define sa_flags sv_flags
157 #endif
158 struct sigaction sig_act;
159 #endif /* USGISH */
160 
161 boolean	native_win_slashes = FALSE;
162 
163 int main(argc, argv)
164 	int	argc;
165 	char	**argv;
166 {
167 	register char	**fp = filelist;
168 	register char	**incp = includedirs;
169 	register char	*p;
170 	register struct inclist	*ip;
171 	char	*makefile = NULL;
172 	struct filepointer	*filecontent;
173 	struct pair *psymp = predefs;
174 	char *endmarker = NULL;
175 	char *defincdir = NULL;
176     struct IncludesCollection* incCollection;
177 
178 	ProgramName = argv[0];
179 
180 	while (psymp->p_name)
181 	{
182 	    hash_define(psymp->p_name, psymp->p_value, &maininclist);
183 	    psymp++;
184 	}
185 	if (argc == 2 && argv[1][0] == '@') {
186 	    struct stat ast;
187 	    int afd;
188 	    char *args;
189 	    char **nargv;
190 	    int nargc;
191 	    char quotechar = '\0';
192 
193 	    nargc = 1;
194 	    if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
195 		fatalerr("cannot open \"%s\"\n", argv[1]+1);
196 	    fstat(afd, &ast);
197 	    args = (char *)malloc(ast.st_size + 1);
198 	    if ((ast.st_size = read(afd, args, (size_t) ast.st_size)) < 0)
199 		fatalerr("failed to read %s\n", argv[1]+1);
200 	    args[ast.st_size] = '\0';
201 	    close(afd);
202 	    for (p = args; *p; p++) {
203 		if (quotechar) {
204 		    if (quotechar == '\\' ||
205 			(*p == quotechar && p[-1] != '\\'))
206 			quotechar = '\0';
207 		    continue;
208 		}
209 		switch (*p) {
210 		case '\\':
211 		case '"':
212 		case '\'':
213 		    quotechar = *p;
214 		    break;
215 		case ' ':
216 		case '\n':
217 		    *p = '\0';
218 		    if (p > args && p[-1])
219 			nargc++;
220 		    break;
221 		}
222 	    }
223 	    if (p[-1])
224 		nargc++;
225 	    nargv = (char **)malloc(nargc * sizeof(char *));
226 	    nargv[0] = argv[0];
227 	    argc = 1;
228 	    for (p = args; argc < nargc; p += strlen(p) + 1)
229 		if (*p) nargv[argc++] = p;
230 	    argv = nargv;
231 	}
232 	for(argc--, argv++; argc; argc--, argv++) {
233 	    	/* if looking for endmarker then check before parsing */
234 		if (endmarker && strcmp (endmarker, *argv) == 0) {
235 		    endmarker = NULL;
236 		    continue;
237 		}
238 		if (**argv != '-') {
239 			/* treat +thing as an option for C++ */
240 			if (endmarker && **argv == '+')
241 				continue;
242 			*fp++ = argv[0];
243 			continue;
244 		}
245 		switch(argv[0][1]) {
246 		case '-':
247 			endmarker = &argv[0][2];
248 			if (endmarker[0] == '\0') endmarker = "--";
249 			break;
250 		case 'D':
251 			if (argv[0][2] == '\0') {
252 				argv++;
253 				argc--;
254 			}
255 			for (p=argv[0] + 2; *p ; p++)
256 				if (*p == '=') {
257 					*p = ' ';
258 					break;
259 				}
260 			define(argv[0] + 2, &maininclist);
261 			break;
262 		case 'I':
263 			if (incp >= includedirs + MAXDIRS)
264 			    fatalerr("Too many -I flags.\n");
265 			*incp++ = argv[0]+2;
266 			if (**(incp-1) == '\0') {
267 				*(incp-1) = *(++argv);
268 				argc--;
269 			}
270 			break;
271 		case 'Y':
272 			defincdir = argv[0]+2;
273 			break;
274 		/* do not use if endmarker processing */
275 		case 'a':
276 			if (endmarker) break;
277 			append = TRUE;
278 			break;
279 		case 'w':
280 			if (endmarker) break;
281 			if (argv[0][2] == '\0') {
282 				argv++;
283 				argc--;
284 				width = atoi(argv[0]);
285 			} else
286 				width = atoi(argv[0]+2);
287 			break;
288 		case 'n':
289             // Use "-n" switch to generate dependencies with windows-native slash style
290             native_win_slashes = TRUE;
291 			break;
292 		case 'o':
293 			if (endmarker) break;
294 			if (argv[0][2] == '\0') {
295 				argv++;
296 				argc--;
297 				objsuffix = argv[0];
298 			} else
299 				objsuffix = argv[0]+2;
300 			break;
301 		case 'p':
302 			if (endmarker) break;
303 			if (argv[0][2] == '\0') {
304 				argv++;
305 				argc--;
306 				objprefix = argv[0];
307 			} else
308 				objprefix = argv[0]+2;
309 			break;
310 		case 'v':
311 			if (endmarker) break;
312 			verbose = TRUE;
313 #ifdef DEBUG
314 			if (argv[0][2])
315 				_debugmask = atoi(argv[0]+2);
316 #endif
317 			break;
318 		case 's':
319 			if (endmarker) break;
320 			startat = argv[0]+2;
321 			if (*startat == '\0') {
322 				startat = *(++argv);
323 				argc--;
324 			}
325 			if (*startat != '#')
326 				fatalerr("-s flag's value should start %s\n",
327 					"with '#'.");
328 			break;
329 		case 'f':
330 			if (endmarker) break;
331 			makefile = argv[0]+2;
332 			if (*makefile == '\0') {
333 				makefile = *(++argv);
334 				argc--;
335 			}
336 			break;
337 
338 		case 'm':
339 			warn_multiple = TRUE;
340 			break;
341 
342 		/* Ignore -O, -g so we can just pass ${CFLAGS} to
343 		   makedepend
344 		 */
345 		case 'O':
346 		case 'g':
347 			break;
348 		default:
349 			if (endmarker) break;
350 	/*		fatalerr("unknown opt = %s\n", argv[0]); */
351 			warning("ignoring option %s\n", argv[0]);
352 		}
353 	}
354 
355     convert_slashes(objprefix);
356     objprefix = append_slash(objprefix);
357 
358     if (!defincdir) {
359 #ifdef PREINCDIR
360 	    if (incp >= includedirs + MAXDIRS)
361 		fatalerr("Too many -I flags.\n");
362 	    *incp++ = PREINCDIR;
363 #endif
364 	    if (incp >= includedirs + MAXDIRS)
365 		fatalerr("Too many -I flags.\n");
366 	    *incp++ = INCLUDEDIR;
367 #ifdef POSTINCDIR
368 	    if (incp >= includedirs + MAXDIRS)
369 		fatalerr("Too many -I flags.\n");
370 	    *incp++ = POSTINCDIR;
371 #endif
372 	} else if (*defincdir) {
373 	    if (incp >= includedirs + MAXDIRS)
374 		fatalerr("Too many -I flags.\n");
375 	    *incp++ = defincdir;
376 	}
377 
378 	redirect(startat, makefile);
379 
380 	/*
381 	 * catch signals.
382 	 */
383 #ifdef USGISH
384 /*  should really reset SIGINT to SIG_IGN if it was.  */
385 #ifdef SIGHUP
386 	signal (SIGHUP, catch);
387 #endif
388 	signal (SIGINT, catch);
389 #ifdef SIGQUIT
390 	signal (SIGQUIT, catch);
391 #endif
392 	signal (SIGILL, catch);
393 #ifdef SIGBUS
394 	signal (SIGBUS, catch);
395 #endif
396 	signal (SIGSEGV, catch);
397 #ifdef SIGSYS
398 	signal (SIGSYS, catch);
399 #endif
400 	signal (SIGFPE, catch);
401 #else
402 	sig_act.sa_handler = catch;
403 #ifdef _POSIX_SOURCE
404 	sigemptyset(&sig_act.sa_mask);
405 	sigaddset(&sig_act.sa_mask, SIGINT);
406 	sigaddset(&sig_act.sa_mask, SIGQUIT);
407 #ifdef SIGBUS
408 	sigaddset(&sig_act.sa_mask, SIGBUS);
409 #endif
410 	sigaddset(&sig_act.sa_mask, SIGILL);
411 	sigaddset(&sig_act.sa_mask, SIGSEGV);
412 	sigaddset(&sig_act.sa_mask, SIGHUP);
413 	sigaddset(&sig_act.sa_mask, SIGPIPE);
414 #ifdef SIGSYS
415 	sigaddset(&sig_act.sa_mask, SIGSYS);
416 #endif
417 #else
418 	sig_act.sa_mask = ((1<<(SIGINT -1))
419 			   |(1<<(SIGQUIT-1))
420 #ifdef SIGBUS
421 			   |(1<<(SIGBUS-1))
422 #endif
423 			   |(1<<(SIGILL-1))
424 			   |(1<<(SIGSEGV-1))
425 			   |(1<<(SIGHUP-1))
426 			   |(1<<(SIGPIPE-1))
427 #ifdef SIGSYS
428 			   |(1<<(SIGSYS-1))
429 #endif
430 			   );
431 #endif /* _POSIX_SOURCE */
432 	sig_act.sa_flags = 0;
433 	sigaction(SIGHUP, &sig_act, (struct sigaction *)0);
434 	sigaction(SIGINT, &sig_act, (struct sigaction *)0);
435 	sigaction(SIGQUIT, &sig_act, (struct sigaction *)0);
436 	sigaction(SIGILL, &sig_act, (struct sigaction *)0);
437 #ifdef SIGBUS
438 	sigaction(SIGBUS, &sig_act, (struct sigaction *)0);
439 #endif
440 	sigaction(SIGSEGV, &sig_act, (struct sigaction *)0);
441 #ifdef SIGSYS
442 	sigaction(SIGSYS, &sig_act, (struct sigaction *)0);
443 #endif
444 #endif /* USGISH */
445 
446 	/*
447 	 * now peruse through the list of files.
448 	 */
449     incCollection = create_IncludesCollection();
450 
451     for(fp=filelist; *fp; fp++) {
452 		struct symhash *includes;
453 		filecontent = getfile(*fp);
454 		ip = newinclude(*fp, (char *)NULL);
455 
456 		includes = hash_copy( maininclist );
457 		find_includes(filecontent, ip, ip, 0, FALSE, incCollection, includes);
458 		hash_free( includes );
459 
460 		freefile(filecontent);
461 		recursive_pr_include(ip, ip->i_file, base_name(*fp));
462 		inc_clean();
463 	}
464 	if (printed)
465 		printf("\n");
466 
467 	delete_IncludesCollection(incCollection);
468 
469 	exit(0);
470 }
471 
472 struct filepointer *getfile(file)
473 	char	*file;
474 {
475 	register int	fd;
476 	struct filepointer	*content;
477 	struct stat	st;
478 	off_t		size_backup;
479 	ssize_t		bytes_read;
480 	size_t		malloc_size;
481 
482 	content = (struct filepointer *)malloc(sizeof(struct filepointer));
483 	if ((fd = open(file, O_RDONLY)) < 0) {
484 		warning("makedepend:  Cannot open file \"%s\"\n", file);
485 		content->f_p = content->f_base = content->f_end = (char *)malloc(1);
486 		*content->f_p = '\0';
487 		return(content);
488 	}
489 	fstat(fd, &st);
490 
491 	size_backup = st.st_size;
492 	malloc_size = size_backup;
493 	/* Since off_t is larger than size_t, need to test for
494 	 * truncation.
495 	 */
496 	if ( (off_t)malloc_size != size_backup )
497 	{
498 		close( fd );
499 		warning("makedepend:  File \"%s\" size larger than can fit in size_t.  Cannot allocate memory for contents.\n", file);
500 		content->f_p = content->f_base = content->f_end = (char *)malloc(1);
501 		*content->f_p = '\0';
502 		return(content);
503 	}
504 
505 	content->f_base = (char *)malloc(malloc_size+1);
506 	if (content->f_base == NULL)
507 		fatalerr("makedepend:  Cannot allocate memory to process file \"%s\"\n", file);
508 	if ((bytes_read = read(fd, content->f_base, malloc_size)) < 0)
509 		if ( st.st_mode & S_IFREG )
510 			fatalerr("makedepend:  Failed to read file \"%s\"\n", file);
511 
512 	close(fd);
513 	content->f_len = bytes_read+1;
514 	content->f_p = content->f_base;
515 	content->f_end = content->f_base + bytes_read;
516 	*content->f_end = '\0';
517 	content->f_line = 0;
518 	return(content);
519 }
520 
521 void freefile(fp)
522 	struct filepointer	*fp;
523 {
524 	free(fp->f_base);
525 	free(fp);
526 }
527 
528 char *copy(str)
529 	register char	*str;
530 {
531 	register char	*p = (char *)malloc(strlen(str) + 1);
532 
533 	strcpy(p, str);
534 	return(p);
535 }
536 
537 int match(str, list)
538 	register char	*str, **list;
539 {
540 	register int	i;
541 
542 	for (i=0; *list; i++, list++)
543 		if (strcmp(str, *list) == 0)
544 			return(i);
545 	return(-1);
546 }
547 
548 /*
549  * Get the next line.  We only return lines beginning with '#' since that
550  * is all this program is ever interested in.
551  */
552 char *get_line(filep)
553 	register struct filepointer	*filep;
554 {
555 	register char	*p,	/* walking pointer */
556 			*eof,	/* end of file pointer */
557 			*bol;	/* beginning of line pointer */
558 	register int	lineno;	/* line number */
559 
560 	p = filep->f_p;
561 	eof = filep->f_end;
562 	if (p >= eof)
563 		return((char *)NULL);
564 	lineno = filep->f_line;
565 
566 	for(bol = p--; ++p < eof; ) {
567 		if (*p == '/' && *(p+1) == '*') { /* consume comments */
568 			*p++ = ' ', *p++ = ' ';
569 			while (*p) {
570 				if (*p == '*' && *(p+1) == '/') {
571 					*p++ = ' ', *p = ' ';
572 					break;
573 				}
574 				else if (*p == '\n')
575 					lineno++;
576 				*p++ = ' ';
577 			}
578 			continue;
579 		}
580 		else if (*p == '/' && *(p+1) == '/') { /* consume comments */
581 			*p++ = ' ', *p++ = ' ';
582 			while (*p && *p != '\n')
583 				*p++ = ' ';
584 			if ( *p == '\n' )
585 				p--;
586 			lineno++;
587 			continue;
588 		}
589 		else if (*p == '\\') {
590 			if (*(p+1) == '\n') {
591 				*p = ' ';
592 				*(p+1) = ' ';
593 				lineno++;
594 			}
595 		}
596 		else if (*p == '\n') {
597 			lineno++;
598 			if (*bol == '#') {
599 				register char *cp;
600 
601 				*p++ = '\0';
602 				/* punt lines with just # (yacc generated) */
603 				for (cp = bol+1;
604 				     *cp && (*cp == ' ' || *cp == '\t'); cp++);
605 				if (*cp) goto done;
606 			}
607 			bol = p+1;
608 		}
609 	}
610 	if (*bol != '#')
611 		bol = NULL;
612 done:
613 	filep->f_p = p;
614 	filep->f_line = lineno;
615 	return(bol);
616 }
617 
618 /*
619  * Strip the file name down to what we want to see in the Makefile.
620  * It will have objprefix and objsuffix around it.
621  */
622 char *base_name(file)
623 	register char	*file;
624 {
625 	register char	*p;
626 
627 	file = copy(file);
628 	for(p=file+strlen(file); p>file && *p != '.'; p--) ;
629 
630 	if (*p == '.')
631 		*p = '\0';
632 
633     while (p > file) {
634         if ( *p == '/' ||  *p == '\\') {
635             file = p + 1;
636             break;
637         }
638         p--;
639     }
640 	return(file);
641 }
642 
643 #if defined(USG) && !defined(CRAY) && !defined(SVR4)
644 int rename (from, to)
645     char *from, *to;
646 {
647     (void) unlink (to);
648     if (link (from, to) == 0) {
649 	unlink (from);
650 	return 0;
651     } else {
652 	return -1;
653     }
654 }
655 #endif /* USGISH */
656 
657 void redirect(line, makefile)
658 	char	*line,
659 		*makefile;
660 {
661 	struct stat	st;
662 	FILE	*fdin, *fdout;
663 	char	backup[ OURBUFSIZ ],
664 		buf[ OURBUFSIZ ];
665 	boolean	found = FALSE;
666 	int	len;
667 
668 	/*
669 	 * if makefile is "-" then let it pour onto stdout.
670 	 */
671 	if (makefile && *makefile == '-' && *(makefile+1) == '\0')
672 		return;
673 
674 	/*
675 	 * use a default makefile is not specified.
676 	 */
677 	if (!makefile) {
678 		if (stat("Makefile", &st) == 0)
679 			makefile = "Makefile";
680 		else if (stat("makefile", &st) == 0)
681 			makefile = "makefile";
682 		else
683 			fatalerr("[mM]akefile is not present\n");
684 	}
685 	else
686 	    stat(makefile, &st);
687 	if ((fdin = fopen(makefile, "r")) == NULL)
688 		fatalerr("cannot open \"%s\"\n", makefile);
689 	sprintf(backup, "%s.bak", makefile);
690 	unlink(backup);
691 #if defined(WIN32) || defined(OS2)
692 	fclose(fdin);
693 #endif
694 	if (rename(makefile, backup) < 0)
695 		fatalerr("cannot rename %s to %s\n", makefile, backup);
696 #if defined(WIN32) || defined(OS2)
697 	if ((fdin = fopen(backup, "r")) == NULL)
698 		fatalerr("cannot open \"%s\"\n", backup);
699 #endif
700 	if ((fdout = freopen(makefile, "w", stdout)) == NULL)
701 		fatalerr("cannot open \"%s\"\n", backup);
702 	len = strlen(line);
703 	while (!found && fgets(buf, OURBUFSIZ, fdin)) {
704 		if (*buf == '#' && strncmp(line, buf, len) == 0)
705 			found = TRUE;
706 		fputs(buf, fdout);
707 	}
708 	if (!found) {
709 		if (verbose)
710 		warning("Adding new delimiting line \"%s\" and dependencies...\n",
711 			line);
712 		puts(line); /* same as fputs(fdout); but with newline */
713 	} else if (append) {
714 	    while (fgets(buf, OURBUFSIZ, fdin)) {
715 		fputs(buf, fdout);
716 	    }
717 	}
718 	fflush(fdout);
719 #if defined(USGISH) || defined(_SEQUENT_) || defined(USE_CHMOD)
720 	chmod(makefile, st.st_mode);
721 #else
722 	fchmod(fileno(fdout), st.st_mode);
723 #endif /* USGISH */
724 	fclose(fdin);
725 }
726 
727 void fatalerr(char *msg, ...)
728 {
729 	va_list args;
730 	fprintf(stderr, "%s: error:  ", ProgramName);
731 	va_start(args, msg);
732 	vfprintf(stderr, msg, args);
733 	va_end(args);
734 	exit (1);
735 }
736 
737 void warning(char *msg, ...)
738 {
739 #ifdef DEBUG_MKDEPEND
740 	va_list args;
741 	fprintf(stderr, "%s: warning:  ", ProgramName);
742 	va_start(args, msg);
743 	vfprintf(stderr, msg, args);
744 	va_end(args);
745 #else
746 	(void)msg;
747 #endif /* DEBUG_MKDEPEND */
748 }
749 
750 void warning1(char *msg, ...)
751 {
752 #ifdef DEBUG_MKDEPEND
753 	va_list args;
754 	va_start(args, msg);
755 	vfprintf(stderr, msg, args);
756 	va_end(args);
757 #else
758 	(void)msg;
759 #endif /* DEBUG_MKDEPEND */
760 }
761 
762 void convert_slashes(path)
763     char* path;
764 {
765 #if defined (WNT) || defined(OS2)
766 	/*
767 	 * Convert backslashes to slashes
768 	 */
769     char *ptr;
770     if (native_win_slashes) {
771         for (ptr = (char*)path; *ptr; ++ptr)
772             if (*ptr == '/')
773                 *ptr = '\\';
774     } else {
775         for (ptr = (char*)path; *ptr; ++ptr)
776             if (*ptr == '\\')
777                 *ptr = '/';
778     }
779 #else
780     (void)path;
781 #endif
782 }
783 
784 char* append_slash(path)
785     char* path;
786 {
787     char *new_string;
788     if ((path[strlen(path) - 1] == '/') || (path[strlen(path) - 1] == '\\')) {
789         new_string = path;
790     } else {
791         new_string = (char*)malloc(sizeof(char) * (strlen(path) + 2));
792         strcpy(new_string, path);
793         if (native_win_slashes)
794             strcat(new_string, "\\");
795         else
796             strcat(new_string, "/");
797     }
798     return new_string;
799 }
800 
801