//************************************************************************** //** //** ## ## ## ## ## #### #### ### ### //** ## ## ## ## ## ## ## ## ## ## #### #### //** ## ## ## ## ## ## ## ## ## ## ## ## ## ## //** ## ## ######## ## ## ## ## ## ## ## ### ## //** ### ## ## ### ## ## ## ## ## ## //** # ## ## # #### #### ## ## //** //** $Id: vcc.cpp 2324 2007-06-01 20:09:08Z dj_jl $ //** //** Copyright (C) 1999-2006 Jānis Legzdiņš //** //** This program is free software; you can redistribute it and/or //** modify it under the terms of the GNU General Public License //** as published by the Free Software Foundation; either version 2 //** of the License, or (at your option) any later version. //** //** This program is distributed in the hope that it will be useful, //** but WITHOUT ANY WARRANTY; without even the implied warranty of //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //** GNU General Public License for more details. //** //************************************************************************** // HEADER FILES ------------------------------------------------------------ #include #include #include "vcc.h" // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PRIVATE FUNCTION PROTOTYPES --------------------------------------------- static void SignalHandler(int s); static void Init(); static void ProcessArgs(int ArgCount, char **ArgVector); static void OpenDebugFile(char *name); static void DumpAsm(); static void PC_Init(); static void PC_DumpAsm(char*); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // PUBLIC DATA DEFINITIONS ------------------------------------------------- char SourceFileName[MAX_FILE_NAME_LENGTH]; static char ObjectFileName[MAX_FILE_NAME_LENGTH]; VPackage* CurrentPackage; // PRIVATE DATA DEFINITIONS ------------------------------------------------ static int num_dump_asm; static char* dump_asm_names[1024]; static bool DebugMode; static FILE* DebugFile; static VLexer Lex; // CODE -------------------------------------------------------------------- //========================================================================== // // main // //========================================================================== int main(int argc, char **argv) { int starttime; int endtime; signal(SIGSEGV, SignalHandler); starttime = time(0); Init(); ProcessArgs(argc, argv); Lex.OpenSource(SourceFileName); VParser Parser(Lex, CurrentPackage); Parser.Parse(); int parsetime = time(0); dprintf("Parsed in %02d:%02d\n", (parsetime - starttime) / 60, (parsetime - starttime) % 60); CurrentPackage->Emit(); int compiletime = time(0); dprintf("Compiled in %02d:%02d\n", (compiletime - parsetime) / 60, (compiletime - parsetime) % 60); CurrentPackage->WriteObject(ObjectFileName); DumpAsm(); VName::StaticExit(); endtime = time(0); dprintf("Wrote in %02d:%02d\n", (endtime - compiletime) / 60, (endtime - compiletime) % 60); dprintf("Time elapsed: %02d:%02d\n", (endtime - starttime) / 60, (endtime - starttime) % 60); return 0; } //========================================================================== // // signal_handler // // Shuts down system, on error signal // //========================================================================== static void SignalHandler(int s) { switch (s) { case SIGSEGV: FatalError("%s:%d Segmentation Violation", Lex.Location.GetSource(), Lex.Location.GetLine()); } } //========================================================================== // // Init // //========================================================================== static void Init() { DebugMode = false; DebugFile = NULL; num_dump_asm = 0; VName::StaticInit(); PC_Init(); } //========================================================================== // // DisplayUsage // //========================================================================== static void DisplayUsage() { // Print usage. printf("\n"); printf("VCC Version 1.%d. Copyright (c)2000-2001 by JL. ("__DATE__" "__TIME__")\n", PROG_VERSION); printf("Usage: vcc [options] source[.c] [object[.dat]]\n"); printf(" -d Output debugging information into specified file\n"); printf(" -a Output function's ASM statements into debug file\n"); printf(" -D Define macro\n"); printf(" -I Include files directory\n"); printf(" -P Package import files directory\n"); exit(1); } //========================================================================== // // ProcessArgs // //========================================================================== static void ProcessArgs(int ArgCount, char **ArgVector) { int i; int count; char* text; char option; count = 0; for (i = 1; i < ArgCount; i++) { text = ArgVector[i]; if (*text == '-') { text++; if (*text == 0) { DisplayUsage(); } option = *text++; switch (option) { case 'd': DebugMode = true; if (*text) { OpenDebugFile(text); } break; case 'a': if (!*text) { DisplayUsage(); } dump_asm_names[num_dump_asm++] = text; break; case 'I': Lex.AddIncludePath(text); break; case 'D': Lex.AddDefine(text); break; case 'P': VMemberBase::AddPackagePath(text); break; default: DisplayUsage(); break; } continue; } count++; switch(count) { case 1: strcpy(SourceFileName, text); DefaultExtension(SourceFileName, ".vc"); break; case 2: strcpy(ObjectFileName, text); DefaultExtension(ObjectFileName, ".dat"); break; default: DisplayUsage(); break; } } if (count == 0) { DisplayUsage(); } if (count == 1) { strcpy(ObjectFileName, SourceFileName); StripExtension(ObjectFileName); DefaultExtension(ObjectFileName, ".dat"); } if (!DebugFile) { char DbgFileName[MAX_FILE_NAME_LENGTH]; strcpy(DbgFileName, ObjectFileName); StripExtension(DbgFileName); DefaultExtension(DbgFileName, ".txt"); OpenDebugFile(DbgFileName); DebugMode = true; } FixFileSlashes(SourceFileName); FixFileSlashes(ObjectFileName); dprintf("Main source file: %s\n", SourceFileName); dprintf(" Resulting file: %s\n", ObjectFileName); } //========================================================================== // // OpenDebugFile // //========================================================================== static void OpenDebugFile(char *name) { DebugFile = fopen(name, "w"); if (!DebugFile) { FatalError("Can\'t open debug file \"%s\".", name); } } //========================================================================== // // DumpAsm // //========================================================================== static void DumpAsm() { for (int i = 0; i < num_dump_asm; i++) { PC_DumpAsm(dump_asm_names[i]); } } //========================================================================== // // dprintf // //========================================================================== int dprintf(const char *text, ...) { va_list argPtr; if (!DebugMode) { return 0; } FILE* fp = DebugFile? DebugFile : stdout; va_start(argPtr, text); int ret = vfprintf(fp, text, argPtr); va_end(argPtr); fflush(fp); return ret; } //========================================================================== // // PC_Init // //========================================================================== static void PC_Init() { CurrentPackage = new VPackage(); } //========================================================================== // // PC_DumpAsm // //========================================================================== static void PC_DumpAsm(char* name) { int i; char buf[1024]; char *cname; char *fname; strcpy(buf, name); if (strstr(buf, ".")) { cname = buf; fname = strstr(buf, ".") + 1; fname[-1] = 0; } else { dprintf("Dump ASM: Bad name %s\n", name); return; } for (i = 0; i < VMemberBase::GMembers.Num(); i++) { if (VMemberBase::GMembers[i]->MemberType == MEMBER_Method && !strcmp(cname, *VMemberBase::GMembers[i]->Outer->Name) && !strcmp(fname, *VMemberBase::GMembers[i]->Name)) { ((VMethod*)VMemberBase::GMembers[i])->DumpAsm(); return; } } dprintf("Dump ASM: %s not found!\n", name); }