/* */
/* */
/* */
-/* (C) 2000 Ullrich von Bassewitz */
+/* (C) 2000-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
-#include <ctype.h>
#include <errno.h>
-#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 "cpu.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 "segname.h"
"\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\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"
" --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"
-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;
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:
- fputs ("Unknown system type\n", stderr);
- exit (EXIT_FAILURE);
+ default:
+ AbEnd ("Unknown target system type");
}
+
+ /* 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);
}
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;
}
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
*/
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';
+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 */
{
+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 */
{
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 */
{
static void OptTarget (const char* Opt, const char* Arg)
/* Set the target system */
{
- if (Arg == 0) {
- NeedArg (Opt);
- }
SetSys (Arg);
}
static void OptVerbose (const char* Opt, const char* Arg)
/* Increase verbosity */
{
- ++Verbose;
+ ++Verbosity;
}
{
/* 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 },
+ { "--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;
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] == '-') {
OptTarget (Arg, GetArg (&I, 2));
break;
+ case 'u':
+ OptCreateDep (Arg, 0);
+ break;
+
case 'v':
OptVerbose (Arg, 0);
break;
case 'l':
OptStaticLocals (Arg, 0);
break;
- default:
- UnknownOption (Arg);
- break;
+ default:
+ UnknownOption (Arg);
+ break;
}
}
break;
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;
+ break;
case 's':
InlineStdFuncs = 1;
- break;
+ break;
}
}
break;
/* 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 */
OutputFile = MakeFilename (InputFile, ".s");
}
+
+
+
/* Go! */
Compile ();
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 */
/* 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 */