/* */
/* */
/* */
-/* (C) 1998 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2000 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <stdio.h>
#include <string.h>
-#include "../common/version.h"
-#include "../common/xmalloc.h"
+/* common */
+#include "version.h"
+#include "xmalloc.h"
+/* cc65 */
#include "asmcode.h"
#include "asmlabel.h"
#include "check.h"
#include "global.h"
#include "litpool.h"
#include "optimize.h"
+#include "segname.h"
#include "util.h"
#include "codegen.h"
-
+
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/* Compiler relative stk ptr */
-int oursp = 0;
+int oursp = 0;
/* Current segment */
-static enum {
- SEG_INV = -1, /* Invalid segment */
- SEG_CODE,
- SEG_RODATA,
- SEG_DATA,
- SEG_BSS
-} CurSeg = SEG_CODE;
+segment_t CurSeg = SEG_INV;
/* Segment names */
-static char* SegmentNames [4];
static char* SegmentHints [4] = {
"seg:code", "seg:rodata", "seg:data", "seg:bss"
};
/* Allow auto import for runtime library routines */
AddCodeLine (".autoimport\ton");
- /* Switch the assembler into case sensible mode */
+ /* Switch the assembler into case sensitive mode */
AddCodeLine (".case\t\ton");
/* Tell the assembler if we want to generate debug info */
AddCodeLine (".endmacro");
AddEmptyLine ();
- /* Define the default names for the segments */
- SegmentNames [SEG_CODE] = xstrdup ("CODE");
- SegmentNames [SEG_RODATA] = xstrdup ("RODATA");
- SegmentNames [SEG_DATA] = xstrdup ("DATA");
- SegmentNames [SEG_BSS] = xstrdup ("BSS");
-
/* Tell the optimizer that this is the end of the preamble */
AddCodeHint ("end_of_preamble");
}
-static void SegName (int Seg, const char* Name)
+static void SegName (segment_t Seg, const char* Name)
/* Set the name of a segment */
{
/* Free the old name and set a new one */
- xfree (SegmentNames [Seg]);
- SegmentNames [Seg] = xstrdup (Name);
+ NewSegName (Seg, Name);
/* If the new segment is the current segment, emit a segment directive
* with the new name.
#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 "cmdline.h"
+#include "fname.h"
+#include "version.h"
+#include "xmalloc.h"
+
+/* cc65 */
#include "asmcode.h"
#include "compile.h"
#include "cpu.h"
#include "macrotab.h"
#include "optimize.h"
#include "scanner.h"
+#include "segname.h"
"\n"
"Long options:\n"
" --ansi\t\tStrict ANSI mode\n"
+ " --bss-name seg\tSet the name of the BSS segment\n"
+ " --code-name seg\tSet the name of the CODE segment\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"
break;
case TGT_PET:
- cbmsys ("__PET__");
- break;
+ cbmsys ("__PET__");
+ break;
- case TGT_NES:
- AddNumericMacro ("__NES__", 1);
- break;
+ case TGT_NES:
+ AddNumericMacro ("__NES__", 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");
}
}
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
+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 */
+{
+ /* Must have a segment name */
+ if (Arg == 0) {
+ NeedArg (Opt);
+ }
+
+ /* Check for a valid name */
+ CheckSegName (Arg);
+
+ /* Set the name */
+ NewSegName (SEG_BSS, Arg);
+}
+
+
+
+static void OptCodeName (const char* Opt, const char* Arg)
+/* Handle the --code-name option */
+{
+ /* Must have a segment name */
+ if (Arg == 0) {
+ NeedArg (Opt);
+ }
+
+ /* Check for a valid name */
+ CheckSegName (Arg);
+
+ /* Set the name */
+ NewSegName (SEG_CODE, Arg);
+}
+
+
+
static void OptCPU (const char* Opt, const char* Arg)
/* Handle the --cpu option */
{
} 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 */
+{
+ /* Must have a segment name */
+ if (Arg == 0) {
+ NeedArg (Opt);
}
+
+ /* Check for a valid name */
+ CheckSegName (Arg);
+
+ /* Set the name */
+ NewSegName (SEG_DATA, Arg);
}
+static void OptRodataName (const char* Opt, const char* Arg)
+/* Handle the --rodata-name option */
+{
+ /* Must have a segment name */
+ if (Arg == 0) {
+ NeedArg (Opt);
+ }
+
+ /* 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 const LongOpt OptTab[] = {
{ "--add-source", 0, OptAddSource },
{ "--ansi", 0, OptAnsi },
+ { "--bss-name", 1, OptBssName },
+ { "--code-name", 1, OptCodeName },
{ "--cpu", 1, OptCPU },
+ { "--data-name", 1, OptDataName },
{ "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo },
{ "--help", 0, OptHelp },
{ "--include-dir", 1, OptIncludeDir },
+ { "--rodata-name", 1, OptRodataName },
{ "--signed-chars", 0, OptSignedChars },
{ "--static-locals", 0, OptStaticLocals },
{ "--target", 1, OptTarget },
/* Initialize the cmdline module */
InitCmdLine (argc, argv, "cc65");
+ /* Initialize the default segment names */
+ InitSegNames ();
+
/* Parse the command line */
I = 1;
while (I < argc) {
/* 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 */
preproc.o \
pragma.o \
scanner.o \
+ segname.o \
stdfunc.o \
stmt.o \
symentry.o \
preproc.obj \
stmt.obj \
scanner.obj \
+ segname.obj \
stdfunc.obj \
symentry.obj \
symtab.obj \
FILE preproc.obj
FILE stmt.obj
FILE scanner.obj
+FILE segname.obj
FILE stdfunc.obj
FILE symentry.obj
FILE symtab.obj
--- /dev/null
+/*****************************************************************************/
+/* */
+/* segname.c */
+/* */
+/* Segment name management */
+/* */
+/* */
+/* */
+/* (C) 2000 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#include <ctype.h>
+
+/* common */
+#include "xmalloc.h"
+
+/* cc65 */
+#include "check.h"
+#include "segname.h"
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Actual names for the segments */
+char* SegmentNames[SEG_COUNT];
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void InitSegNames (void)
+/* Initialize the segment names */
+{
+ SegmentNames [SEG_BSS] = xstrdup ("BSS");
+ SegmentNames [SEG_CODE] = xstrdup ("CODE");
+ SegmentNames [SEG_DATA] = xstrdup ("DATA");
+ SegmentNames [SEG_RODATA] = xstrdup ("RODATA");
+}
+
+
+
+void NewSegName (segment_t Seg, const char* Name)
+/* Set a new name for a segment */
+{
+ /* Check the parameter */
+ CHECK (Seg != SEG_INV);
+
+ /* Free the old name and set a new one */
+ xfree (SegmentNames [Seg]);
+ SegmentNames [Seg] = xstrdup (Name);
+}
+
+
+
+int ValidSegName (const char* Name)
+/* Return true if the given segment name is valid, return false otherwise */
+{
+ /* Must start with '_' or a letter */
+ if (*Name != '_' && !isalpha(*Name)) {
+ return 0;
+ }
+
+ /* Can have letters, digits or the underline */
+ while (*++Name) {
+ if (*Name != '_' && !isalnum(*Name)) {
+ return 0;
+ }
+ }
+
+ /* Name is ok */
+ return 1;
+}
+
+
+
--- /dev/null
+/*****************************************************************************/
+/* */
+/* segname.h */
+/* */
+/* Segment name management */
+/* */
+/* */
+/* */
+/* (C) 2000 Ullrich von Bassewitz */
+/* Wacholderweg 14 */
+/* D-70597 Stuttgart */
+/* EMail: uz@musoftware.de */
+/* */
+/* */
+/* This software is provided 'as-is', without any expressed or implied */
+/* warranty. In no event will the authors be held liable for any damages */
+/* arising from the use of this software. */
+/* */
+/* Permission is granted to anyone to use this software for any purpose, */
+/* including commercial applications, and to alter it and redistribute it */
+/* freely, subject to the following restrictions: */
+/* */
+/* 1. The origin of this software must not be misrepresented; you must not */
+/* claim that you wrote the original software. If you use this software */
+/* in a product, an acknowledgment in the product documentation would be */
+/* appreciated but is not required. */
+/* 2. Altered source versions must be plainly marked as such, and must not */
+/* be misrepresented as being the original software. */
+/* 3. This notice may not be removed or altered from any source */
+/* distribution. */
+/* */
+/*****************************************************************************/
+
+
+
+#ifndef SEGNAME_H
+#define SEGNAME_H
+
+
+
+/*****************************************************************************/
+/* Data */
+/*****************************************************************************/
+
+
+
+/* Current segment */
+typedef enum segment_t {
+ SEG_INV = -1, /* Invalid segment */
+ SEG_CODE,
+ SEG_RODATA,
+ SEG_DATA,
+ SEG_BSS,
+ SEG_COUNT
+} segment_t;
+
+/* Actual names for the segments */
+extern char* SegmentNames[SEG_COUNT];
+
+
+
+/*****************************************************************************/
+/* Code */
+/*****************************************************************************/
+
+
+
+void InitSegNames (void);
+/* Initialize the segment names */
+
+void NewSegName (segment_t Seg, const char* Name);
+/* Set a new name for a segment */
+
+int ValidSegName (const char* Name);
+/* Return true if the given segment name is valid, return false otherwise */
+
+
+
+/* End of segname.h */
+
+#endif
+
+
+