Fully working implementation for C compiler front-end.

This commit is contained in:
carl 2019-05-11 01:05:34 +08:00
parent 7a642d6df3
commit 82fddaab77

View file

@ -14,15 +14,6 @@
Something wrong here! Only one of FM2, FPC, or FCC must be defined Something wrong here! Only one of FM2, FPC, or FCC must be defined
#endif #endif
#ifdef sun3
#define MACHNAME "m68020"
#define SYSNAME "sun3"
#endif
#ifdef vax4
#define MACHNAME "vax4"
#define SYSNAME "vax4"
#endif
#ifdef i386 #ifdef i386
#define MACHNAME "i386" #define MACHNAME "i386"
@ -37,6 +28,8 @@ Something wrong here! Only one of FM2, FPC, or FCC must be defined
#include <stdarg.h> #include <stdarg.h>
#include <limits.h> #include <limits.h>
#include <stddef.h> #include <stddef.h>
#include "smap.h"
#include "stringlist.h"
#include "em_path.h" #include "em_path.h"
#include "system.h" #include "system.h"
@ -76,25 +69,158 @@ struct arglist
static char *CPP; static char *CPP;
static char *COMP; static char *COMP;
static char *LD;
static char *cc = "cc"; static char *cc = "cc";
static int kids = -1; static int kids = -1;
static int ecount = 0; static int ecount = 0;
struct arglist CPP_FLAGS =
struct size_info
{ {
/* size in bytes */
int size;
/* alignment */
int align;
};
/** Contains information on the different systems supported. */
struct system_information
{
/** Architecture / machine name */
char* arch;
/** Platform name */
char* platform;
/** Linker path and name */
char *linker;
/** Runtime startup file */
char *startup;
/** Converter path and name */
char *cv;
/** C preprocessor command line arguments. */
struct arglist cpp_flags;
/** Compiler flags. */
struct arglist compiler_flags;
};
const struct system_information machine_info[2] =
{
{
"em22" /* arch */,
"em22" /* platform */,
"$H/lib/ack/em_ass" /* linker */,
#ifdef FCC #ifdef FCC
7, "c-ansi.m" /* startup file */,
#else #else
13, #ifdef FPC
"pascal.m" /* startup file */,
#ifdef FM2
"modula2.m" /* startup file */,
#endif #endif
{ "-D__unix", "-D_EM_WSIZE=4", "-D_EM_PSIZE=4", "-D_EM_SSIZE=2",
"-D_EM_LSIZE=4", "-D_EM_FSIZE=4", "-D_EM_DSIZE=8",
#ifndef FCC
"-DEM_WSIZE=4", "-DEM_PSIZE=4", "-DEM_SSIZE=2", "-DEM_LSIZE=4",
"-DEM_FSIZE=4", "-DEM_DSIZE=8",
#endif #endif
} }; #endif
NULL /* converter */,
/** CPP Flags */
{17,{
"-DEM_WSIZE=2",
"-DEM_PSIZE=2",
"-DEM_SSIZE=2",
"-DEM_LSIZE=4",
"-DEM_FSIZE=4",
"-DEM_DSIZE=8",
"-DEM_XSIZE=8",
"-D_EM_WSIZE=2",
"-D_EM_PSIZE=2",
"-D_EM_SSIZE=2",
"-D_EM_LSIZE=4",
"-D_EM_FSIZE=4",
"-D_EM_DSIZE=8",
"-D_EM_XSIZE=8",
"-Dem22",
"-D__em22",
"-D__unix"}},
/* compiler flags */
#ifdef FCC
{1, {
"-Vw2.2i2.2p2.2f4.2s2.2l4.2d8.2x8.2"
}}
#else
#ifdef FPC
/* pc Flags */
{1, {
"-Vw2.2i2.2l4.2p2.2f8.2S2.2"
}}
#else
#ifdef FM2
/* pc Flags */
{1, {
"-Vw2.2i2.2l4.2p2.2f8.2S2.2"
}}
#endif
#endif
#endif
},
{
"em24" /* arch */,
"em24" /* platform */,
"$H/lib/ack/em_ass" /* linker */,
#ifdef FCC
"c-ansi.m" /* startup file */,
#else
#ifdef FPC
"pascal.m" /* startup file */,
#ifdef FM2
"modula2.m" /* startup file */,
#endif
#endif
#endif
NULL /* converter */,
/** CPP Flags */
{17,{
"-DEM_WSIZE=2",
"-DEM_PSIZE=4",
"-DEM_SSIZE=2",
"-DEM_LSIZE=4",
"-DEM_FSIZE=4",
"-DEM_DSIZE=8",
"-DEM_XSIZE=8",
"-D_EM_WSIZE=2",
"-D_EM_PSIZE=4",
"-D_EM_SSIZE=2",
"-D_EM_LSIZE=4",
"-D_EM_FSIZE=4",
"-D_EM_DSIZE=8",
"-D_EM_XSIZE=8",
"-Dem24",
"-D__em24",
"-D__unix"}},
/* compiler flags */
#ifdef FCC
{1, {
"-Vw2.2i2.2p4.2f4.2s2.2l4.2d8.2x8.2"
}}
#else
#ifdef FPC
/* pc Flags */
{1, {
"-Vw2.2i2.2l4.2p4.2f8.2S2.2"
}}
#else
#ifdef FM2
/* pc Flags */
{1, {
"-Vw2.2i2.2l4.2p4.2f8.2S2.2"
}}
#endif
#endif
#endif
}
};
struct arglist CPP_FLAGS = {0,{NULL}};
struct arglist LD_HEAD = struct arglist LD_HEAD =
{ 2, { 2,
@ -110,28 +236,6 @@ struct arglist LD_HEAD =
#endif #endif
}}; }};
struct arglist LD_TAIL =
{
#if defined(sun3) || defined(i386)
5,
#else
4,
#endif
{
#ifdef FCC
"$H/lib/$S/tail_$A",
#endif
#ifdef FM2
"$H/lib/$S/tail_m2",
#endif
#ifdef FPC
"$H/lib/$S/tail_pc",
#endif
#if defined(sun3) || defined(i386)
"$H/lib/$M/tail_fp",
#endif
"$H/lib/$M/tail_em", "$H/lib/$S/tail_mon",
"$H/lib/$M/end_em" } };
struct arglist align = struct arglist align =
{ 5, { 5,
@ -189,6 +293,7 @@ static int v_flag = 0;
static int O_flag = 0; static int O_flag = 0;
/* Only ANSI C is now supported. */ /* Only ANSI C is now supported. */
static int ansi_c = 1; static int ansi_c = 1;
static int cv_flag = 0;
char *mkstr(char *, ...); char *mkstr(char *, ...);
static char *alloc(unsigned int); static char *alloc(unsigned int);
@ -346,9 +451,10 @@ int lang_opt(char *str)
char* stringdup(const char* s) char* stringdup(const char* s)
{ {
char *p;
if (s == NULL) if (s == NULL)
return NULL; return NULL;
char *p = alloc(strlen(s) + sizeof(char)); p = alloc(strlen(s) + sizeof(char));
strcpy(p, s); strcpy(p, s);
return p; return p;
} }
@ -368,20 +474,89 @@ char* getackhome(void)
} }
#define LIB_PREFIX "lib"
#define LIB_SUFFIX ".a"
/** From a library library directory list,
* search for the libraries that exist, and return
* the full path to the directory where the
* library is located.
*
* The search starts from the first added directory
* item at the command line.
*
* @param[in] dirs The directory list to search in.
* @param[in] lib The library name to search for.
* @returns The full path specification, allocated in the heap, it must
* be freed by the caller.
*/
char* search_library_path(struct stringlist *dirs, char* lib)
{
char fname[FILENAME_MAX];
FILE *fd;
int len;
int dirs_count;
int index = stringlist_count(dirs)-1;
dirs_count = stringlist_count(dirs);
for (index = 0; index < dirs_count; index++)
{
strcpy(fname, stringlist_get(dirs,index));
len = strlen(fname);
/* len-1 is the NULL character */
if (fname[len-1] != '/')
{
/* Add trailing slash */
fname[len] = '/';
fname[len+1] = 0;
len++;
}
fname[len] = 0;
strcat(fname,lib);
fd = fopen(fname,"rb");
if (fd!=NULL)
{
/* Return the path! */
fclose(fd);
return stringdup(fname);
}
}
return NULL;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
/* Contains the directories being searched for libraries */
struct stringlist library_dirs;
/* Contains the library lists */
struct stringlist libraries;
/* Contains the directory paths. */
struct smap paths;
/* Contains the src file list */
struct stringlist srcfiles;
char *str; char *str;
char *startup_file;
char **argvec; char **argvec;
int count; int count;
int index;
int libs_count;
char *ext; char *ext;
FILE* fd; FILE* fd;
register struct arglist *call = &CALL_VEC; register struct arglist *call = &CALL_VEC;
char tmpbuffer[256];
char *file; char *file;
char *ldfile; char *ldfile;
char *INCLUDE = NULL; char *INCLUDE = NULL;
int compile_cnt = 0; int compile_cnt = 0;
struct system_information* sys_info;
startup_file = NULL;
sys_info = &machine_info[0];
strcpy(tmpbuffer, LIB_PREFIX);
stringlist_init(&library_dirs);
stringlist_init(&libraries);
stringlist_init(&srcfiles);
smap_init(&paths);
ackhome = stringdup(getackhome()); ackhome = stringdup(getackhome());
if (ackhome == NULL) if (ackhome == NULL)
@ -402,17 +577,9 @@ int main(int argc, char *argv[])
COMP = expand_string(comp_name()); COMP = expand_string(comp_name());
/* get c pre-processor to use */ /* get c pre-processor to use */
CPP = expand_string(CPP_NAME); CPP = expand_string(CPP_NAME);
/** get linker to use */
LD = expand_string(sys_info->linker);
#ifdef vax4
append(&CPP_FLAGS, "-D__vax");
#endif
#ifdef sun3
append(&CPP_FLAGS, "-D__sun");
#endif
#ifdef m68020
append(&CPP_FLAGS, "-D__mc68020");
append(&CPP_FLAGS, "-D__mc68000");
#endif
if (signal(SIGINT, SIG_IGN) != SIG_IGN) if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, trapcc); signal(SIGINT, trapcc);
@ -422,7 +589,7 @@ int main(int argc, char *argv[])
{ {
if (*(str = *argv++) != '-') if (*(str = *argv++) != '-')
{ {
append(&SRCFILES, str); stringlist_add(&srcfiles,stringdup(str));
continue; continue;
} }
@ -472,8 +639,11 @@ int main(int argc, char *argv[])
if (str[2] == 'n') if (str[2] == 'n')
noexec = 1; noexec = 1;
break; break;
case 'L':
stringlist_add(&library_dirs,stringdup(str+2));
break;
case 'l': /* library file */ case 'l': /* library file */
append(&SRCFILES, str); stringlist_add(&srcfiles,stringdup(str));
break; break;
case 'M': /* use other compiler (for testing) */ case 'M': /* use other compiler (for testing) */
free(COMP); free(COMP);
@ -485,6 +655,10 @@ int main(int argc, char *argv[])
CPP = alloc(strlen(str)+2-1); CPP = alloc(strlen(str)+2-1);
strcpy(CPP, str + 2); strcpy(CPP, str + 2);
break; break;
case 'X': /* use other linker (for testing) */
LD = alloc(strlen(str)+2-1);
strcpy(LD, str + 2);
break;
case 's': /* strip */ case 's': /* strip */
if (str[2] == '\0') if (str[2] == '\0')
{ {
@ -498,8 +672,48 @@ int main(int argc, char *argv[])
} }
} }
/* Add C preprocessor flags. */
for (count = 0; count < sys_info->cpp_flags.al_argc; count++)
{
append(&CPP_FLAGS, sys_info->cpp_flags.al_argv[count]);
}
/* Add compiler flags. */
for (count = 0; count < sys_info->compiler_flags.al_argc; count++)
{
append(&COMP_FLAGS, sys_info->compiler_flags.al_argv[count]);
}
/* Now for each srcfile, if it starts with -l then replace it with the correct real
* path immediately.
*/
count = stringlist_count(&srcfiles);
for (index = 0; index < count; index++)
{
str = stringlist_get(&srcfiles,index);
/* -l parameter */
if (*str == '-')
{
/* Search for the directory where this library might be located. */
strcpy(tmpbuffer,LIB_PREFIX);
strcat(tmpbuffer,str+2);
strcat(tmpbuffer,LIB_SUFFIX);
str = search_library_path(&library_dirs,tmpbuffer);
if (str != NULL)
{
stringlist_add(&srcfiles,str);
append(&SRCFILES,str);
}
} else
{
append(&SRCFILES,str);
}
}
if (ecount) if (ecount)
{
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}
count = SRCFILES.al_argc; count = SRCFILES.al_argc;
argvec = &(SRCFILES.al_argv[0]); argvec = &(SRCFILES.al_argv[0]);
@ -526,12 +740,12 @@ int main(int argc, char *argv[])
/* INCLUDE = expand_string( /* INCLUDE = expand_string(
ansi_c ? "-I$H/include/tail_ac" : "-I$H/include/_tail_cc"); */ ansi_c ? "-I$H/include/tail_ac" : "-I$H/include/_tail_cc"); */
INCLUDE = expand_string("-I$H/share/ack/include"); INCLUDE = expand_string("-I$H/share/ack/include");
append(&COMP_FLAGS, "-L"); /* append(&COMP_FLAGS, "-L");*/
#endif /* FCC */ #endif /* FCC */
count = SRCFILES.al_argc; count = SRCFILES.al_argc;
argvec = &(SRCFILES.al_argv[0]); argvec = &(SRCFILES.al_argv[0]);
/* For each source file... */ /* For argument file */
while (count-- > 0) while (count-- > 0)
{ {
register char *f; register char *f;
@ -539,7 +753,8 @@ int main(int argc, char *argv[])
ext = extension(file); ext = extension(file);
/* if not standard input and file is equal to the supported language suffix. */ /* if not standard input and file is equal to the supported language suffix,
* then compile it */
if (file[0] != '-' && ext != file && (!strcmp(ext, lang_suffix()))) if (file[0] != '-' && ext != file && (!strcmp(ext, lang_suffix())))
{ {
if (compile_cnt > 1) if (compile_cnt > 1)
@ -617,7 +832,8 @@ int main(int argc, char *argv[])
} }
cleanup(tmp_file); cleanup(tmp_file);
tmp_file[0] = '\0'; tmp_file[0] = '\0';
} } /* endif compiling source file. */
else if (file[0] != '-' && strcmp(ext, "o") && strcmp(ext, "a")) else if (file[0] != '-' && strcmp(ext, "o") && strcmp(ext, "a"))
{ {
@ -632,24 +848,48 @@ int main(int argc, char *argv[])
append(&LDFILES, file); append(&LDFILES, file);
} }
/* See if we need to convert the flags. */
cv_flag = sys_info->cv!=NULL;
/* *.s to a.out */ /* *.s to a.out */
if (RET_CODE == 0 && LDFILES.al_argc > 0) if (RET_CODE == 0 && LDFILES.al_argc > 0)
{ {
init(call); init(call);
// expand(&LD_HEAD); /* expand(&LD_HEAD);
// cc = "cc.2g"; // cc = "cc.2g";
// expand(&LD_TAIL); expand(&LD_TAIL);*/
append(call, expand_string(LD_NAME)); append(call, LD);
// concat(call, &align); /* concat(call, &align);*/
append(call, "-p");
append(call, "-sx");
append(call, "-o"); append(call, "-o");
if (cv_flag)
{
if (sys_tmpnam(tmp_file)==NULL) if (sys_tmpnam(tmp_file)==NULL)
{ {
panic("Cannot get temporary filename."); panic("Cannot get temporary filename.");
} }
append(call, tmp_file); append(call, tmp_file);
// concat(call, &LD_HEAD); } else
// concat(call, &LD_FLAGS); {
append(call, o_FILE);
}
/* concat(call, &LD_HEAD);
concat(call, &LD_FLAGS);*/
if (sys_info->startup!=NULL)
{
startup_file = search_library_path(&library_dirs,sys_info->startup);
if (startup_file!=NULL)
{
append(call,startup_file);
} else
{
panic("Cannot find startup file.");
}
}
concat(call, &LDFILES); concat(call, &LDFILES);
/* if (g_flag) /* if (g_flag)
append(call, expand_string("$H/lib/$M/tail_db")); append(call, expand_string("$H/lib/$M/tail_db"));
@ -663,17 +903,35 @@ int main(int argc, char *argv[])
cleanup(tmp_file); cleanup(tmp_file);
exit(RET_CODE); exit(RET_CODE);
} }
/* init(call);
append(call, expand_string(CV_NAME)); /* Check if we need to convert the file to
* a standard executable file for the specific
* target.
*
*/
if (cv_flag)
{
init(call);
append(call, expand_string(sys_info->cv));
append(call, tmp_file); append(call, tmp_file);
append(call, o_FILE); append(call, o_FILE);
runvec(call, (char *) 0);*/ if (runvec(call, (char *) 0)==EXIT_FAILURE)
{
cleanup(tmp_file); cleanup(tmp_file);
exit(RET_CODE);
}
cleanup(tmp_file);
}
} }
if ((LDFILES.al_argc == 0) && (SRCFILES.al_argc==0)) if ((LDFILES.al_argc == 0) && (SRCFILES.al_argc==0))
{ {
panic("No input source files or input object files specified."); panic("No input source files or input object files specified.");
} }
stringlist_free(&library_dirs,1);
stringlist_free(&libraries,1);
if (startup_file!=NULL)
free(startup_file);
smap_free(&paths,1,1);
exit(RET_CODE); exit(RET_CODE);
} }
@ -811,7 +1069,7 @@ char *mkstr(char *dst, ...)
return dst; return dst;
} }
static char * extension(char *fn) static char *extension(char *fn)
{ {
register char *c = fn; register char *c = fn;
@ -877,6 +1135,10 @@ static int runvec(struct arglist *vec, char *outp)
append(vec,redirect); append(vec,redirect);
} }
p = arg2str(vec); p = arg2str(vec);
if ((v_flag) && (p != NULL))
{
fprintf(stdout,"Executing : %s\n",p);
}
status = system(p); status = system(p);
free(p); free(p);