dos_compilers/Zortech C++ v30r1/SAMPLE/CL.CPP
2024-07-02 08:01:21 -07:00

343 lines
7.8 KiB
C++

// D.J.Bustin. May 1991.
// CL transposes MS flags into equivalent ZTC flags
// compile with:
// ztc -mi -o+space cl _mains.obj list mem
//
#define MAXARGS 128
#include <ctype.h>
#include <dos.h>
#include <errno.h>
#include <process.h>
#include <stdlib.h>
#include <stream.hpp>
#include <string.h>
extern "C"
{
#include "mem.h"
#include "list.h"
#include "assert.h"
}
struct flags_info {
char *msc_flag;
char *ztc_flag;
};
const char *title = "CL - Zortech CL v3.0r1 Copyright (C) 1991 by Zortech\nAll Rights Reserved, written by D.J.Bustin.\n\n";
char *zargs[MAXARGS];
list_t flags_list = NULL;
int line;
int reading_config = 0; // set to 1 when reading CL.CFG to display warnings
int verbose = 0;
char file_name[80];
char *zflg;
void fatal_error(int l,int i);
int read_config_file(char *);
void del_list();
char* checkin(char*);
void usage()
{
cout << title;
cout << "This small utility mimicks the Microsoft CL program and\n";
cout << "saves the need to change makefiles, batch files and so on\n";
cout << "by reading a file called CL.CFG which equates the various\n";
cout << "MS-C compiler flags to the equivalent ZTC flags. It then\n";
cout << "translates its command line flags and spawns ZTC with the\n";
cout << "appropriate flags.\n\n";
cout << "If the flag -V is specified then a warning is displayed\n";
cout << "for unknown command line flags.\n\n";
cout << "Usage:\n\tCL [flags] file(s) [@file]\n";
}
//---------------------------------------------------------------------------
// Main
main(int argc, char *argv[])
{
int i=0,j=0;
char *zcmd = "ZTC";
response_expand(&argc, &argv);
int nargs = argc;
if (argc==1)
{
usage();
return 1;
}
// initialization
mem_init();
list_init();
read_config_file(argv[0]);
if (argv[1][0] == '?')
{
usage();
return 0;
}
zargs[j++] = mem_strdup(zcmd); // place holder
while (--nargs > 0)
{
i++;
if ((argv[i][0] != '-') && (argv[i][0] != '/'))
zargs[j] = mem_strdup(argv[i]);
else
switch(argv[i][1])
{
case '?':
usage();
return 0;
case 'V':
verbose = 1;
break;
default:
if ((zflg=checkin(&argv[i][1]))!= NULL)
{
int lenarg = strlen(&argv[i][1]);
int extra_chars = lenarg - strlen(zflg);
if (extra_chars <0 )
extra_chars = 0;
zargs[j] = mem_malloc(strlen(zflg)+2+extra_chars);
assert(zargs[i-1]!=NULL);
zargs[j][0] = '-';
strcpy(&zargs[j][1],zflg);
if (extra_chars)
strcat(&zargs[j][1],&argv[i][1+strlen(zflg)]);
}
}
j++;
}
zargs[++i] = NULL;
for (j=0;j<i;j++)
cout << zargs[j] << " ";
cout << "\n";
if (spawnvp(0,zcmd,zargs) == -1)
cerr << "Cannot execute ztc.com - check path\n";
for (j=0;j<i;j++)
mem_free(zargs[j]);
del_list();
mem_term();
}
//---------------------------------------------------------------------------
int compare(flags_info *fip, char *str)
{
int cmp;
cmp = strncmp(str,fip->msc_flag,strlen(fip->msc_flag));
if (cmp == 0 && reading_config)
cout << "\n" << file_name << "(" << line
<< ") Warning: Redefinition attempted on flag /" << str << "\n";
return cmp;
}
//---------------------------------------------------------------------------
// Returns NULL if str not in flag list otherwise returns equivalent
// ztc flag
char *checkin(char *str)
{
int i, cmp;
list_t le;
flags_info *fip;
int start = 0;
int endstop = list_nitems(flags_list);
int size = endstop - start;
if (size == 0) return 0;
fip = (flags_info*)list_ptr(flags_list); // test start
if (compare(fip, str) == 0)
return fip->ztc_flag;
fip = (flags_info*)list_ptr(list_last(flags_list)); // test end
if (compare(fip, str) == 0)
return fip->ztc_flag;
if (size == 1)
return NULL;
while (size>0)
{
i = (start+endstop) / 2;
le = list_nth(flags_list, i);
fip = (flags_info*)list_ptr(le);
cmp = compare(fip, str);
if (cmp == 0)
return fip->ztc_flag;
else
if (cmp > 0)
start = i;
else
if (cmp < 0)
endstop = i;
size /= 2;
}
if (verbose)
cout << "Warning: No equivalent flag found in CL.CFG for /" << str << "\n";
return NULL;
}
//---------------------------------------------------------------------------
int add_flag(char *msc, char *ztc)
{
if ((msc == NULL) || checkin(msc)!=NULL)
return 0;
flags_info *flp = mem_malloc(sizeof(flags_info));
assert (flp != NULL);
flp->msc_flag = mem_strdup(msc);
assert(flp->msc_flag);
if (ztc != NULL)
{
flp->ztc_flag = mem_strdup(ztc);
assert(flp->msc_flag);
}
else
flp->ztc_flag = NULL;
list_t le,ll;
void *vop;
char *cp;
for (le=flags_list;le;le = list_next(le)) // find out where to insert str
{
ll = le;
vop = list_ptr(le);
cp = ((flags_info*)vop)->msc_flag;
if (strcmp(msc, cp) < 0)
break;
}
if (le != NULL && strcmp(msc, cp) < 0)
{
if ((le = list_prepend(&le, flp)) == NULL)
fatal_error(__LINE__,ENOMEM);
if (ll == flags_list)
flags_list = le;
else
list_next(list_prev(flags_list,ll)) = le;
}
else
{
if (le == NULL)
le = flags_list;
if ((le = list_append(&le, flp)) == NULL)
fatal_error(__LINE__,ENOMEM);
}
if (flags_list == NULL)
flags_list = le;
return 1;
}
//---------------------------------------------------------------------------
// Delete all elements in flags_list
void del_list()
{
list_t le;
flags_info *fip;
if (flags_list == NULL)
return;
for (le=flags_list; le;le=list_next(le))
{
fip = list_ptr(le);
mem_free(fip->msc_flag);
if (fip->ztc_flag != NULL)
mem_free(fip->ztc_flag);
}
list_free(&flags_list,mem_freefp);
}
//---------------------------------------------------------------------------
int read_config_file(char *cldir)
{
FILE *fp;
char buffer[256];
char ch;
char *str;
char *ptr;
char *equals;
strcpy(file_name,cldir);
ptr = strrchr(file_name, '\\');
if (ptr++ != NULL)
*ptr = NULL;
strcat(file_name,"CL.CFG");
if ((fp = fopen(file_name, "rb")) == NULL)
{
cerr << "\nError: Cannot open file: " << file_name << "\n";
return 1;
}
line = 0;
reading_config = 1;
while ((fgets(buffer, 255, fp)) != NULL)
{
str = buffer;
line++;
if (str[0] == '\n' || str[0] == '\r' || str[0] == '*')
continue;
equals = strchr(str, '=');
ptr = strchr(str, '\r');
if (ptr != NULL)
*ptr = NULL;
else
{
ptr = strchr(str, '\n');
if (ptr != NULL)
*ptr = NULL;
}
if (equals == NULL)
{
cerr << file_name << "(" << line << ") - Error in configuration file\n";
return 1;
}
*equals++ = NULL;
add_flag(str, equals);
} // end of main while
fclose(fp);
reading_config = 0;
return 0; // ok
}
//---------------------------------------------------------------------------
void fatal_error(int l,int i)
{
cout << "\n";
cerr << "Fatal Error: ";
switch(i)
{
case ENOMEM:
cerr << "Out of memory";
break;
default:
cerr << "RC = "<< i;
}
#if DEBUG
cerr << " at line " << l;
#endif
cerr << "\n";
exit(i);
}