home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
makdep4d.zip
/
MAKDPDOS.ZIP
/
MAKEDEP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-28
|
18KB
|
553 lines
// --------------------------------------------------------------------------
//
// File: MAKEDEP.C
// Product: MAKEDEP program
// Author: Sulyok Péter (C) 1994.
// Compiler: Borland C\C++ 3.1
// Borland C\C++ 4.02
// Microsoft C 6.00A
// Microsoft C\C++ 7.00
// Watcom C 9.0
// Notes: Generate dependency list of C and assembly programs
// for MAKE.
//
// --------------------------------------------------------------------------
// Include files ------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <string.h>
#include <malloc.h>
#include <exparg.h>
// Constants ----------------------------------------------------------------
#ifdef MAXPATH
#undef MAXPATH
#endif
#define MAXPATH 128 // Maximal size of path.
#define MAXNUM 50 // Maximum number of path.
#define EXTNUM 6 // Number of source file extensions.
#define LSIZE 256 // Line size.
#define DOS_ERROR 1 // Error code to DOS.
#define DOS_OK 0 // OK code to DOS.
#define ASM_TYPE 0 // Source is an assembly file.
#define C_TYPE 1 // Source is a C file.
#define TRUE 1 // True value.
#define FALSE 0 // False value.
#define usage "MAKEDEP dependecies generator, SP (C) 1994.\n" \
"Usage: MAKEDEP [-option ...] objectfile [outputfile]\n" \
"Options:\n" \
" -a Append to outputfile\n" \
" -sPATH[;PATH...] Source file search directories\n" \
" -iPATH[;PATH...] Include file search directories\n" \
" -n Ignore include file if not found\n" \
" -d Do not write objectfile\n" \
" -b Write depencies base name\n" \
" -u Use upper case\n" \
" -l Use lower case\n" \
" -h,-? This text\n" \
" @respfile Response file for options"
#define backslash(s) \
if ( (s)[strlen((s))-1] != '\\' ) { \
unsigned int pos; \
pos = strlen((s)); \
(s)[pos] = '\\'; \
(s)[pos+1] = '\0'; \
}
// Local variables ----------------------------------------------------------
static short source_num = 0; // Number of source directories.
static char source_dirs[MAXNUM][MAXPATH]; // Array of source directories.
static char source_type = C_TYPE; // Type of source file.
static char *source_exts[EXTNUM] = { // Source file extensions.
".c",
".cc",
".cpp",
".asm",
".as",
".a"
};
static short include_num = 0; // Number of include directories.
static char include_dirs[MAXNUM][MAXPATH]; // Array of include directories.
static short depend_num = 0; // Number of dependent file.
static char depends[MAXNUM][MAXPATH]; // Array of dependent file.
static char source_file[MAXPATH] = { 0 }; // Full source file name.
static char object_file[MAXPATH] = { 0 }; // Object file name.
static char depend_file[MAXPATH] = { 0 }; // Dependency output file name.
static char append_mode = FALSE; // Append mode flag.
static char ignore_mode = FALSE; // Ignore mode flag.
static char depend_mode = FALSE; // Dependency only mode flag.
static char upper_mode = FALSE; // Upper case mode.
static char lower_mode = FALSE; // Lower case mode.
static char basename_mode = FALSE; // Base name mode flag.
#ifdef __TURBOC__
extern unsigned _stklen = 10000; // We use recursive calls !
#endif
// Local functions ---------------------------------------------------------
static char *next_white(char *s);
static char *next_nonwhite(char *s);
static void search_source_file(void);
static void search_include_file(char *name);
static void make_depend_files(char *name);
static void write_depend_files(void);
// --------------------------------------------------------------------------
// Name: next_nonwhite
// Input: char *s string
// Output: char * next position
// NULL if EOS
// Notes: Search the next nonwhitespace character in string.
// --------------------------------------------------------------------------
static char *next_nonwhite(char *s)
{
// Check the string.
while( *s ) {
// If this is a whitespace character than continue the loop.
if ( (*s == ' ') || (*s == 9) || (*s == '\n') || (*s == '\r') ) {
s++;
continue;
} // if
// Found a none whitespace character.
return s;
} // while
return NULL;
}
// --------------------------------------------------------------------------
// Name: next_white
// Input: char *s string
// Output: char * next position
// NULL if EOS
// Notes: Search the next whitespace character in string.
// --------------------------------------------------------------------------
static char *next_white(char *s)
{
// Check the string.
while( *s ) {
// Found a whitespace character.
if ( (*s == ' ') || (*s == 9) || (*s == '\n') || (*s == '\r') )
return s;
// Else continue the loop.
s++;
} // while
return NULL;
}
// --------------------------------------------------------------------------
// Name: search_source_file
// Input: void
// Output: void
// Notes: Search the original source file from the object file name.
// --------------------------------------------------------------------------
static void search_source_file(void)
{
short i, j;
char tmp[MAXPATH];
char drive[_MAX_DRIVE], dir[_MAX_DIR],
name[_MAX_FNAME], ext[_MAX_EXT];
struct find_t find;
// Split object file name to its components.
_splitpath(object_file, drive, dir, name, ext);
// Try to find in all source directory.
for(i=0; i<source_num; i++) {
// Try to open with every source file extension.
for(j=0; j<EXTNUM; j++) {
// Make the full source file name.
_makepath(tmp, NULL, source_dirs[i], name, source_exts[j]);
// Try to locate the source file.
if ( !_dos_findfirst(tmp, _A_ARCH|_A_RDONLY|_A_HIDDEN, &find) ) {
strcpy(source_file, tmp);
source_type = ( source_exts[j][1] == 'a' ) ? ASM_TYPE : C_TYPE;
return;
} // if
} //for
} // for
// If source file not found.
printf("Source file not found for %s.\n", object_file);
exit(DOS_ERROR);
}
// --------------------------------------------------------------------------
// Name: search_include_file
// Input: char *name include file name
// Output: void
// Notes: Search the the given include file in the include directories.
// --------------------------------------------------------------------------
static void search_include_file(char *name)
{
int i, j;
char tmp[MAXPATH];
struct find_t find;
// Try to find in all include directory.
for(i=0; i<include_num; i++) {
// Make the full name.
strcpy(tmp, include_dirs[i]);
strcat(tmp, name);
// Try to locate the include file.
if ( !_dos_findfirst(tmp, _A_ARCH|_A_RDONLY|_A_HIDDEN, &find) ) {
// Check if it appears in the dependecy list.
for(j=0; j<depend_num; j++)
if ( !strcmp(depends[j], tmp) )
return;
// It is a new dependent file.
if ( depend_num == MAXNUM ) {
puts("Too many dependent file.");
exit(DOS_ERROR);
} // if
strcpy(depends[depend_num++], tmp);
return;
} // if
} // for
// If include file not found.
if ( !ignore_mode ) {
printf("Cannot locate %s include file.\n", name);
exit(DOS_ERROR);
} // if
}
// --------------------------------------------------------------------------
// Name: make_depend_files
// Input: char *name source file name
// Output: void
// Notes: Search the dependencies of the given source file.
// --------------------------------------------------------------------------
static void make_depend_files(char *name)
{
FILE *sf;
char line[LSIZE];
char *s, *e;
int i, first, last;
// Register the first dependent file.
first = depend_num;
// Open source file.
if ( (sf = fopen(name, "rt")) == NULL ) {
printf("Unable to open %s file.\n", name);
exit(DOS_ERROR);
} // if
// Scan source file for include statments.
while( fgets(line, LSIZE, sf) ) {
// Go to first nonwhitespace character in line.
if ( (s = next_nonwhite(line)) == NULL )
continue;
// Process an assembly line.
if ( source_type == ASM_TYPE ) {
// This is an include statment ?
if ( !strnicmp(s, "include", 7) ) {
s += 7;
// Search begin of include file name.
if ( (s = next_nonwhite(s)) == NULL )
continue;
// Search end of include file name.
if ( (e= next_white(s)) == NULL )
continue;
*e = '\0';
// Search full path of include file.
search_include_file(s);
} // if
} // if
// Process a C line.
if ( source_type == C_TYPE ) {
// This is an #include statment ?
if ( !strnicmp(s, "#include", 8) ) {
s += 8;
// Search begin of include file name.
if ( (s = next_nonwhite(s)) == NULL )
continue;
s++;
// Search end of include file name.
if ( (e = strchr(s, '>')) == NULL )
if ( (e = strchr(s, '"')) == NULL )
continue;
*e = '\0';
// Search full path of include file.
search_include_file(s);
} // if
} // if
} // while
// Register the last dependent file.
last = depend_num;
// Close the source file.
fclose(sf);
// Check include files in this source file.
if ( first < last )
for(i=first; i<last; i++)
make_depend_files(depends[i]);
}
// --------------------------------------------------------------------------
// Name: write_depend_files
// Input: void
// Output: void
// Notes: Write list of dependent files to the given file or stdout.
// --------------------------------------------------------------------------
static void write_depend_files(void)
{
int i;
FILE *output;
char drive[_MAX_DRIVE], dir[_MAX_DIR],
name[_MAX_FNAME], ext[_MAX_EXT];
// Output is stdout.
if ( !depend_file[0] ) {
output = stdout;
} // if
// Output is a file.
else {
char *mode;
mode = ( append_mode ) ? "a+t" : "w+t";
if ( (output = fopen(depend_file, mode)) == NULL ) {
printf("Unable to open %s.", depend_file);
exit(DOS_ERROR);
} // if
} // else
// Use upper case if need.
if ( upper_mode ) {
strupr(object_file);
for(i=0; i<depend_num; i++)
strupr(depends[i]);
} // if
// Use lower case if need.
if ( lower_mode ) {
strlwr(object_file);
for(i=0; i<depend_num; i++)
strlwr(depends[i]);
} // if
// Write object file name too if need.
if ( !depend_mode )
fprintf(output, "%s: ", object_file);
// Write dependecies to output.
for(i=0; i<depend_num; i++) {
if ( !basename_mode )
fprintf(output, "%s ", depends[i]);
else {
char tmp[MAXPATH];
_splitpath(depends[i], drive, dir, name, ext);
_makepath(tmp, NULL, NULL, name, ext);
fprintf(output, "%s ", tmp);
} // else
} // for
// Close output.
fprintf(output, "\n");
fclose(output);
}
// --------------------------------------------------------------------------
// Name: main
// Input: int argc number of arguments
// char *argv[] list of argument
// Output: void
// Notes: The main() function.
// --------------------------------------------------------------------------
void main(int argc, char *argv[])
{
int i;
char *s, *d;
// Expand command line.
switch( exparg(&argc, &argv) ) {
case -1:
puts("Not enough memory to load response file.");
exit(DOS_ERROR);
case -2:
puts("Unable to load response file.");
exit(DOS_ERROR);
} // switch
// If not enough command line argument.
if ( argc < 2 ) {
puts("Not enough argument (use -h for help).");
exit(DOS_ERROR);
} // if
// Check all argument.
for(i=1; i<argc; i++) {
// If argument is an option.
if ( (argv[i][0] == '-') || (argv[i][0] == '/') ) {
switch( argv[i][1] ) {
case '?' :
case 'h' :
case 'H' :
puts(usage);
exit(DOS_OK);
break;
case 'a' :
case 'A' :
append_mode = TRUE;
break;
case 'n' :
case 'N' :
ignore_mode = TRUE;
break;
case 'd' :
case 'D' :
depend_mode = TRUE;
break;
case 'b' :
case 'B' :
basename_mode = TRUE;
break;
case 'u' :
case 'U' :
lower_mode = FALSE;
upper_mode = TRUE;
break;
case 'l' :
case 'L' :
upper_mode = FALSE;
lower_mode = TRUE;
break;
case 's' :
case 'S' :
s = &argv[i][2];
while( (d = strchr(s, ';')) != NULL ) {
*d++ = '\0';
strcpy(source_dirs[source_num], s);
backslash(source_dirs[source_num]);
source_num++;
s = d;
} // while
strcpy(source_dirs[source_num], s);
backslash(source_dirs[source_num]);
source_num++;
break;
case 'i' :
case 'I' :
s = &argv[i][2];
while( (d = strchr(s, ';')) != NULL ) {
*d++ = '\0';
strcpy(include_dirs[include_num], s);
backslash(include_dirs[include_num]);
include_num++;
s = d;
} // while
strcpy(include_dirs[include_num], s);
backslash(include_dirs[include_num]);
include_num++;
break;
default:
printf("Unknown argument %s (use -h for help).\n", argv[i]);
exit(DOS_ERROR);
} // switch
} // if
// If argument is a file name.
else {
// First time get the object file name.
if ( !object_file[0] ) {
strcpy(object_file, argv[i]);
continue;
} // if
// Second time get the dependencies file name.
if ( !depend_file[0] ) {
strcpy(depend_file, argv[i]);
continue;
} // if
puts("Too many file name (use -h for help).");
exit(DOS_ERROR);
} // else
} // for
// If object file missing.
if ( !object_file[0] ) {
puts("Missing object file name (use -h for help).");
exit(DOS_ERROR);
} // if
// Always use the current directory.
include_dirs[include_num++][0] = '\0';
source_dirs[source_num++][0] = '\0';
// Search the original source file.
search_source_file();
// First dependcy is the source file.
strcpy(depends[depend_num++], source_file);
// Make list of depenencies.
make_depend_files(source_file);
// Write out list of dependencies.
write_depend_files();
exit(DOS_OK);
}
// End ----------------------------------------------------------------------