X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fmain.c;h=32adcb7251229b565cfbdacba061c771a496c3c8;hb=9ce1e413e4d5a9f48a57b3ce357e71d62281c7c8;hp=0b0388bf0f9db4ebbe2d3ae5ad29c25d1dde0394;hpb=7bd93e9e822b6cadcc58dbb1fdd05c742f649fb5;p=cc65 diff --git a/src/cc65/main.c b/src/cc65/main.c index 0b0388bf0..32adcb725 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (C) 2000 Ullrich von Bassewitz */ +/* (C) 2000-2001 Ullrich von Bassewitz */ /* Wacholderweg 14 */ /* D-70597 Stuttgart */ -/* EMail: uz@musoftware.de */ +/* EMail: uz@cc65.org */ /* */ /* */ /* This software is provided 'as-is', without any expressed or implied */ @@ -36,47 +36,31 @@ #include #include #include -#include #include -#include "../common/cmdline.h" -#include "../common/fname.h" -#include "../common/version.h" -#include "../common/xmalloc.h" - +/* common */ +#include "abend.h" +#include "chartype.h" +#include "cmdline.h" +#include "fname.h" +#include "print.h" +#include "target.h" +#include "tgttrans.h" +#include "version.h" +#include "xmalloc.h" + +/* cc65 */ #include "asmcode.h" #include "compile.h" +#include "codeopt.h" #include "cpu.h" #include "error.h" #include "global.h" #include "incpath.h" #include "input.h" #include "macrotab.h" -#include "optimize.h" #include "scanner.h" - - - -/*****************************************************************************/ -/* data */ -/*****************************************************************************/ - - - -/* Names of the target systems sorted by target name */ -static const char* TargetNames [] = { - "none", - "atari", - "c64", - "c128", - "ace", - "plus4", - "cbm610", - "pet", - "nes", - "apple2", - "geos", -}; +#include "segments.h" @@ -101,7 +85,7 @@ static void Usage (void) " -A\t\t\tStrict ANSI mode\n" " -Cl\t\t\tMake local variables static\n" " -Dsym[=defn]\t\tDefine a symbol\n" - " -I path\t\tSet an include directory search path\n" + " -I dir\t\tSet an include directory search path\n" " -O\t\t\tOptimize code\n" " -Oi\t\t\tOptimize code, inline more code\n" " -Or\t\t\tEnable register variables\n" @@ -112,11 +96,19 @@ static void Usage (void) "\n" "Long options:\n" " --ansi\t\tStrict ANSI mode\n" + " --bss-name seg\tSet the name of the BSS segment\n" + " --check-stack\t\tGenerate stack overflow checks\n" + " --code-name seg\tSet the name of the CODE segment\n" + " --codesize x\t\tAccept larger code by factor x\n" " --cpu type\t\tSet cpu type\n" + " --data-name seg\tSet the name of the DATA segment\n" " --debug\t\tDebug mode\n" " --debug-info\t\tAdd debug info to object file\n" + " --disable-opt name\tDisable an optimization step\n" + " --enable-opt name\tEnable an optimization step\n" " --help\t\tHelp (this text)\n" " --include-dir dir\tSet an include directory search path\n" + " --rodata-name seg\tSet the name of the RODATA segment\n" " --signed-chars\tDefault characters are signed\n" " --static-locals\tMake local variables static\n" " --target sys\t\tSet the target system\n" @@ -136,35 +128,10 @@ static void cbmsys (const char* sys) -static int MapSys (const char* Name) -/* Map a target name to a system code. Return -1 in case of an error */ -{ - unsigned I; - - /* Check for a numeric target */ - if (isdigit (*Name)) { - int Target = atoi (Name); - if (Target >= 0 && Target < TGT_COUNT) { - return Target; - } - } - - /* Check for a target string */ - for (I = 0; I < TGT_COUNT; ++I) { - if (strcmp (TargetNames [I], Name) == 0) { - return I; - } - } - /* Not found */ - return -1; -} - - - static void SetSys (const char* Sys) /* Define a target system */ { - switch (Target = MapSys (Sys)) { + switch (Target = FindTarget (Sys)) { case TGT_NONE: break; @@ -194,26 +161,55 @@ static void SetSys (const char* Sys) break; case TGT_PET: - cbmsys ("__PET__"); - break; + cbmsys ("__PET__"); + break; - case TGT_NES: - AddNumericMacro ("__NES__", 1); - break; + case TGT_BBC: + AddNumericMacro ("__BBC__", 1); + break; - case TGT_APPLE2: - AddNumericMacro ("__APPLE2__", 1); - break; + case TGT_APPLE2: + AddNumericMacro ("__APPLE2__", 1); + break; - case TGT_GEOS: - /* Do not handle as a CBM system */ - AddNumericMacro ("__GEOS__", 1); - break; + case TGT_GEOS: + /* Do not handle as a CBM system */ + AddNumericMacro ("__GEOS__", 1); + break; + + default: + AbEnd ("Unknown target system type"); + } - default: - fputs ("Unknown system type\n", stderr); - exit (EXIT_FAILURE); + /* Initialize the translation tables for the target system */ + TgtTranslateInit (); +} + + + +static void DoCreateDep (const char* OutputName) +/* Create the dependency file */ +{ + /* Make the dependency file name from the output file name */ + char* DepName = MakeFilename (OutputName, ".u"); + + /* Open the file */ + FILE* F = fopen (DepName, "w"); + if (F == 0) { + Fatal ("Cannot open dependency file `%s': %s", DepName, strerror (errno)); } + + /* Write the dependencies to the file */ + WriteDependencies (F, OutputName); + + /* Close the file, check for errors */ + if (fclose (F) != 0) { + remove (DepName); + Fatal ("Cannot write to dependeny file (disk full?)"); + } + + /* Free the name */ + xfree (DepName); } @@ -224,12 +220,12 @@ static void DefineSym (const char* Def) const char* P = Def; /* The symbol must start with a character or underline */ - if (Def [0] != '_' && !isalpha (Def [0])) { + if (Def [0] != '_' && !IsAlpha (Def [0])) { InvDef (Def); } /* Check the symbol name */ - while (isalnum (*P) || *P == '_') { + while (IsAlNum (*P) || *P == '_') { ++P; } @@ -239,7 +235,7 @@ static void DefineSym (const char* Def) InvDef (Def); } /* No value given. Define the macro with the value 1 */ - AddNumericMacro (Def, 1); + AddNumericMacro (Def, 1); } else { /* We have a value, P points to the '=' character. Since the argument * is const, create a copy and replace the '=' in the copy by a zero @@ -247,7 +243,7 @@ static void DefineSym (const char* Def) */ char* Q; unsigned Len = strlen (Def)+1; - char* S = xmalloc (Len); + char* S = (char*) xmalloc (Len); memcpy (S, Def, Len); Q = S + (P - Def); *Q++ = '\0'; @@ -262,6 +258,17 @@ static void DefineSym (const char* Def) +static void CheckSegName (const char* Seg) +/* Abort if the given name is not a valid segment name */ +{ + /* Print an error and abort if the name is not ok */ + if (!ValidSegName (Seg)) { + AbEnd ("Segment name `%s' is invalid", Seg); + } +} + + + static void OptAddSource (const char* Opt, const char* Arg) /* Add source lines as comments in generated assembler file */ { @@ -278,24 +285,85 @@ static void OptAnsi (const char* Opt, const char* Arg) +static void OptBssName (const char* Opt, const char* Arg) +/* Handle the --bss-name option */ +{ + /* Check for a valid name */ + CheckSegName (Arg); + + /* Set the name */ + NewSegName (SEG_BSS, Arg); +} + + + +static void OptCheckStack (const char* Opt, const char* Arg) +/* Handle the --check-stack option */ +{ + CheckStack = 1; +} + + + +static void OptCodeName (const char* Opt, const char* Arg) +/* Handle the --code-name option */ +{ + /* Check for a valid name */ + CheckSegName (Arg); + + /* Set the name */ + NewSegName (SEG_CODE, Arg); +} + + + +static void OptCodeSize (const char* Opt, const char* Arg) +/* Handle the --codesize option */ +{ + /* Numeric argument expected */ + if (sscanf (Arg, "%u", &CodeSizeFactor) != 1 || + CodeSizeFactor < 100 || + CodeSizeFactor > 1000) { + AbEnd ("Argument for %s is invalid", Opt); + } +} + + + +static void OptCreateDep (const char* Opt, const char* Arg) +/* Handle the --create-dep option */ +{ + CreateDep = 1; +} + + + static void OptCPU (const char* Opt, const char* Arg) /* Handle the --cpu option */ { - if (Arg == 0) { - NeedArg (Opt); - } if (strcmp (Arg, "6502") == 0) { CPU = CPU_6502; } else if (strcmp (Arg, "65C02") == 0) { CPU = CPU_65C02; } else { - fprintf (stderr, "Invalid CPU: `%s'\n", Arg); - exit (EXIT_FAILURE); + AbEnd ("Invalid CPU: `%s'", Arg); } } +static void OptDataName (const char* Opt, const char* Arg) +/* Handle the --code-name option */ +{ + /* Check for a valid name */ + CheckSegName (Arg); + + /* Set the name */ + NewSegName (SEG_DATA, Arg); +} + + + static void OptDebug (const char* Opt, const char* Arg) /* Compiler debug mode */ { @@ -312,6 +380,22 @@ static void OptDebugInfo (const char* Opt, const char* Arg) +static void OptDisableOpt (const char* Opt, const char* Arg) +/* Disable an optimization step */ +{ + DisableOpt (Arg); +} + + + +static void OptEnableOpt (const char* Opt, const char* Arg) +/* Enable an optimization step */ +{ + EnableOpt (Arg); +} + + + static void OptHelp (const char* Opt, const char* Arg) /* Print usage information and exit */ { @@ -324,14 +408,23 @@ static void OptHelp (const char* Opt, const char* Arg) static void OptIncludeDir (const char* Opt, const char* Arg) /* Add an include search path */ { - if (Arg == 0) { - NeedArg (Opt); - } AddIncludePath (Arg, INC_SYS | INC_USER); } +static void OptRodataName (const char* Opt, const char* Arg) +/* Handle the --rodata-name option */ +{ + /* Check for a valid name */ + CheckSegName (Arg); + + /* Set the name */ + NewSegName (SEG_RODATA, Arg); +} + + + static void OptSignedChars (const char* Opt, const char* Arg) /* Make default characters signed */ { @@ -351,9 +444,6 @@ static void OptStaticLocals (const char* Opt, const char* Arg) static void OptTarget (const char* Opt, const char* Arg) /* Set the target system */ { - if (Arg == 0) { - NeedArg (Opt); - } SetSys (Arg); } @@ -362,7 +452,7 @@ static void OptTarget (const char* Opt, const char* Arg) static void OptVerbose (const char* Opt, const char* Arg) /* Increase verbosity */ { - ++Verbose; + ++Verbosity; } @@ -381,18 +471,27 @@ int main (int argc, char* argv[]) { /* Program long options */ static const LongOpt OptTab[] = { - { "--add-source", 0, OptAddSource }, - { "--ansi", 0, OptAnsi }, - { "--cpu", 1, OptCPU }, - { "--debug", 0, OptDebug }, - { "--debug-info", 0, OptDebugInfo }, - { "--help", 0, OptHelp }, + { "--add-source", 0, OptAddSource }, + { "--ansi", 0, OptAnsi }, + { "--bss-name", 1, OptBssName }, + { "--check-stack", 0, OptCheckStack }, + { "--code-name", 1, OptCodeName }, + { "--codesize", 1, OptCodeSize }, + { "--create-dep", 0, OptCreateDep }, + { "--cpu", 1, OptCPU }, + { "--data-name", 1, OptDataName }, + { "--debug", 0, OptDebug }, + { "--debug-info", 0, OptDebugInfo }, + { "--disable-opt", 1, OptDisableOpt }, + { "--enable-opt", 1, OptEnableOpt, }, + { "--help", 0, OptHelp }, { "--include-dir", 1, OptIncludeDir }, - { "--signed-chars", 0, OptSignedChars }, - { "--static-locals", 0, OptStaticLocals }, - { "--target", 1, OptTarget }, - { "--verbose", 0, OptVerbose }, - { "--version", 0, OptVersion }, + { "--rodata-name", 1, OptRodataName }, + { "--signed-chars", 0, OptSignedChars }, + { "--static-locals", 0, OptStaticLocals }, + { "--target", 1, OptTarget }, + { "--verbose", 0, OptVerbose }, + { "--version", 0, OptVersion }, }; int I; @@ -402,16 +501,19 @@ int main (int argc, char* argv[]) const char* InputFile = 0; /* Initialize the cmdline module */ - InitCmdLine (argc, argv, "cc65"); + InitCmdLine (&argc, &argv, "cc65"); + + /* Initialize the default segment names */ + InitSegNames (); /* Parse the command line */ I = 1; - while (I < argc) { + while (I < (int)ArgCount) { const char* P; /* Get the argument */ - const char* Arg = argv [I]; + const char* Arg = ArgVec[I]; /* Check for an option */ if (Arg [0] == '-') { @@ -447,6 +549,10 @@ int main (int argc, char* argv[]) OptTarget (Arg, GetArg (&I, 2)); break; + case 'u': + OptCreateDep (Arg, 0); + break; + case 'v': OptVerbose (Arg, 0); break; @@ -462,9 +568,9 @@ int main (int argc, char* argv[]) case 'l': OptStaticLocals (Arg, 0); break; - default: - UnknownOption (Arg); - break; + default: + UnknownOption (Arg); + break; } } break; @@ -479,21 +585,22 @@ int main (int argc, char* argv[]) case 'O': Optimize = 1; - P = Arg + 2; + P = Arg + 2; while (*P) { switch (*P++) { - case 'f': - sscanf (P, "%lx", (long*) &OptDisable); + case 'f': + sscanf (P, "%lx", (long*) &OptDisable); break; case 'i': FavourSize = 0; + CodeSizeFactor = 200; break; case 'r': - EnableRegVars = 1; - break; + EnableRegVars = 1; + break; case 's': InlineStdFuncs = 1; - break; + break; } } break; @@ -528,35 +635,33 @@ int main (int argc, char* argv[]) /* Did we have a file spec on the command line? */ if (InputFile == 0) { - fprintf (stderr, "%s: No input files\n", argv [0]); - exit (EXIT_FAILURE); + AbEnd ("No input files"); } - /* Open the input file */ - OpenMainFile (InputFile); - /* Create the output file name if it was not explicitly given */ if (OutputFile == 0) { OutputFile = MakeFilename (InputFile, ".s"); } /* Go! */ - Compile (); + Compile (InputFile); /* Create the output file if we didn't had any errors */ if (ErrorCount == 0 || Debug) { FILE* F; - /* Optimize the output if requested */ - if (Optimize) { - OptDoOpt (); - } +#if 0 + /* Optimize the output if requested */ + if (Optimize) { + OptDoOpt (); + } +#endif /* Open the file */ F = fopen (OutputFile, "w"); if (F == 0) { - Fatal (FAT_CANNOT_OPEN_OUTPUT, strerror (errno)); + Fatal ("Cannot open output file `%s': %s", OutputFile, strerror (errno)); } /* Write the output to the file */ @@ -565,8 +670,14 @@ int main (int argc, char* argv[]) /* Close the file, check for errors */ if (fclose (F) != 0) { remove (OutputFile); - Fatal (FAT_CANNOT_WRITE_OUTPUT); + Fatal ("Cannot write to output file (disk full?)"); } + + /* Create dependencies if requested */ + if (CreateDep) { + DoCreateDep (OutputFile); + } + } /* Return an apropriate exit code */