ref: 80e2129f2219d6a458591117c91320a8a4fb4c8d
parent: af70f03933abf02f218044ccc954417eb0e94663
parent: 25efb00769cb1a16fe3ab643e4b63d33402a5bcc
author: stag019 <[email protected]>
date: Sat Nov 1 21:00:20 EDT 2014
Merge https://github.com/bentley/rgbds Conflicts: include/lib/types.h src/asm/symbol.c
--- a/LICENSE
+++ b/LICENSE
@@ -1,5 +1,5 @@
-rgbasm, rgblink, and rgblib are derived from Justin Lloyd's RGBDS, which
-is released under the following license:
+rgbasm and rgblink are derived from Justin Lloyd's RGBDS, which is
+released under the following license:
DO WHATEVER PUBLIC LICENSE*
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@@ -17,3 +17,9 @@
rgbfix was rewritten from scratch by Anthony J. Bentley, and is released
under the ISC license; see the source file for the text of the license.
+
+extern/err.c is derived from the Musl C library, http://www.musl-libc.org,
+and is released under the MIT license.
+
+extern/strl.c is derived from the OpenBSD Project, http://www.openbsd.org,
+and is released under the BSD license.
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,7 @@
-CFLAGS += -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99
+.POSIX:
+REALCFLAGS = ${CFLAGS} -Wall -Iinclude -Iinclude/asm/gameboy -g -std=c99
+
# User-defined variables
PREFIX = /usr/local
BINPREFIX = ${PREFIX}/bin
@@ -13,7 +15,6 @@
src/asm/gameboy/yaccprt4.y
rgbasm_obj := \
- src/asm/alloca.o \
src/asm/asmy.o \
src/asm/charmap.o \
src/asm/fstack.o \
@@ -24,12 +25,11 @@
src/asm/output.o \
src/asm/rpn.o \
src/asm/symbol.o \
- src/asm/gameboy/locallex.o
+ src/asm/gameboy/locallex.o \
+ src/extern/err.o \
+ src/extern/strlcpy.o \
+ src/extern/strlcat.o
-rgblib_obj := \
- src/lib/library.o \
- src/lib/main.o
-
rgblink_obj := \
src/link/assign.o \
src/link/library.o \
@@ -38,61 +38,53 @@
src/link/object.o \
src/link/output.o \
src/link/patch.o \
- src/link/symbol.o
+ src/link/symbol.o \
+ src/extern/err.o
rgbfix_obj := \
- src/fix/main.o
+ src/fix/main.o \
+ src/extern/err.o
-all: rgbasm rgblib rgblink rgbfix
+all: rgbasm rgblink rgbfix
clean:
- ${Q}rm -rf rgbds.html
- ${Q}rm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html
- ${Q}rm -rf rgblib rgblib.exe ${rgblib_obj} rgblib.html
- ${Q}rm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html
- ${Q}rm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html
- ${Q}rm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y
+ $Qrm -rf rgbds.html
+ $Qrm -rf rgbasm rgbasm.exe ${rgbasm_obj} rgbasm.html
+ $Qrm -rf rgblink rgblink.exe ${rgblink_obj} rgblink.html
+ $Qrm -rf rgbfix rgbfix.exe ${rgbfix_obj} rgbfix.html
+ $Qrm -rf src/asm/asmy.c src/asm/asmy.h src/asm/asmy.y
install: all
- ${Q}install -s -m 555 rgbasm ${BINPREFIX}/rgbasm
- ${Q}install -s -m 555 rgbfix ${BINPREFIX}/rgbfix
- ${Q}install -s -m 555 rgblink ${BINPREFIX}/rgblink
- ${Q}install -s -m 555 rgblib ${BINPREFIX}/rgblib
- ${Q}install -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7 || \
- (echo Installing manpages to ${MANPREFIX} failed. >&2 && \
- echo Check where your manpages are installed and set the \
- proper directory >&2 && \
- echo with, e.g., make install MANPREFIX=/usr/share/man \
- >&2 ; false)
- ${Q}install -m 444 src/asm/rgbasm.1 \
- ${MANPREFIX}/man1/rgbasm.1
- ${Q}install -m 444 src/fix/rgbfix.1 \
- ${MANPREFIX}/man1/rgbfix.1
- ${Q}install -m 444 src/link/rgblink.1 \
- ${MANPREFIX}/man1/rgblink.1
- ${Q}install -m 444 src/lib/rgblib.1 \
- ${MANPREFIX}/man1/rgblib.1
+ $Qmkdir -p ${BINPREFIX}
+ $Qinstall -s -m 555 rgbasm ${BINPREFIX}/rgbasm
+ $Qinstall -s -m 555 rgbfix ${BINPREFIX}/rgbfix
+ $Qinstall -s -m 555 rgblink ${BINPREFIX}/rgblink
+ $Qmkdir -p ${MANPREFIX}/man1 ${MANPREFIX}/man7
+ $Qinstall -m 444 src/rgbds.7 ${MANPREFIX}/man7/rgbds.7
+ $Qinstall -m 444 src/asm/rgbasm.1 ${MANPREFIX}/man1/rgbasm.1
+ $Qinstall -m 444 src/fix/rgbfix.1 ${MANPREFIX}/man1/rgbfix.1
+ $Qinstall -m 444 src/link/rgblink.1 ${MANPREFIX}/man1/rgblink.1
rgbasm: ${rgbasm_obj}
- ${Q}${CC} ${CFLAGS} -o $@ ${rgbasm_obj} -lm
+ $Q${CC} ${REALCFLAGS} -o $@ ${rgbasm_obj} -lm
-rgblib: ${rgblib_obj}
- ${Q}${CC} ${CFLAGS} -o $@ ${rgblib_obj}
-
rgblink: ${rgblink_obj}
- ${Q}${CC} ${CFLAGS} -o $@ ${rgblink_obj}
+ $Q${CC} ${REALCFLAGS} -o $@ ${rgblink_obj}
rgbfix: ${rgbfix_obj}
- ${Q}${CC} ${CFLAGS} -o $@ ${rgbfix_obj}
+ $Q${CC} ${REALCFLAGS} -o $@ ${rgbfix_obj}
+.y.c:
+ $Q${YACC} -d ${YFLAGS} -o $@ $<
+
.c.o:
- ${Q}${CC} ${CFLAGS} -c -o $@ $<
+ $Q${CC} ${REALCFLAGS} -c -o $@ $<
-src/asm/asmy.c: src/asm/asmy.y
- ${Q}${YACC} -d -o $@ $<
+src/asm/gameboy/locallex.o src/asm/globlex.o src/asm/lexer.o: src/asm/asmy.h
+src/asm/asmy.h: src/asm/asmy.c
src/asm/asmy.y: ${yacc_pre}
- ${Q}cat ${yacc_pre} > $@
+ $Qcat ${yacc_pre} > $@
# Below is a target for the project maintainer to easily create win32 exes.
@@ -100,19 +92,23 @@
# If you're building on Windows with Cygwin or Mingw, just follow the Unix
# install instructions instead.
mingw:
- ${Q}env PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin make CC=gcc CFLAGS="-I/usr/local/mingw32/include ${CFLAGS}"
- ${Q}mv rgbasm rgbasm.exe
- ${Q}mv rgblib rgblib.exe
- ${Q}mv rgblink rgblink.exe
- ${Q}mv rgbfix rgbfix.exe
+ $Qenv PATH=/usr/local/mingw32/bin:/bin:/usr/bin:/usr/local/bin \
+ make CC=gcc CFLAGS="-I/usr/local/mingw32/include \
+ -D__progname=\\\"\\\" ${CFLAGS}"
+ $Qmv rgbasm rgbasm.exe
+ $Qmv rgblink rgblink.exe
+ $Qmv rgbfix rgbfix.exe
# Below is a target for the project maintainer to easily create web manuals.
# It relies on mandoc: http://mdocml.bsd.lv
-MANDOC = -Thtml -Oman=/rgbds/manual/%N/ -Ostyle=/rgbds/manual/manual.css -Ios=General
+MANDOC = -Thtml -Ios=General -Oman=/rgbds/manual/%N/ \
+ -Ostyle=/rgbds/manual/manual.css
wwwman:
- ${Q}mandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html
- ${Q}mandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > rgbasm.html
- ${Q}mandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > rgbfix.html
- ${Q}mandoc ${MANDOC} src/lib/rgblib.1 | sed s/OpenBSD/General/ > rgblib.html
- ${Q}mandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > rgblink.html
+ $Qmandoc ${MANDOC} src/rgbds.7 | sed s/OpenBSD/General/ > rgbds.html
+ $Qmandoc ${MANDOC} src/asm/rgbasm.1 | sed s/OpenBSD/General/ > \
+ rgbasm.html
+ $Qmandoc ${MANDOC} src/fix/rgbfix.1 | sed s/OpenBSD/General/ > \
+ rgbfix.html
+ $Qmandoc ${MANDOC} src/link/rgblink.1 | sed s/OpenBSD/General/ > \
+ rgblink.html
--- a/README
+++ b/README
@@ -7,7 +7,6 @@
- rgbasm (assembler)
- rgblink (linker)
- - rgblib (library manager)
- rgbfix (checksum/header fixer)
rgbds-linux is a fork of the original RGBDS which aims to make the programs
--- a/doc/index.htm
+++ b/doc/index.htm
@@ -12,7 +12,6 @@
<li><a href="geninfo.htm">ASMotor General Information</a>
<li><a href="asm.htm">xASM Documentation</a>
<li><a href="link.htm">xLink Documentation</a>
- <li><a href="lib.htm">xLib Documentation</a>
<li><a href="fix.htm">RGBFix Documentation</a>
<li><a href="rgb0.htm">The RGB0-2 ObjectFileFormat</a>
</ul>
--- a/doc/lib.htm
+++ /dev/null
@@ -1,47 +1,0 @@
-<!DOCTYPE HTML PUBliC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
- <title>xLib</title>
- <link rel="stylesheet" type="text/css" href="./style.css">
-</head>
-<body>
-<h1>xLib Documentation</h1>
-<h2>Table of Contents</h2>
-<ul>
-<li><a href="#history"> History</A>
-<li><a href="#usage"> Usage</A>
-<li><a href="#commands"> The commands</A>
-</ul>
-<hr>
-<h2 id="history">History</h2>
-<table>
- <caption>The history of xLib</caption>
-<thead>
-<tr>
- <th scope="col">Version</th>
- <th scope="col">Dated</th>
- <th scope="col">Release notes</th>
-</tr>
-</thead>
-<tr>
- <td>1.0</td>
- <td>21 Sep. 1997</td>
- <td>First release</td>
-</tr>
-</table>
-<h2 id="usage">Usage</h2>
-<pre> xlib library command [module1 module2 ... modulen]</pre>
-<h2 id="commands">The Commands</h2>
-<p>The <b>command</b> specified after <b>library</b> on the <a href="#Usage">commandline</a> tells xLib what to do.
-<p>The following commands are available:
-<ul>
- <li>a — Adds (or replaces if already present) the modules to the library
- <li>d — Deletes the modules specified from the library
- <li>l — Lists the library contents
- <li>x — Extracts the modules from the library
-</ul>
-<hr>
-<p>Last updated 21 September 1997 by <a href="mailto:[email protected]">Carsten Sorensen</a></p>
-</body>
-</html>
--- a/include/asm/asm.h
+++ b/include/asm/asm.h
@@ -17,8 +17,6 @@
#include "localasm.h"
-#include "asmotor.h"
-
extern SLONG nLineNo;
extern ULONG nTotalLines;
extern ULONG nPC;
--- a/include/asm/fstack.h
+++ b/include/asm/fstack.h
@@ -9,6 +9,8 @@
#ifndef ASMOTOR_ASM_FSTACK_H
#define ASMOTOR_ASM_FSTACK_H
+#include <stdio.h>
+
#include "asm/asm.h"
#include "asm/types.h"
#include "asm/lexer.h"
@@ -27,14 +29,17 @@
ULONG nREPTBlockSize;
};
-extern ULONG fstk_RunInclude(char *s);
+void
+fstk_RunInclude(char *);
extern void fstk_RunMacroArg(SLONG s);
-extern ULONG fstk_Init(char *s);
+void
+fstk_Init(char *);
extern void fstk_Dump(void);
extern void fstk_AddIncludePath(char *s);
extern ULONG fstk_RunMacro(char *s);
extern void fstk_RunRept(ULONG count);
-extern void fstk_FindFile(char *s);
+FILE *
+fstk_FindFile(char *);
extern int yywrap(void);
--- a/include/asm/lexer.h
+++ b/include/asm/lexer.h
@@ -5,7 +5,8 @@
#include "asm/types.h"
-#define LEXHASHSIZE 512
+#define LEXHASHSIZE (1 << 11)
+#define MAXSTRLEN 255
struct sLexInitString {
char *tzName;
@@ -18,7 +19,9 @@
};
struct yy_buffer_state {
- char *pBufferStart;
+ char *pBufferRealStart; // actual starting address
+ char *pBufferStart; // address where the data is initially written
+ // after the "safety margin"
char *pBuffer;
ULONG nBufferSize;
ULONG oAtLineStart;
--- a/include/asm/symbol.h
+++ b/include/asm/symbol.h
@@ -3,7 +3,7 @@
#include "asm/types.h"
-#define HASHSIZE 73
+#define HASHSIZE (1 << 16)
#define MAXSYMLEN 256
struct sSymbol {
@@ -35,6 +35,7 @@
#define SYMF_CONST 0x200 /* symbol has a constant value, will
* not be changed during linking */
+ULONG calchash(char *s);
void sym_PrepPass1(void);
void sym_PrepPass2(void);
void sym_AddLocalReloc(char *tzSym);
--- a/include/asmotor.h
+++ /dev/null
@@ -1,21 +1,0 @@
-/* asmotor.h
- *
- * Contains defines for every program in the ASMotor package
- *
- * Copyright 1997 Carsten Sorensen
- *
- */
-
-#ifndef ASMOTOR_ASMOTOR_H
-#define ASMOTOR_ASMOTOR_H
-
-#define ASMOTOR
-
-#define ASMOTOR_VERSION "1.10-linux"
-
-#define ASM_VERSION "1.08c"
-#define LINK_VERSION "1.06c"
-#define RGBFIX_VERSION "1.02"
-#define LIB_VERSION "1.00"
-
-#endif
--- /dev/null
+++ b/include/extern/err.h
@@ -1,0 +1,63 @@
+/*
+ * Copyright © 2005-2013 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef EXTERN_ERR_H
+#define EXTERN_ERR_H
+
+#ifdef ERR_IN_LIBC
+#include <err.h>
+#else
+
+#include <stdarg.h>
+
+#define warn rgbds_warn
+#define vwarn rgbds_vwarn
+#define warnx rgbds_warnx
+#define vwarnx rgbds_vwarnx
+
+#define err rgbds_err
+#define verr rgbds_verr
+#define errx rgbds_errx
+#define verrx rgbds_verrx
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void warn(const char *, ...);
+void vwarn(const char *, va_list);
+void warnx(const char *, ...);
+void vwarnx(const char *, va_list);
+
+void err(int, const char *, ...);
+void verr(int, const char *, va_list);
+void errx(int, const char *, ...);
+void verrx(int, const char *, va_list);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
--- /dev/null
+++ b/include/extern/strl.h
@@ -1,0 +1,13 @@
+#ifndef STRL_H
+#define STRL_H
+
+#ifdef STRL_IN_LIBC
+#include <string.h>
+#else
+#define strlcpy rgbds_strlcpy
+#define strlcat rgbds_strlcat
+size_t strlcpy(char *, const char *, size_t);
+size_t strlcat(char *, const char *, size_t);
+#endif
+
+#endif
--- a/include/lib/library.h
+++ /dev/null
@@ -1,13 +1,0 @@
-#ifndef ASMOTOR_LIB_LIBRARY_H
-#define ASMOTOR_LIB_LIBRARY_H
-
-#include "lib/libwrap.h"
-
-extern sLibrary *lib_Read(char *filename);
-extern BBOOL lib_Write(sLibrary * lib, char *filename);
-extern sLibrary *lib_AddReplace(sLibrary * lib, char *filename);
-extern void lib_Free(sLibrary * lib);
-extern sLibrary *lib_DeleteModule(sLibrary * lib, char *filename);
-extern sLibrary *lib_Find(sLibrary * lib, char *filename);
-
-#endif
--- a/include/lib/libwrap.h
+++ /dev/null
@@ -1,19 +1,0 @@
-#ifndef ASMOTOR_LIB_LIBWRAP_H
-#define ASMOTOR_LIB_LIBWRAP_H
-
-#include "lib/types.h"
-
-#define MAXNAMELENGTH 256
-
-struct LibraryWrapper {
- char tName[MAXNAMELENGTH];
- UWORD uwTime;
- UWORD uwDate;
- SLONG nByteLength;
- UBYTE *pData;
- struct LibraryWrapper *pNext;
-};
-
-typedef struct LibraryWrapper sLibrary;
-
-#endif
--- a/include/lib/types.h
+++ /dev/null
@@ -1,16 +1,0 @@
-#ifndef ASMOTOR_LIB_TYPES_H
-#define ASMOTOR_LIB_TYPES_H
-
-#ifndef _MAX_PATH
-#define _MAX_PATH 512
-#endif
-
-typedef unsigned char UBYTE;
-typedef signed char SBYTE;
-typedef unsigned short UWORD;
-typedef signed short SWORD;
-typedef unsigned long ULONG;
-typedef signed long SLONG;
-typedef signed char BBOOL;
-
-#endif
--- a/include/link/object.h
+++ b/include/link/object.h
@@ -2,6 +2,5 @@
#define ASMOTOR_LINK_OBJECT_H
extern void obj_Readfile(char *tzObjectfile);
-extern void lib_Readfile(char *tzLibfile);
#endif
--- a/src/asm/alloca.c
+++ /dev/null
@@ -1,466 +1,0 @@
-/* alloca.c -- allocate automatically reclaimed memory
- (Mostly) portable public-domain implementation -- D A Gwyn
-
- This implementation of the PWB library alloca function,
- which is used to allocate space off the run-time stack so
- that it is automatically reclaimed upon procedure exit,
- was inspired by discussions with J. Q. Johnson of Cornell.
- J.Otto Tennant <[email protected]> contributed the Cray support.
-
- There are some preprocessor constants that can
- be defined when compiling for your specific system, for
- improved efficiency; however, the defaults should be okay.
-
- The general concept of this implementation is to keep
- track of all alloca-allocated blocks, and reclaim any
- that are found to be deeper in the stack than the current
- invocation. This heuristic does not reclaim storage as
- soon as it becomes invalid, but it will do so eventually.
-
- As a special case, alloca(0) reclaims storage without
- allocating any. It is a good idea to use alloca(0) in
- your main control loop, etc. to force garbage collection. */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef emacs
-#include "blockinput.h"
-#endif
-
-/* If compiling with GCC 2, this file's not needed. */
-#if !defined (__GNUC__) || __GNUC__ < 2
-
-/* If someone has defined alloca as a macro,
- there must be some other way alloca is supposed to work. */
-#ifndef alloca
-
-#ifdef emacs
-#ifdef static
-/* actually, only want this if static is defined as ""
- -- this is for usg, in which emacs must undefine static
- in order to make unexec workable
- */
-#ifndef STACK_DIRECTION
-you lose-- must know STACK_DIRECTION at compile - time
-#endif /* STACK_DIRECTION undefined */
-#endif /* static */
-#endif /* emacs */
-/* If your stack is a linked list of frames, you have to
- provide an "address metric" ADDRESS_FUNCTION macro. */
-#if defined (CRAY) && defined (CRAY_STACKSEG_END)
-long i00afunc();
-#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
-#else
-#define ADDRESS_FUNCTION(arg) &(arg)
-#endif
-#if __STDC__
- typedef void *pointer;
-#else
- typedef char *pointer;
-#endif
-
-#define NULL 0
-
-/* Different portions of Emacs need to call different versions of
- malloc. The Emacs executable needs alloca to call xmalloc, because
- ordinary malloc isn't protected from input signals. On the other
- hand, the utilities in lib-src need alloca to call malloc; some of
- them are very simple, and don't have an xmalloc routine.
-
- Non-Emacs programs expect this to call use xmalloc.
-
- Callers below should use malloc. */
-
-/* Carsten Sorensen 09/09/97
- * Commented out the following, I want malloc!
-#ifndef emacs
-#define malloc xmalloc
-#endif
-extern pointer malloc ();
- And added the following line:
- */
-#include <stdlib.h>
-
-/* Define STACK_DIRECTION if you know the direction of stack
- growth for your system; otherwise it will be automatically
- deduced at run-time.
-
- STACK_DIRECTION > 0 => grows toward higher addresses
- STACK_DIRECTION < 0 => grows toward lower addresses
- STACK_DIRECTION = 0 => direction of growth unknown */
-
-#ifndef STACK_DIRECTION
-#define STACK_DIRECTION 0 /* Direction unknown. */
-#endif
-
-#if STACK_DIRECTION != 0
-
-#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
-
-#else /* STACK_DIRECTION == 0; need run-time code. */
-
-static int stack_dir; /* 1 or -1 once known. */
-#define STACK_DIR stack_dir
-
-static void
-find_stack_direction()
-{
- static char *addr = NULL; /* Address of first `dummy', once
- * known. */
- auto char dummy; /* To get stack address. */
-
- if (addr == NULL) { /* Initial entry. */
- addr = ADDRESS_FUNCTION(dummy);
-
- find_stack_direction(); /* Recurse once. */
- } else {
- /* Second entry. */
- if (ADDRESS_FUNCTION(dummy) > addr)
- stack_dir = 1; /* Stack grew upward. */
- else
- stack_dir = -1; /* Stack grew downward. */
- }
-}
-#endif /* STACK_DIRECTION == 0 */
-
-/* An "alloca header" is used to:
- (a) chain together all alloca'ed blocks;
- (b) keep track of stack depth.
-
- It is very important that sizeof(header) agree with malloc
- alignment chunk size. The following default should work okay. */
-
-#ifndef ALIGN_SIZE
-#define ALIGN_SIZE sizeof(double)
-#endif
-
-typedef union hdr {
- char align[ALIGN_SIZE]; /* To force sizeof(header). */
- struct {
- union hdr *next;/* For chaining headers. */
- char *deep; /* For stack depth measure. */
- } h;
-} header;
-
-static header *last_alloca_header = NULL; /* -> last alloca header. */
-
-/* Return a pointer to at least SIZE bytes of storage,
- which will be automatically reclaimed upon exit from
- the procedure that called alloca. Originally, this space
- was supposed to be taken from the current stack frame of the
- caller, but that method cannot be made to work for some
- implementations of C, for example under Gould's UTX/32. */
-
-pointer
-alloca(size)
- unsigned size;
-{
- auto char probe; /* Probes stack depth: */
- register char *depth = ADDRESS_FUNCTION(probe);
-
-#if STACK_DIRECTION == 0
- if (STACK_DIR == 0) /* Unknown growth direction. */
- find_stack_direction();
-#endif
-
- /* Reclaim garbage, defined as all alloca'd storage that was allocated
- * from deeper in the stack than currently. */
-
- {
- register header *hp; /* Traverses linked list. */
-
-#ifdef emacs
- BLOCK_INPUT;
-#endif
-
- for (hp = last_alloca_header; hp != NULL;)
- if ((STACK_DIR > 0 && hp->h.deep > depth)
- || (STACK_DIR < 0 && hp->h.deep < depth)) {
- register header *np = hp->h.next;
-
- free((pointer) hp); /* Collect garbage. */
-
- hp = np; /* -> next header. */
- } else
- break; /* Rest are not deeper. */
-
- last_alloca_header = hp; /* -> last valid storage. */
-
-#ifdef emacs
- UNBLOCK_INPUT;
-#endif
- }
-
- if (size == 0)
- return NULL; /* No allocation required. */
-
- /* Allocate combined header + user data storage. */
-
- {
- register pointer new = malloc(sizeof(header) + size);
- /* Address of header. */
-
- ((header *) new)->h.next = last_alloca_header;
- ((header *) new)->h.deep = depth;
-
- last_alloca_header = (header *) new;
-
- /* User storage begins just after header. */
-
- return (pointer) ((char *) new + sizeof(header));
- }
-}
-#if defined (CRAY) && defined (CRAY_STACKSEG_END)
-
-#ifdef DEBUG_I00AFUNC
-#include <stdio.h>
-#endif
-
-#ifndef CRAY_STACK
-#define CRAY_STACK
-#ifndef CRAY2
-/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
-struct stack_control_header {
- long shgrow:32; /* Number of times stack has grown. */
- long shaseg:32; /* Size of increments to stack. */
- long shhwm:32; /* High water mark of stack. */
- long shsize:32; /* Current size of stack (all segments). */
-};
-/* The stack segment linkage control information occurs at
- the high-address end of a stack segment. (The stack
- grows from low addresses to high addresses.) The initial
- part of the stack segment linkage control information is
- 0200 (octal) words. This provides for register storage
- for the routine which overflows the stack. */
-
-struct stack_segment_linkage {
- long ss[0200]; /* 0200 overflow words. */
- long sssize:32; /* Number of words in this segment. */
- long ssbase:32; /* Offset to stack base. */
- long:32;
- long sspseg:32; /* Offset to linkage control of previous
- * segment of stack. */
- long:32;
- long sstcpt:32; /* Pointer to task common address block. */
- long sscsnm; /* Private control structure number for
- * microtasking. */
- long ssusr1; /* Reserved for user. */
- long ssusr2; /* Reserved for user. */
- long sstpid; /* Process ID for pid based multi-tasking. */
- long ssgvup; /* Pointer to multitasking thread giveup. */
- long sscray[7]; /* Reserved for Cray Research. */
- long ssa0;
- long ssa1;
- long ssa2;
- long ssa3;
- long ssa4;
- long ssa5;
- long ssa6;
- long ssa7;
- long sss0;
- long sss1;
- long sss2;
- long sss3;
- long sss4;
- long sss5;
- long sss6;
- long sss7;
-};
-#else /* CRAY2 */
-/* The following structure defines the vector of words
- returned by the STKSTAT library routine. */
-struct stk_stat {
- long now; /* Current total stack size. */
- long maxc; /* Amount of contiguous space which would be
- * required to satisfy the maximum stack
- * demand to date. */
- long high_water; /* Stack high-water mark. */
- long overflows; /* Number of stack overflow ($STKOFEN) calls. */
- long hits; /* Number of internal buffer hits. */
- long extends; /* Number of block extensions. */
- long stko_mallocs; /* Block allocations by $STKOFEN. */
- long underflows; /* Number of stack underflow calls ($STKRETN). */
- long stko_free; /* Number of deallocations by $STKRETN. */
- long stkm_free; /* Number of deallocations by $STKMRET. */
- long segments; /* Current number of stack segments. */
- long maxs; /* Maximum number of stack segments so far. */
- long pad_size; /* Stack pad size. */
- long current_address; /* Current stack segment address. */
- long current_size; /* Current stack segment size. This number is
- * actually corrupted by STKSTAT to include
- * the fifteen word trailer area. */
- long initial_address; /* Address of initial segment. */
- long initial_size; /* Size of initial segment. */
-};
-/* The following structure describes the data structure which trails
- any stack segment. I think that the description in 'asdef' is
- out of date. I only describe the parts that I am sure about. */
-
-struct stk_trailer {
- long this_address; /* Address of this block. */
- long this_size; /* Size of this block (does not include this
- * trailer). */
- long unknown2;
- long unknown3;
- long link; /* Address of trailer block of previous
- * segment. */
- long unknown5;
- long unknown6;
- long unknown7;
- long unknown8;
- long unknown9;
- long unknown10;
- long unknown11;
- long unknown12;
- long unknown13;
- long unknown14;
-};
-#endif /* CRAY2 */
-#endif /* not CRAY_STACK */
-
-#ifdef CRAY2
-/* Determine a "stack measure" for an arbitrary ADDRESS.
- I doubt that "lint" will like this much. */
-
-static long
-i00afunc(long *address)
-{
- struct stk_stat status;
- struct stk_trailer *trailer;
- long *block, size;
- long result = 0;
-
- /* We want to iterate through all of the segments. The first step is
- * to get the stack status structure. We could do this more quickly
- * and more directly, perhaps, by referencing the $LM00 common block,
- * but I know that this works. */
-
- STKSTAT(&status);
-
- /* Set up the iteration. */
-
- trailer = (struct stk_trailer *) (status.current_address
- + status.current_size - 15);
-
- /* There must be at least one stack segment. Therefore it is a fatal
- * error if "trailer" is null. */
-
- if (trailer == 0)
- abort();
-
- /* Discard segments that do not contain our argument address. */
-
- while (trailer != 0) {
- block = (long *) trailer->this_address;
- size = trailer->this_size;
- if (block == 0 || size == 0)
- abort();
- trailer = (struct stk_trailer *) trailer->link;
- if ((block <= address) && (address < (block + size)))
- break;
- }
-
- /* Set the result to the offset in this segment and add the sizes of
- * all predecessor segments. */
-
- result = address - block;
-
- if (trailer == 0) {
- return result;
- }
- do {
- if (trailer->this_size <= 0)
- abort();
- result += trailer->this_size;
- trailer = (struct stk_trailer *) trailer->link;
- }
- while (trailer != 0);
-
- /* We are done. Note that if you present a bogus address (one not in
- * any segment), you will get a different number back, formed from
- * subtracting the address of the first block. This is probably not
- * what you want. */
-
- return (result);
-}
-#else /* not CRAY2 */
-/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
- Determine the number of the cell within the stack,
- given the address of the cell. The purpose of this
- routine is to linearize, in some sense, stack addresses
- for alloca. */
-
-static long
-i00afunc(long address)
-{
- long stkl = 0;
-
- long size, pseg, this_segment, stack;
- long result = 0;
-
- struct stack_segment_linkage *ssptr;
-
- /* Register B67 contains the address of the end of the current stack
- * segment. If you (as a subprogram) store your registers on the
- * stack and find that you are past the contents of B67, you have
- * overflowed the segment.
- *
- * B67 also points to the stack segment linkage control area, which is
- * what we are really interested in. */
-
- stkl = CRAY_STACKSEG_END();
- ssptr = (struct stack_segment_linkage *) stkl;
-
- /* If one subtracts 'size' from the end of the segment, one has the
- * address of the first word of the segment.
- *
- * If this is not the first segment, 'pseg' will be nonzero. */
-
- pseg = ssptr->sspseg;
- size = ssptr->sssize;
-
- this_segment = stkl - size;
-
- /* It is possible that calling this routine itself caused a stack
- * overflow. Discard stack segments which do not contain the target
- * address. */
-
- while (!(this_segment <= address && address <= stkl)) {
-#ifdef DEBUG_I00AFUNC
- fprintf(stderr, "%011o %011o %011o\n", this_segment, address,
- stkl);
-#endif
- if (pseg == 0)
- break;
- stkl = stkl - pseg;
- ssptr = (struct stack_segment_linkage *) stkl;
- size = ssptr->sssize;
- pseg = ssptr->sspseg;
- this_segment = stkl - size;
- }
-
- result = address - this_segment;
-
- /* If you subtract pseg from the current end of the stack, you get the
- * address of the previous stack segment's end. This seems a little
- * convoluted to me, but I'll bet you save a cycle somewhere. */
-
- while (pseg != 0) {
-#ifdef DEBUG_I00AFUNC
- fprintf(stderr, "%011o %011o\n", pseg, size);
-#endif
- stkl = stkl - pseg;
- ssptr = (struct stack_segment_linkage *) stkl;
- size = ssptr->sssize;
- pseg = ssptr->sspseg;
- result += size;
- }
- return (result);
-}
-#endif /* not CRAY2 */
-#endif /* CRAY */
-
-#endif /* no alloca */
-#endif /* not GCC version 2 */
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -5,6 +5,8 @@
*
*/
+#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -14,7 +16,13 @@
#include "asm/types.h"
#include "asm/main.h"
#include "asm/lexer.h"
+#include "extern/err.h"
+#include "extern/strl.h"
+#ifndef PATH_MAX
+#define PATH_MAX 256
+#endif
+
/*
* RGBAsm - FSTACK.C (FileStack routines)
*
@@ -62,8 +70,7 @@
while (*ppFileStack)
ppFileStack = &((*ppFileStack)->pNext);
- if ((*ppFileStack =
- (struct sContext *) malloc(sizeof(struct sContext))) != NULL) {
+ if ((*ppFileStack = malloc(sizeof(struct sContext))) != NULL) {
(*ppFileStack)->FlexHandle = CurrentFlexHandle;
(*ppFileStack)->pNext = NULL;
strcpy((char *) (*ppFileStack)->tzFileName,
@@ -195,28 +202,33 @@
strcpy(IncludePaths[NextIncPath++], s);
}
-void
-fstk_FindFile(char *s)
+FILE *
+fstk_FindFile(char *fname)
{
- char t[_MAX_PATH + 1];
- SLONG i = -1;
+ char path[PATH_MAX];
+ int i;
+ FILE *f;
- strcpy(t, s);
+ if ((f = fopen(fname, "rb")) != NULL || errno != ENOENT) {
+ return f;
+ }
- while (i < NextIncPath) {
- FILE *f;
-
- if ((f = fopen(t, "rb")) != NULL) {
- fclose(f);
- strcpy(s, t);
- return;
+ for (i = 0; i < NextIncPath; ++i) {
+ if (strlcpy(path, IncludePaths[i], sizeof path) >=
+ sizeof path) {
+ continue;
}
- i += 1;
- if (i < NextIncPath) {
- strcpy(t, IncludePaths[i]);
- strcat(t, s);
+ if (strlcat(path, fname, sizeof path) >= sizeof path) {
+ continue;
}
+
+ if ((f = fopen(path, "rb")) != NULL || errno != ENOENT) {
+ return f;
+ }
}
+
+ errno = ENOENT;
+ return NULL;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -225,33 +237,30 @@
*
*/
-ULONG
+void
fstk_RunInclude(char *tzFileName)
{
FILE *f;
- //printf("INCLUDE: %s\n", s);
+ f = fstk_FindFile(tzFileName);
- fstk_FindFile(tzFileName);
- //printf("INCLUDING: %s\n", tzFileName);
+ if (f == NULL) {
+ err(1, "Unable to open included file '%s'",
+ tzFileName);
+ }
- if ((f = fopen(tzFileName, "r")) != NULL) {
- pushcontext();
- nLineNo = 1;
- nCurrentStatus = STAT_isInclude;
- strcpy(tzCurrentFileName, tzFileName);
- pCurrentFile = f;
- CurrentFlexHandle = yy_create_buffer(pCurrentFile);
- yy_switch_to_buffer(CurrentFlexHandle);
+ pushcontext();
+ nLineNo = 1;
+ nCurrentStatus = STAT_isInclude;
+ strcpy(tzCurrentFileName, tzFileName);
+ pCurrentFile = f;
+ CurrentFlexHandle = yy_create_buffer(pCurrentFile);
+ yy_switch_to_buffer(CurrentFlexHandle);
- //Dirty hack to give the INCLUDE directive a linefeed
+ //Dirty hack to give the INCLUDE directive a linefeed
- yyunput('\n');
- nLineNo -= 1;
-
- return (1);
- } else
- return (0);
+ yyunput('\n');
+ nLineNo -= 1;
}
/*
* RGBAsm - FSTACK.C (FileStack routines)
@@ -360,7 +369,7 @@
*
*/
-ULONG
+void
fstk_Init(char *s)
{
char tzFileName[_MAX_PATH + 1];
@@ -368,17 +377,16 @@
sym_AddString("__FILE__", s);
strcpy(tzFileName, s);
- fstk_FindFile(tzFileName);
-
pFileStack = NULL;
- if ((pCurrentFile = fopen(tzFileName, "r")) != NULL) {
- nMacroCount = 0;
- nCurrentStatus = STAT_isInclude;
- strcpy(tzCurrentFileName, tzFileName);
- CurrentFlexHandle = yy_create_buffer(pCurrentFile);
- yy_switch_to_buffer(CurrentFlexHandle);
- nLineNo = 1;
- return (1);
- } else
- return (0);
+ pCurrentFile = fopen(tzFileName, "rb");
+ if (pCurrentFile == NULL) {
+ err(1, "Unable to open file '%s'", tzFileName);
+ }
+
+ nMacroCount = 0;
+ nCurrentStatus = STAT_isInclude;
+ strcpy(tzCurrentFileName, tzFileName);
+ CurrentFlexHandle = yy_create_buffer(pCurrentFile);
+ yy_switch_to_buffer(CurrentFlexHandle);
+ nLineNo = 1;
}
--- a/src/asm/gameboy/yaccprt4.y
+++ b/src/asm/gameboy/yaccprt4.y
@@ -290,6 +290,8 @@
z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']'
{ out_AbsByte(0xF8); out_RelByte(&$6); }
+ | T_Z80_LD T_MODE_HL comma T_MODE_SP const_8bit
+ { out_AbsByte(0xF8); out_RelByte(&$5); }
| T_Z80_LD T_MODE_HL comma const_16bit
{ out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4); }
;
--- a/src/asm/globlex.c
+++ b/src/asm/globlex.c
@@ -208,10 +208,14 @@
char *s;
yyskipbytes(size);
- if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) {
- yyunputstr(s);
+ if ((size == 2 && src[1] >= '1' && src[1] <= '9')) {
+ if ((s = sym_FindMacroArg(src[1] - '0')) != NULL) {
+ yyunputstr(s);
+ } else {
+ yyerror("Macro argument not defined");
+ }
} else {
- yyerror("Macro argument not defined");
+ yyerror("Invalid macro argument");
}
return (0);
}
@@ -219,9 +223,15 @@
ULONG
PutUniqueArg(char *src, ULONG size)
{
+ char *s;
+
src = src;
yyskipbytes(size);
- yyunputstr(sym_FindMacroArg(-1));
+ if ((s = sym_FindMacroArg(-1)) != NULL) {
+ yyunputstr(s);
+ } else {
+ yyerror("Macro unique label string not defined");
+ }
return (0);
}
@@ -388,7 +398,7 @@
id = lex_FloatAlloc(&tMacroArgToken);
lex_FloatAddFirstRange(id, '\\', '\\');
- lex_FloatAddSecondRange(id, '0', '9');
+ lex_FloatAddSecondRange(id, '1', '9');
id = lex_FloatAlloc(&tMacroUniqueToken);
lex_FloatAddFirstRange(id, '\\', '\\');
lex_FloatAddSecondRange(id, '@', '@');
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -11,6 +11,7 @@
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"
+#include "extern/err.h"
#include "asmy.h"
@@ -20,18 +21,18 @@
ULONG nNameLength;
struct sLexString *pNext;
};
-#define pLexBuffer (pCurrentBuffer->pBuffer)
-#define nLexBufferLeng (pCurrentBuffer->nBufferSize)
+#define pLexBufferRealStart (pCurrentBuffer->pBufferRealStart)
+#define pLexBuffer (pCurrentBuffer->pBuffer)
+#define AtLineStart (pCurrentBuffer->oAtLineStart)
#define SAFETYMARGIN 1024
-extern ULONG symvaluetostring(char *dest, char *s);
+extern size_t symvaluetostring(char *dest, size_t maxLength, char *sym);
struct sLexFloat tLexFloat[32];
struct sLexString *tLexHash[LEXHASHSIZE];
YY_BUFFER_STATE pCurrentBuffer;
-ULONG yyleng;
-ULONG nLexMaxLeng;
+ULONG nLexMaxLength; // max length of all keywords and operators
ULONG tFloatingSecondChar[256];
ULONG tFloatingFirstChar[256];
@@ -39,8 +40,6 @@
ULONG nFloating;
enum eLexerState lexerstate = LEX_STATE_NORMAL;
-#define AtLineStart pCurrentBuffer->oAtLineStart
-
#ifdef __GNUC__
void
strupr(char *s)
@@ -75,6 +74,9 @@
void
yyunput(char c)
{
+ if (pLexBuffer <= pLexBufferRealStart)
+ fatalerror("Buffer safety margin exceeded");
+
*(--pLexBuffer) = c;
}
@@ -81,12 +83,15 @@
void
yyunputstr(char *s)
{
- SLONG i;
+ int i, len;
- i = strlen(s) - 1;
+ len = strlen(s);
- while (i >= 0)
- yyunput(s[i--]);
+ if (pLexBuffer - len < pLexBufferRealStart)
+ fatalerror("Buffer safety margin exceeded");
+
+ for (i = len - 1; i >= 0; i--)
+ *(--pLexBuffer) = s[i];
}
void
@@ -113,13 +118,11 @@
{
YY_BUFFER_STATE pBuffer;
- if ((pBuffer =
- (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) !=
- NULL) {
- if ((pBuffer->pBuffer = pBuffer->pBufferStart =
- (char *) malloc(size + 1 + SAFETYMARGIN)) != NULL) {
- pBuffer->pBuffer += SAFETYMARGIN;
- pBuffer->pBufferStart += SAFETYMARGIN;
+ if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
+ if ((pBuffer->pBufferRealStart =
+ malloc(size + 1 + SAFETYMARGIN)) != NULL) {
+ pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
+ pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
memcpy(pBuffer->pBuffer, mem, size);
pBuffer->nBufferSize = size;
pBuffer->oAtLineStart = 1;
@@ -136,9 +139,7 @@
{
YY_BUFFER_STATE pBuffer;
- if ((pBuffer =
- (YY_BUFFER_STATE) malloc(sizeof(struct yy_buffer_state))) !=
- NULL) {
+ if ((pBuffer = malloc(sizeof(struct yy_buffer_state))) != NULL) {
ULONG size;
fseek(f, 0, SEEK_END);
@@ -145,13 +146,13 @@
size = ftell(f);
fseek(f, 0, SEEK_SET);
- if ((pBuffer->pBuffer = pBuffer->pBufferStart =
- (char *) malloc(size + 2 + SAFETYMARGIN)) != NULL) {
+ if ((pBuffer->pBufferRealStart =
+ malloc(size + 2 + SAFETYMARGIN)) != NULL) {
char *mem;
ULONG instring = 0;
- pBuffer->pBuffer += SAFETYMARGIN;
- pBuffer->pBufferStart += SAFETYMARGIN;
+ pBuffer->pBufferStart = pBuffer->pBufferRealStart + SAFETYMARGIN;
+ pBuffer->pBuffer = pBuffer->pBufferRealStart + SAFETYMARGIN;
size = fread(pBuffer->pBuffer, sizeof(UBYTE), size, f);
@@ -165,11 +166,14 @@
if (*mem == '\"')
instring = 1 - instring;
- if (instring) {
+ if (mem[0] == '\\' &&
+ (mem[1] == '\"' || mem[1] == '\\')) {
+ mem += 2;
+ } else if (instring) {
mem += 1;
} else {
if ((mem[0] == 10 && mem[1] == 13)
- || (mem[0] == 13 && mem[1] == 10)) {
+ || (mem[0] == 13 && mem[1] == 10)) {
mem[0] = ' ';
mem[1] = '\n';
mem += 2;
@@ -176,17 +180,12 @@
} else if (mem[0] == 10 || mem[0] == 13) {
mem[0] = '\n';
mem += 1;
- } else if (mem[0] == '\n'
- && mem[1] == '*') {
+ } else if (mem[0] == '\n' && mem[1] == '*') {
mem += 1;
- while (!
- (*mem == '\n'
- || *mem == '\0'))
+ while (!(*mem == '\n' || *mem == '\0'))
*mem++ = ' ';
} else if (*mem == ';') {
- while (!
- (*mem == '\n'
- || *mem == '\0'))
+ while (!(*mem == '\n' || *mem == '\0'))
*mem++ = ' ';
} else
mem += 1;
@@ -201,17 +200,32 @@
return (NULL);
}
-ULONG
-lex_FloatAlloc(struct sLexFloat * tok)
+ULONG
+lex_FloatAlloc(struct sLexFloat *token)
{
- tLexFloat[nFloating] = (*tok);
+ tLexFloat[nFloating] = *token;
return (1 << (nFloating++));
}
+/*
+ * Make sure that only non-zero ASCII characters are used. Also, check if the
+ * start is greater than the end of the range.
+ */
+void
+lex_CheckCharacterRange(UWORD start, UWORD end)
+{
+ if (start > end || start < 1 || end > 127) {
+ errx(1, "Invalid character range (start: %u, end: %u)",
+ start, end);
+ }
+}
+
void
lex_FloatDeleteRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingChars[start] &= ~id;
start += 1;
@@ -221,6 +235,8 @@
void
lex_FloatAddRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingChars[start] |= id;
start += 1;
@@ -230,6 +246,8 @@
void
lex_FloatDeleteFirstRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingFirstChar[start] &= ~id;
start += 1;
@@ -239,6 +257,8 @@
void
lex_FloatAddFirstRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingFirstChar[start] |= id;
start += 1;
@@ -248,6 +268,8 @@
void
lex_FloatDeleteSecondRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingSecondChar[start] &= ~id;
start += 1;
@@ -257,6 +279,8 @@
void
lex_FloatAddSecondRange(ULONG id, UWORD start, UWORD end)
{
+ lex_CheckCharacterRange(start, end);
+
while (start <= end) {
tFloatingSecondChar[start] |= id;
start += 1;
@@ -264,32 +288,32 @@
}
struct sLexFloat *
-lexgetfloat(ULONG id)
+lexgetfloat(ULONG nFloatMask)
{
- ULONG r = 0, mask = 1;
+ if (nFloatMask == 0) {
+ fatalerror("Internal error in lexgetfloat");
+ }
- if (id == 0)
- return (NULL);
+ int i = 0;
- while ((id & mask) == 0) {
- mask <<= 1;
- r += 1;
+ while ((nFloatMask & 1) == 0) {
+ nFloatMask >>= 1;
+ i++;
}
- return (&tLexFloat[r]);
+ return (&tLexFloat[i]);
}
ULONG
lexcalchash(char *s)
{
- ULONG r = 0;
+ ULONG hash = 0;
while (*s) {
- r = ((r << 1) + (toupper(*s))) % LEXHASHSIZE;
- s += 1;
+ hash = (hash * 283) ^ toupper(*s++);
}
- return (r);
+ return (hash % LEXHASHSIZE);
}
void
@@ -297,17 +321,17 @@
{
ULONG i;
- for (i = 0; i < LEXHASHSIZE; i += 1) {
+ for (i = 0; i < LEXHASHSIZE; i++) {
tLexHash[i] = NULL;
}
- for (i = 0; i < 256; i += 1) {
+ for (i = 0; i < 256; i++) {
tFloatingFirstChar[i] = 0;
tFloatingSecondChar[i] = 0;
tFloatingChars[i] = 0;
}
- nLexMaxLeng = 0;
+ nLexMaxLength = 0;
nFloating = 0;
}
@@ -322,11 +346,7 @@
while (*ppHash)
ppHash = &((*ppHash)->pNext);
- //printf("%s has hashvalue %d\n", lex->tzName, hash);
-
- if (((*ppHash) =
- (struct sLexString *) malloc(sizeof(struct sLexString))) !=
- NULL) {
+ if (((*ppHash) = malloc(sizeof(struct sLexString))) != NULL) {
if (((*ppHash)->tzName =
(char *) strdup(lex->tzName)) != NULL) {
(*ppHash)->nNameLength = strlen(lex->tzName);
@@ -335,8 +355,8 @@
strupr((*ppHash)->tzName);
- if ((*ppHash)->nNameLength > nLexMaxLeng)
- nLexMaxLeng = (*ppHash)->nNameLength;
+ if ((*ppHash)->nNameLength > nLexMaxLength)
+ nLexMaxLength = (*ppHash)->nNameLength;
} else
fatalerror("Out of memory!");
@@ -347,458 +367,390 @@
}
}
-ULONG
-yylex(void)
+/*
+ * Gets the "float" mask and "float" length.
+ * "Float" refers to the token type of a token that is not a keyword.
+ * The character classes floatingFirstChar, floatingSecondChar, and
+ * floatingChars are defined separately for each token type.
+ * It uses bit masks to match against a set of simple regular expressions
+ * of the form /[floatingFirstChar]([floatingSecondChar][floatingChars]*)?/.
+ * The token types with the longest match from the current position in the
+ * buffer will have their bits set in the float mask.
+ */
+void
+yylex_GetFloatMaskAndFloatLen(ULONG *pnFloatMask, ULONG *pnFloatLen)
{
- ULONG hash, maxlen;
- char *s;
- struct sLexString *pLongestFixed = NULL;
- ULONG nFloatMask, nOldFloatMask, nFloatLen;
- ULONG linestart = AtLineStart;
+ // Note that '\0' should always have a bit mask of 0 in the "floating"
+ // tables, so it doesn't need to be checked for separately.
- switch (lexerstate) {
- case LEX_STATE_NORMAL:
- AtLineStart = 0;
+ char *s = pLexBuffer;
+ ULONG nOldFloatMask = 0;
+ ULONG nFloatMask = tFloatingFirstChar[(int)*s];
-scanagain:
+ if (nFloatMask != 0) {
+ s++;
+ nOldFloatMask = nFloatMask;
+ nFloatMask &= tFloatingSecondChar[(int)*s];
- while (*pLexBuffer == ' ' || *pLexBuffer == '\t') {
- linestart = 0;
- pLexBuffer += 1;
+ while (nFloatMask != 0) {
+ s++;
+ nOldFloatMask = nFloatMask;
+ nFloatMask &= tFloatingChars[(int)*s];
}
+ }
- if (*pLexBuffer == 0) {
- if (yywrap() == 0) {
- linestart = AtLineStart;
- AtLineStart = 0;
- goto scanagain;
+ *pnFloatMask = nOldFloatMask;
+ *pnFloatLen = (ULONG)(s - pLexBuffer);
+}
+
+/*
+ * Gets the longest keyword/operator from the current position in the buffer.
+ */
+struct sLexString *
+yylex_GetLongestFixed()
+{
+ struct sLexString *pLongestFixed = NULL;
+ char *s = pLexBuffer;
+ ULONG hash = 0;
+ ULONG length = 0;
+
+ while (length < nLexMaxLength && *s) {
+ hash = (hash * 283) ^ toupper(*s);
+ s++;
+ length++;
+
+ struct sLexString *lex = tLexHash[hash % LEXHASHSIZE];
+
+ while (lex) {
+ if (lex->nNameLength == length
+ && strncasecmp(pLexBuffer, lex->tzName, length) == 0) {
+ pLongestFixed = lex;
+ break;
}
+ lex = lex->pNext;
}
- s = pLexBuffer;
- nOldFloatMask = nFloatLen = 0;
- nFloatMask = tFloatingFirstChar[(int) *s++];
- while (nFloatMask && nFloatLen < nLexBufferLeng) {
- nFloatLen += 1;
- nOldFloatMask = nFloatMask;
- if (nFloatLen == 1)
- nFloatMask &= tFloatingSecondChar[(int) *s++];
- else
- nFloatMask &= tFloatingChars[(int) *s++];
+ }
+
+ return pLongestFixed;
+}
+
+size_t
+CopyMacroArg(char *dest, size_t maxLength, char c)
+{
+ int i;
+ char *s;
+ int argNum;
+
+ switch (c) {
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ argNum = c - '0';
+ break;
+ case '@':
+ argNum = -1;
+ break;
+ default:
+ return 0;
+ }
+
+ if ((s = sym_FindMacroArg(argNum)) == NULL)
+ fatalerror("Macro argument not defined");
+
+ for (i = 0; s[i] != 0; i++) {
+ if (i >= maxLength) {
+ fatalerror("Macro argument too long to fit buffer");
}
+ dest[i] = s[i];
+ }
- maxlen = nLexBufferLeng;
- if (nLexMaxLeng < maxlen)
- maxlen = nLexMaxLeng;
+ return i;
+}
- yyleng = 0;
- hash = 0;
- s = pLexBuffer;
- while (yyleng < nLexMaxLeng) {
- /* XXX: Kludge warning! The dereference of s below
- * may go beyond the end of the buffer. We use the
- * following test to stop that from happening,
- * without really understanding what the rest of
- * the code is doing. This may not be the correct
- * fix! */
- if (!*s)
+static inline void
+yylex_StringWriteChar(char *s, size_t index, char c)
+{
+ if (index >= MAXSTRLEN) {
+ fatalerror("String too long");
+ }
+
+ s[index] = c;
+}
+
+static inline void
+yylex_SymbolWriteChar(char *s, size_t index, char c)
+{
+ if (index >= MAXSYMLEN) {
+ fatalerror("Symbol too long");
+ }
+
+ s[index] = c;
+}
+
+/*
+ * Trims white space at the end of a string.
+ * The index parameter is the index of the 0 at the end of the string.
+ */
+void yylex_TrimEnd(char *s, size_t index)
+{
+ int i;
+
+ for (i = (int)index - 1; i >= 0 && (s[i] == ' ' || s[i] == '\t'); i--)
+ s[i] = 0;
+}
+
+size_t
+yylex_ReadBracketedSymbol(char *dest, size_t index)
+{
+ char sym[MAXSYMLEN + 1];
+ char ch;
+ size_t i = 0;
+ size_t length, maxLength;
+
+ for (ch = *pLexBuffer;
+ ch != '}' && ch != '"' && ch != '\n';
+ ch = *(++pLexBuffer)) {
+ if (ch == '\\') {
+ ch = *(++pLexBuffer);
+ maxLength = MAXSYMLEN - i;
+ length = CopyMacroArg(&sym[i], maxLength, ch);
+
+ if (length != 0)
+ i += length;
+ else
+ fatalerror("Illegal character escape '%c'", ch);
+ } else
+ yylex_SymbolWriteChar(sym, i++, ch);
+ }
+
+ yylex_SymbolWriteChar(sym, i, 0);
+
+ maxLength = MAXSTRLEN - index; // it's assumed we're writing to a T_STRING
+ length = symvaluetostring(&dest[index], maxLength, sym);
+
+ if (*pLexBuffer == '}')
+ pLexBuffer++;
+ else
+ yyerror("Missing }");
+
+ return length;
+}
+
+void
+yylex_ReadQuotedString()
+{
+ size_t index = 0;
+ size_t length, maxLength;
+
+ while (*pLexBuffer != '"' && *pLexBuffer != '\n') {
+ char ch = *pLexBuffer++;
+
+ if (ch == '\\') {
+ ch = *pLexBuffer++;
+
+ switch (ch) {
+ case 'n':
+ ch = '\n';
break;
+ case 't':
+ ch = '\t';
+ break;
+ case '\\':
+ ch = '\\';
+ break;
+ case '"':
+ ch = '"';
+ break;
+ default:
+ maxLength = MAXSTRLEN - index;
+ length = CopyMacroArg(&yylval.tzString[index], maxLength, ch);
- yyleng += 1;
- hash = ((hash << 1) + (toupper(*s))) % LEXHASHSIZE;
- s += 1;
- if (tLexHash[hash]) {
- struct sLexString *lex;
+ if (length != 0)
+ index += length;
+ else
+ fatalerror("Illegal character escape '%c'", ch);
- lex = tLexHash[hash];
- while (lex) {
- if (lex->nNameLength == yyleng) {
- if (strncasecmp
- (pLexBuffer, lex->tzName,
- yyleng) == 0) {
- pLongestFixed = lex;
- }
- }
- lex = lex->pNext;
- }
+ ch = 0;
+ break;
}
+ } else if (ch == '{') {
+ // Get bracketed symbol within string.
+ index += yylex_ReadBracketedSymbol(yylval.tzString, index);
+ ch = 0;
}
- if (nFloatLen == 0 && pLongestFixed == NULL) {
- if (*pLexBuffer == '"') {
- ULONG index = 0;
+ if (ch)
+ yylex_StringWriteChar(yylval.tzString, index++, ch);
+ }
- pLexBuffer += 1;
- while ((*pLexBuffer != '"')
- && (*pLexBuffer != '\n')) {
- char ch, *marg;
+ yylex_StringWriteChar(yylval.tzString, index, 0);
- if ((ch = *pLexBuffer++) == '\\') {
- switch (ch = (*pLexBuffer++)) {
- case 'n':
- ch = '\n';
- break;
- case 't':
- ch = '\t';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((marg =
- sym_FindMacroArg(ch
- -
- '0'))
- != NULL) {
- while (*marg)
- yylval.
- tzString
- [index++]
- =
- *marg++;
- ch = 0;
- }
- break;
- case '@':
- if ((marg =
- sym_FindMacroArg
- (-1)) != NULL) {
- while (*marg)
- yylval.
- tzString
- [index++]
- =
- *marg++;
- ch = 0;
- }
- break;
- }
- } else if (ch == '{') {
- char sym[MAXSYMLEN];
- int i = 0;
+ if (*pLexBuffer == '"')
+ pLexBuffer++;
+ else
+ yyerror("Unterminated string");
+}
- while ((*pLexBuffer != '}')
- && (*pLexBuffer != '"')
- && (*pLexBuffer !=
- '\n')) {
- if ((ch =
- *pLexBuffer++) ==
- '\\') {
- switch (ch =
- (*pLexBuffer++)) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((marg = sym_FindMacroArg(ch - '0')) != NULL) {
- while
- (*marg)
- sym[i++] = *marg++;
- ch = 0;
- }
- break;
- case '@':
- if ((marg = sym_FindMacroArg(-1)) != NULL) {
- while
- (*marg)
- sym[i++] = *marg++;
- ch = 0;
- }
- break;
- }
- } else
- sym[i++] = ch;
- }
+ULONG
+yylex_NORMAL()
+{
+ struct sLexString *pLongestFixed = NULL;
+ ULONG nFloatMask, nFloatLen;
+ ULONG linestart = AtLineStart;
- sym[i] = 0;
- index +=
- symvaluetostring(&yylval.
- tzString
- [index],
- sym);
- if (*pLexBuffer == '}')
- pLexBuffer += 1;
- else
- yyerror("Missing }");
- ch = 0;
- }
- if (ch)
- yylval.tzString[index++] = ch;
- }
+ AtLineStart = 0;
- yylval.tzString[index++] = 0;
+scanagain:
+ while (*pLexBuffer == ' ' || *pLexBuffer == '\t') {
+ linestart = 0;
+ pLexBuffer++;
+ }
- if (*pLexBuffer == '\n')
- yyerror("Unterminated string");
- else
- pLexBuffer += 1;
+ if (*pLexBuffer == 0) {
+ // Reached the end of a file, macro, or rept.
+ if (yywrap() == 0) {
+ linestart = AtLineStart;
+ AtLineStart = 0;
+ goto scanagain;
+ }
+ }
- return (T_STRING);
- } else if (*pLexBuffer == '{') {
- char sym[MAXSYMLEN], ch, *marg;
- int i = 0;
+ // Try to match an identifier, macro argument (e.g. \1),
+ // or numeric literal.
+ yylex_GetFloatMaskAndFloatLen(&nFloatMask, &nFloatLen);
- pLexBuffer += 1;
+ // Try to match a keyword or operator.
+ pLongestFixed = yylex_GetLongestFixed();
- while ((*pLexBuffer != '}')
- && (*pLexBuffer != '\n')) {
- if ((ch = *pLexBuffer++) == '\\') {
- switch (ch = (*pLexBuffer++)) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((marg =
- sym_FindMacroArg(ch
- -
- '0'))
- != NULL) {
- while (*marg)
- sym[i++]
- =
- *marg++;
- ch = 0;
- }
- break;
- case '@':
- if ((marg =
- sym_FindMacroArg
- (-1)) != NULL) {
- while (*marg)
- sym[i++]
- =
- *marg++;
- ch = 0;
- }
- break;
- }
- } else
- sym[i++] = ch;
- }
- sym[i] = 0;
- symvaluetostring(yylval.tzString, sym);
- if (*pLexBuffer == '}')
- pLexBuffer += 1;
- else
- yyerror("Missing }");
+ if (nFloatLen == 0 && pLongestFixed == NULL) {
+ // No keyword, identifier, operator, or numerical literal matches.
- return (T_STRING);
- } else {
- if (*pLexBuffer == '\n')
- AtLineStart = 1;
+ if (*pLexBuffer == '"') {
+ pLexBuffer++;
+ yylex_ReadQuotedString();
+ return T_STRING;
+ } else if (*pLexBuffer == '{') {
+ pLexBuffer++;
+ yylex_ReadBracketedSymbol(yylval.tzString, 0);
+ return T_STRING;
+ } else {
+ // It's not a keyword, operator, identifier, macro argument,
+ // numeric literal, string, or bracketed symbol, so just return
+ // the ASCII character.
+ if (*pLexBuffer == '\n')
+ AtLineStart = 1;
- yyleng = 1;
- return (*pLexBuffer++);
- }
+ return *pLexBuffer++;
}
- if (nFloatLen == 0) {
- yyleng = pLongestFixed->nNameLength;
- pLexBuffer += yyleng;
- return (pLongestFixed->nToken);
- }
- if (pLongestFixed == NULL) {
- struct sLexFloat *tok;
+ }
- tok = lexgetfloat(nOldFloatMask);
- yyleng = nFloatLen;
- if (tok->Callback) {
- if (tok->Callback(pLexBuffer, yyleng) == 0)
- goto scanagain;
- }
- if (tok->nToken == T_ID && linestart) {
- pLexBuffer += yyleng;
- return (T_LABEL);
- } else {
- pLexBuffer += yyleng;
- return (tok->nToken);
- }
+ if (pLongestFixed == NULL || nFloatLen > pLongestFixed->nNameLength) {
+ // Longest match was an identifier, macro argument, or numeric literal.
+ struct sLexFloat *token = lexgetfloat(nFloatMask);
+
+ if (token->Callback) {
+ int done = token->Callback(pLexBuffer, nFloatLen);
+ if (!done)
+ goto scanagain;
}
- if (nFloatLen > pLongestFixed->nNameLength) {
- struct sLexFloat *tok;
- tok = lexgetfloat(nOldFloatMask);
- yyleng = nFloatLen;
- if (tok->Callback) {
- if (tok->Callback(pLexBuffer, yyleng) == 0)
- goto scanagain;
- }
- if (tok->nToken == T_ID && linestart) {
- pLexBuffer += yyleng;
- return (T_LABEL);
- } else {
- pLexBuffer += yyleng;
- return (tok->nToken);
- }
+ pLexBuffer += nFloatLen;
+
+ if (token->nToken == T_ID && linestart) {
+ return T_LABEL;
} else {
- yyleng = pLongestFixed->nNameLength;
- pLexBuffer += yyleng;
- return (pLongestFixed->nToken);
+ return token->nToken;
}
- break;
+ }
- case LEX_STATE_MACROARGS:
- {
- ULONG index = 0;
+ // Longest match was a keyword or operator.
+ pLexBuffer += pLongestFixed->nNameLength;
+ return pLongestFixed->nToken;
+}
- while (*pLexBuffer == ' ' || *pLexBuffer == '\t') {
- linestart = 0;
- pLexBuffer += 1;
- }
+ULONG
+yylex_MACROARGS()
+{
+ size_t index = 0;
+ size_t length, maxLength;
- while ((*pLexBuffer != ',')
- && (*pLexBuffer != '\n')) {
- char ch, *marg;
+ while (*pLexBuffer == ' ' || *pLexBuffer == '\t') {
+ pLexBuffer++;
+ }
- if ((ch = *pLexBuffer++) == '\\') {
- switch (ch = (*pLexBuffer++)) {
- case 'n':
- ch = '\n';
- break;
- case 't':
- ch = '\t';
- break;
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((marg =
- sym_FindMacroArg(ch -
- '0')) !=
- NULL) {
- while (*marg)
- yylval.
- tzString
- [index++] =
- *marg++;
- ch = 0;
- }
- break;
- case '@':
- if ((marg =
- sym_FindMacroArg(-1)) !=
- NULL) {
- while (*marg)
- yylval.
- tzString
- [index++] =
- *marg++;
- ch = 0;
- }
- break;
- }
- } else if (ch == '{') {
- char sym[MAXSYMLEN];
- int i = 0;
+ while (*pLexBuffer != ',' && (*pLexBuffer != '\n')) {
+ char ch = *pLexBuffer++;
- while ((*pLexBuffer != '}')
- && (*pLexBuffer != '"')
- && (*pLexBuffer != '\n')) {
- if ((ch =
- *pLexBuffer++) == '\\') {
- switch (ch =
- (*pLexBuffer++)) {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if ((marg =
- sym_FindMacroArg
- (ch -
- '0')) !=
- NULL) {
- while
- (*marg)
- sym[i++] = *marg++;
- ch = 0;
- }
- break;
- case '@':
- if ((marg =
- sym_FindMacroArg
- (-1)) !=
- NULL) {
- while
- (*marg)
- sym[i++] = *marg++;
- ch = 0;
- }
- break;
- }
- } else
- sym[i++] = ch;
- }
- sym[i] = 0;
- index +=
- symvaluetostring(&yylval.
- tzString[index],
- sym);
- if (*pLexBuffer == '}')
- pLexBuffer += 1;
- else
- yyerror("Missing }");
- ch = 0;
- }
- if (ch)
- yylval.tzString[index++] = ch;
- }
+ if (ch == '\\') {
+ ch = *pLexBuffer++;
- if (index) {
- yyleng = index;
- yylval.tzString[index] = 0;
- if (*pLexBuffer == '\n') {
- while (yylval.tzString[--index] == ' ') {
- yylval.tzString[index] = 0;
- yyleng -= 1;
- }
- }
- return (T_STRING);
- } else if (*pLexBuffer == '\n') {
- pLexBuffer += 1;
- AtLineStart = 1;
- yyleng = 1;
- return ('\n');
- } else if (*pLexBuffer == ',') {
- pLexBuffer += 1;
- yyleng = 1;
- return (',');
- } else {
- yyerror("INTERNAL ERROR IN YYLEX");
- return (0);
+ switch (ch) {
+ case 'n':
+ ch = '\n';
+ break;
+ case 't':
+ ch = '\t';
+ break;
+ case '\\':
+ ch = '\\';
+ break;
+ default:
+ maxLength = MAXSTRLEN - index;
+ length = CopyMacroArg(&yylval.tzString[index], maxLength, ch);
+
+ if (length != 0)
+ index += length;
+ else
+ fatalerror("Illegal character escape '%c'", ch);
+
+ ch = 0;
+ break;
}
+ } else if (ch == '{') {
+ index += yylex_ReadBracketedSymbol(yylval.tzString, index);
+ ch = 0;
}
+ if (ch)
+ yylex_StringWriteChar(yylval.tzString, index++, ch);
+ }
- break;
+ if (index) {
+ yylex_StringWriteChar(yylval.tzString, index, 0);
+
+ // trim trailing white space at the end of the line
+ if (*pLexBuffer == '\n')
+ yylex_TrimEnd(yylval.tzString, index);
+
+ return T_STRING;
+ } else if (*pLexBuffer == '\n') {
+ pLexBuffer++;
+ AtLineStart = 1;
+ return '\n';
+ } else if (*pLexBuffer == ',') {
+ pLexBuffer++;
+ return ',';
}
- yyerror("INTERNAL ERROR IN YYLEX");
- return (0);
+ fatalerror("Internal error in yylex_MACROARGS");
+ return 0;
+}
+
+ULONG
+yylex(void)
+{
+ switch (lexerstate) {
+ case LEX_STATE_NORMAL:
+ return yylex_NORMAL();
+ case LEX_STATE_MACROARGS:
+ return yylex_MACROARGS();
+ }
+
+ fatalerror("Internal error in yylex");
+ return 0;
}
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -19,6 +19,7 @@
#include "asm/fstack.h"
#include "asm/output.h"
#include "asm/main.h"
+#include "extern/err.h"
int yyparse(void);
void setuplex(void);
@@ -133,9 +134,8 @@
newopt.gbgfx[2] = s[3];
newopt.gbgfx[3] = s[4];
} else {
- fprintf(stderr, "Must specify exactly 4 characters "
- "for option 'g'\n");
- exit(1);
+ errx(1, "Must specify exactly 4 characters for "
+ "option 'g'");
}
break;
case 'b':
@@ -143,9 +143,8 @@
newopt.binary[0] = s[1];
newopt.binary[1] = s[2];
} else {
- fprintf(stderr, "Must specify exactly 2 characters "
- "for option 'b'\n");
- exit(1);
+ errx(1, "Must specify exactly 2 characters for option "
+ "'b'");
}
break;
case 'z':
@@ -154,12 +153,10 @@
result = sscanf(&s[1], "%lx", &newopt.fillchar);
if (!((result == EOF) || (result == 1))) {
- fprintf(stderr,
- "Invalid argument for option 'z'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'z'");
}
} else {
- fprintf(stderr, "Invalid argument for option 'z'\n");
+ errx(1, "Invalid argument for option 'z'");
exit(1);
}
break;
@@ -176,9 +173,7 @@
{
struct sOptionStackEntry *pOpt;
- if ((pOpt =
- (struct sOptionStackEntry *)
- malloc(sizeof(struct sOptionStackEntry))) != NULL) {
+ if ((pOpt = malloc(sizeof(struct sOptionStackEntry))) != NULL) {
pOpt->Options = CurrentOptions;
pOpt->pNext = pOptionStack;
pOptionStack = pOpt;
@@ -245,8 +240,6 @@
void
PrintUsage(void)
{
- printf("RGBAsm v" ASM_VERSION " (part of ASMotor " ASMOTOR_VERSION
- ")\n\n");
printf("Usage: rgbasm [-v] [-h] [-b chars] [-g chars] [-i path] [-o outfile] [-p pad_value]\n"
" file\n");
exit(1);
@@ -295,9 +288,8 @@
newopt.binary[0] = optarg[1];
newopt.binary[1] = optarg[2];
} else {
- fprintf(stderr, "Must specify exactly "
- "2 characters for option 'b'\n");
- exit(1);
+ errx(1, "Must specify exactly 2 characters for "
+ "option 'b'");
}
break;
case 'g':
@@ -307,9 +299,8 @@
newopt.gbgfx[2] = optarg[3];
newopt.gbgfx[3] = optarg[4];
} else {
- fprintf(stderr, "Must specify exactly "
- "4 characters for option 'g'\n");
- exit(1);
+ errx(1, "Must specify exactly 4 characters for "
+ "option 'g'");
}
break;
case 'h':
@@ -324,14 +315,11 @@
case 'p':
newopt.fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'p'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'p'");
}
if (newopt.fillchar < 0 || newopt.fillchar > 0xFF) {
- fprintf(stderr, "Argument for option 'p' "
- "must be between 0 and 0xFF\n");
- exit(1);
+ errx(1, "Argument for option 'p' must be "
+ "between 0 and 0xFF");
}
break;
case 'v':
@@ -348,7 +336,6 @@
DefaultOptions = CurrentOptions;
- /* tzMainfile=argv[argn++]; argc-=1; */
tzMainfile = argv[argc - 1];
setuplex();
@@ -366,75 +353,67 @@
nPass = 1;
nErrors = 0;
sym_PrepPass1();
- if (fstk_Init(tzMainfile)) {
- if (CurrentOptions.verbose) {
- printf("Pass 1...\n");
- }
+ fstk_Init(tzMainfile);
+ if (CurrentOptions.verbose) {
+ printf("Pass 1...\n");
+ }
- yy_set_state(LEX_STATE_NORMAL);
- opt_SetCurrentOptions(&DefaultOptions);
+ yy_set_state(LEX_STATE_NORMAL);
+ opt_SetCurrentOptions(&DefaultOptions);
- if (yyparse() == 0 && nErrors == 0) {
- if (nIFDepth == 0) {
- nTotalLines = 0;
- nLineNo = 1;
- nIFDepth = 0;
- nPC = 0;
- nPass = 2;
- nErrors = 0;
- sym_PrepPass2();
- out_PrepPass2();
- fstk_Init(tzMainfile);
- yy_set_state(LEX_STATE_NORMAL);
- opt_SetCurrentOptions(&DefaultOptions);
+ if (yyparse() == 0 && nErrors == 0) {
+ if (nIFDepth == 0) {
+ nTotalLines = 0;
+ nLineNo = 1;
+ nIFDepth = 0;
+ nPC = 0;
+ nPass = 2;
+ nErrors = 0;
+ sym_PrepPass2();
+ out_PrepPass2();
+ fstk_Init(tzMainfile);
+ yy_set_state(LEX_STATE_NORMAL);
+ opt_SetCurrentOptions(&DefaultOptions);
- if (CurrentOptions.verbose) {
- printf("Pass 2...\n");
- }
+ if (CurrentOptions.verbose) {
+ printf("Pass 2...\n");
+ }
- if (yyparse() == 0 && nErrors == 0) {
- double timespent;
+ if (yyparse() == 0 && nErrors == 0) {
+ double timespent;
- nEndClock = clock();
- timespent =
- ((double) (nEndClock - nStartClock))
- / (double) CLOCKS_PER_SEC;
- if (CurrentOptions.verbose) {
- printf
- ("Success! %ld lines in %d.%02d seconds ",
- nTotalLines, (int) timespent,
- ((int) (timespent * 100.0)) % 100);
- if (timespent == 0)
- printf
- ("(INFINITY lines/minute)\n");
- else
- printf("(%d lines/minute)\n",
- (int) (60 / timespent *
- nTotalLines));
- }
- out_WriteObject();
- } else {
+ nEndClock = clock();
+ timespent =
+ ((double) (nEndClock - nStartClock))
+ / (double) CLOCKS_PER_SEC;
+ if (CurrentOptions.verbose) {
printf
- ("Assembly aborted in pass 2 (%ld errors)!\n",
- nErrors);
- //sym_PrintSymbolTable();
- exit(5);
+ ("Success! %ld lines in %d.%02d seconds ",
+ nTotalLines, (int) timespent,
+ ((int) (timespent * 100.0)) % 100);
+ if (timespent == 0)
+ printf
+ ("(INFINITY lines/minute)\n");
+ else
+ printf("(%d lines/minute)\n",
+ (int) (60 / timespent *
+ nTotalLines));
}
+ out_WriteObject();
} else {
- fprintf(stderr,
- "Unterminated IF construct (%ld levels)!\n",
- nIFDepth);
- exit(1);
+ printf
+ ("Assembly aborted in pass 2 (%ld errors)!\n",
+ nErrors);
+ //sym_PrintSymbolTable();
+ exit(5);
}
} else {
- fprintf(stderr,
- "Assembly aborted in pass 1 (%ld errors)!\n",
- nErrors);
- exit(1);
+ errx(1, "Unterminated IF construct (%ld levels)!",
+ nIFDepth);
}
} else {
- printf("File '%s' not found\n", tzMainfile);
- exit(5);
+ errx(1, "Assembly aborted in pass 1 (%ld errors)!",
+ nErrors);
}
- return (0);
+ return 0;
}
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -18,6 +18,7 @@
#include "asm/main.h"
#include "asm/rpn.h"
#include "asm/fstack.h"
+#include "extern/err.h"
#define SECTIONCHUNK 0x4000
@@ -44,6 +45,7 @@
ULONG ID;
struct sSymbol *pSymbol;
struct PatchSymbol *pNext;
+ struct PatchSymbol *pBucketNext; // next symbol in hash table bucket
};
struct SectionStackEntry {
@@ -57,9 +59,11 @@
*
*/
+struct PatchSymbol *tHashedPatchSymbols[HASHSIZE];
struct Section *pSectionList = NULL, *pCurrentSection = NULL;
struct PatchSymbol *pPatchSymbols = NULL;
-char tzObjectname[_MAX_PATH];
+struct PatchSymbol **ppPatchSymbolsTail = &pPatchSymbols;
+char *tzObjectname;
struct SectionStackEntry *pSectionStack = NULL;
/*
@@ -74,9 +78,7 @@
{
struct SectionStackEntry *pSect;
- if ((pSect =
- (struct SectionStackEntry *)
- malloc(sizeof(struct SectionStackEntry))) != NULL) {
+ if ((pSect = malloc(sizeof(struct SectionStackEntry))) != NULL) {
pSect->pSection = pCurrentSection;
pSect->pNext = pSectionStack;
pSectionStack = pSect;
@@ -328,30 +330,30 @@
addsymbol(struct sSymbol * pSym)
{
struct PatchSymbol *pPSym, **ppPSym;
- ULONG ID = 0;
+ static ULONG nextID = 0;
+ ULONG hash;
- pPSym = pPatchSymbols;
- ppPSym = &(pPatchSymbols);
+ hash = calchash(pSym->tzName);
+ ppPSym = &(tHashedPatchSymbols[hash]);
- while (pPSym) {
- if (pSym == pPSym->pSymbol)
- return (pPSym->ID);
- ppPSym = &(pPSym->pNext);
- pPSym = pPSym->pNext;
- ID += 1;
+ while ((*ppPSym) != NULL) {
+ if (pSym == (*ppPSym)->pSymbol)
+ return (*ppPSym)->ID;
+ ppPSym = &((*ppPSym)->pBucketNext);
}
- if ((*ppPSym = pPSym =
- (struct PatchSymbol *) malloc(sizeof(struct PatchSymbol))) !=
- NULL) {
+ if ((*ppPSym = pPSym = malloc(sizeof(struct PatchSymbol))) != NULL) {
pPSym->pNext = NULL;
+ pPSym->pBucketNext = NULL;
pPSym->pSymbol = pSym;
- pPSym->ID = ID;
- return (ID);
+ pPSym->ID = nextID++;
} else
fatalerror("No memory for patchsymbol");
- return ((ULONG) - 1);
+ *ppPatchSymbolsTail = pPSym;
+ ppPatchSymbolsTail = &(pPSym->pNext);
+
+ return pPSym->ID;
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
@@ -386,24 +388,17 @@
struct Patch *
allocpatch(void)
{
- struct Patch *pPatch, **ppPatch;
+ struct Patch *pPatch;
- pPatch = pCurrentSection->pPatches;
- ppPatch = &(pCurrentSection->pPatches);
-
- while (pPatch) {
- ppPatch = &(pPatch->pNext);
- pPatch = pPatch->pNext;
- }
-
- if ((*ppPatch = pPatch =
- (struct Patch *) malloc(sizeof(struct Patch))) != NULL) {
- pPatch->pNext = NULL;
+ if ((pPatch = malloc(sizeof(struct Patch))) != NULL) {
+ pPatch->pNext = pCurrentSection->pPatches;
pPatch->nRPNSize = 0;
pPatch->pRPN = NULL;
} else
fatalerror("No memory for patch");
+ pCurrentSection->pPatches = pPatch;
+
return (pPatch);
}
/*
@@ -473,7 +468,7 @@
break;
}
}
- if ((pPatch->pRPN = (UBYTE *) malloc(rpnptr)) != NULL) {
+ if ((pPatch->pRPN = malloc(rpnptr)) != NULL) {
memcpy(pPatch->pRPN, rpnexpr, rpnptr);
pPatch->nRPNSize = rpnptr;
}
@@ -505,9 +500,12 @@
checkcodesection(SLONG size)
{
checksection();
- if ((pCurrentSection->nType == SECT_ROM0
- || pCurrentSection->nType == SECT_ROMX)
- && (pCurrentSection->nPC + size <= MAXSECTIONSIZE)) {
+ if (pCurrentSection->nType != SECT_ROM0 &&
+ pCurrentSection->nType != SECT_ROMX) {
+ errx(1, "Section '%s' cannot contain code or data (not a "
+ "ROM0 or ROMX)", pCurrentSection->pzName);
+ }
+ if (pCurrentSection->nPC + size <= MAXSECTIONSIZE) {
if (((pCurrentSection->nPC % SECTIONCHUNK) >
((pCurrentSection->nPC + size) % SECTIONCHUNK))
&& (pCurrentSection->nType == SECT_ROM0
@@ -524,8 +522,7 @@
}
return;
} else
- fatalerror
- ("Section can't contain initialized data or section limit exceeded");
+ errx(1, "Section '%s' is too big", pCurrentSection->pzName);
}
/*
* RGBAsm - OUTPUT.C - Outputs an objectfile
@@ -594,7 +591,7 @@
void
out_SetFileName(char *s)
{
- strcpy(tzObjectname, s);
+ tzObjectname = s;
if (CurrentOptions.verbose) {
printf("Output filename %s\n", s);
}
@@ -632,11 +629,8 @@
pSect = pSect->pNext;
}
- if ((*ppSect =
- (pSect =
- (struct Section *) malloc(sizeof(struct Section)))) != NULL) {
- if ((pSect->pzName =
- (char *) malloc(strlen(pzName) + 1)) != NULL) {
+ if ((*ppSect = (pSect = malloc(sizeof(struct Section)))) != NULL) {
+ if ((pSect->pzName = malloc(strlen(pzName) + 1)) != NULL) {
strcpy(pSect->pzName, pzName);
pSect->nType = secttype;
pSect->nPC = 0;
@@ -647,8 +641,7 @@
pSect->charmap = NULL;
pPatchSymbols = NULL;
- if ((pSect->tData =
- (UBYTE *) malloc(SECTIONCHUNK)) != NULL) {
+ if ((pSect->tData = malloc(SECTIONCHUNK)) != NULL) {
return (pSect);
} else
fatalerror("Not enough memory for section");
@@ -918,30 +911,30 @@
{
FILE *f;
- fstk_FindFile(s);
+ f = fstk_FindFile(s);
+ if (f == NULL) {
+ err(1, "Unable to open incbin file '%s'", s);
+ }
- if ((f = fopen(s, "rb")) != NULL) {
- SLONG fsize;
+ SLONG fsize;
- fseek(f, 0, SEEK_END);
- fsize = ftell(f);
- fseek(f, 0, SEEK_SET);
+ fseek(f, 0, SEEK_END);
+ fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
- checkcodesection(fsize);
+ checkcodesection(fsize);
- if (nPass == 2) {
- SLONG dest = nPC;
- SLONG todo = fsize;
+ if (nPass == 2) {
+ SLONG dest = nPC;
+ SLONG todo = fsize;
- while (todo--)
- pCurrentSection->tData[dest++] = fgetc(f);
- }
- pCurrentSection->nPC += fsize;
- nPC += fsize;
- pPCSymbol->nValue += fsize;
- fclose(f);
- } else
- fatalerror("Could not open file '%s': %s", s, strerror(errno));
+ while (todo--)
+ pCurrentSection->tData[dest++] = fgetc(f);
+ }
+ pCurrentSection->nPC += fsize;
+ nPC += fsize;
+ pPCSymbol->nValue += fsize;
+ fclose(f);
}
void
@@ -955,36 +948,36 @@
if (length < 0)
fatalerror("Number of bytes to read must be greater than zero");
- fstk_FindFile(s);
+ f = fstk_FindFile(s);
+ if (f == NULL) {
+ err(1, "Unable to open included file '%s'", s);
+ }
- if ((f = fopen(s, "rb")) != NULL) {
- SLONG fsize;
+ SLONG fsize;
- fseek(f, 0, SEEK_END);
- fsize = ftell(f);
+ fseek(f, 0, SEEK_END);
+ fsize = ftell(f);
- if (start_pos >= fsize)
- fatalerror("Specified start position is greater than length of file");
+ if (start_pos >= fsize)
+ fatalerror("Specified start position is greater than length of file");
- if ((start_pos + length) > fsize)
- fatalerror("Specified range in INCBIN is out of bounds");
+ if ((start_pos + length) > fsize)
+ fatalerror("Specified range in INCBIN is out of bounds");
- fseek(f, start_pos, SEEK_SET);
+ fseek(f, start_pos, SEEK_SET);
- checkcodesection(length);
+ checkcodesection(length);
- if (nPass == 2) {
- SLONG dest = nPC;
- SLONG todo = length;
+ if (nPass == 2) {
+ SLONG dest = nPC;
+ SLONG todo = length;
- while (todo--)
- pCurrentSection->tData[dest++] = fgetc(f);
- }
- pCurrentSection->nPC += length;
- nPC += length;
- pPCSymbol->nValue += length;
+ while (todo--)
+ pCurrentSection->tData[dest++] = fgetc(f);
+ }
+ pCurrentSection->nPC += length;
+ nPC += length;
+ pPCSymbol->nValue += length;
- fclose(f);
- } else
- fatalerror("Could not open file '%s': %s", s, strerror(errno));
+ fclose(f);
}
--- a/src/asm/rgbasm.1
+++ b/src/asm/rgbasm.1
@@ -60,7 +60,6 @@
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbfix 1 ,
-.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -6,6 +6,7 @@
*/
#define _XOPEN_SOURCE 500
+#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
@@ -27,7 +28,6 @@
struct sSymbol *pScope = NULL;
struct sSymbol *pPCSymbol = NULL;
struct sSymbol *p_NARGSymbol = NULL;
-struct sSymbol *p__LINE__Symbol = NULL;
char *currentmacroargs[MAXMACROARGS + 1];
char *newmacroargs[MAXMACROARGS + 1];
char SavedTIME[256];
@@ -45,12 +45,6 @@
return (i);
}
-SLONG
-Callback__LINE__(struct sSymbol * sym)
-{
- sym = sym;
- return (nLineNo);
-}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
*
@@ -76,10 +70,10 @@
ULONG
calchash(char *s)
{
- ULONG hash = 0;
+ ULONG hash = 5381;
while (*s != 0)
- hash += (*s++);
+ hash = (hash * 33) ^ (*s++);
return (hash % HASHSIZE);
}
@@ -102,8 +96,7 @@
while ((*ppsym) != NULL)
ppsym = &((*ppsym)->pNext);
- if (((*ppsym) =
- (struct sSymbol *) malloc(sizeof(struct sSymbol))) != NULL) {
+ if (((*ppsym) = malloc(sizeof(struct sSymbol))) != NULL) {
strcpy((*ppsym)->tzName, s);
(*ppsym)->nValue = 0;
(*ppsym)->nType = 0;
@@ -440,6 +433,8 @@
if (i == -1)
i = MAXMACROARGS + 1;
+ assert(i-1 >= 0 &&
+ i-1 < sizeof currentmacroargs / sizeof *currentmacroargs);
return (currentmacroargs[i - 1]);
}
@@ -578,8 +573,7 @@
nsym = createsymbol(tzSym);
if (nsym) {
- if ((nsym->pMacro =
- (char *) malloc(strlen(tzValue) + 1)) != NULL)
+ if ((nsym->pMacro = malloc(strlen(tzValue) + 1)) != NULL)
strcpy(nsym->pMacro, tzValue);
else
fatalerror("No memory for stringequate");
@@ -849,6 +843,10 @@
sym_AddString("__TIME__", SavedTIME);
sym_AddString("__DATE__", SavedDATE);
sym_AddSet("_RS", 0);
+
+ sym_AddEqu("_NARG", 0);
+ p_NARGSymbol = findsymbol("_NARG", NULL);
+ p_NARGSymbol->Callback = Callback_NARG;
}
/*
* RGBAsm - SYMBOL.C - Symboltable stuff
@@ -876,11 +874,7 @@
sym_AddEqu("_NARG", 0);
p_NARGSymbol = findsymbol("_NARG", NULL);
p_NARGSymbol->Callback = Callback_NARG;
- sym_AddEqu("__LINE__", 0);
- p__LINE__Symbol = findsymbol("__LINE__", NULL);
- p__LINE__Symbol->Callback = Callback__LINE__;
- sym_AddEqu("__ASM__", (SLONG) (atof(ASM_VERSION) * 65536));
sym_AddSet("_RS", 0);
if (time(&tod) != -1) {
--- a/src/asm/yaccprt1.y
+++ b/src/asm/yaccprt1.y
@@ -24,14 +24,38 @@
char *tzNewMacro;
ULONG ulNewMacroSize;
-ULONG symvaluetostring( char *dest, char *sym )
+size_t symvaluetostring(char *dest, size_t maxLength, char *sym)
{
- if( sym_isString(sym) )
- strcpy( dest, sym_GetStringValue(sym) );
- else
- sprintf( dest, "$%lX", sym_GetConstantValue(sym) );
+ size_t length;
- return( strlen(dest) );
+ if (sym_isString(sym)) {
+ char *src = sym_GetStringValue(sym);
+ size_t i;
+
+ for (i = 0; src[i] != 0; i++) {
+ if (i >= maxLength) {
+ fatalerror("Symbol value too long to fit buffer");
+ }
+ dest[i] = src[i];
+ }
+
+ length = i;
+ } else {
+ ULONG value = sym_GetConstantValue(sym);
+ int fullLength = snprintf(dest, maxLength + 1, "$%lX", value);
+
+ if (fullLength < 0) {
+ fatalerror("snprintf encoding error");
+ } else {
+ length = (size_t)fullLength;
+
+ if (length > maxLength) {
+ fatalerror("Symbol value too long to fit buffer");
+ }
+ }
+ }
+
+ return length;
}
ULONG str2int( char *s )
@@ -124,8 +148,7 @@
src=pCurrentBuffer->pBuffer;
ulNewMacroSize=len;
- if( (tzNewMacro=(char *)malloc(ulNewMacroSize+1))!=NULL )
- {
+ if ((tzNewMacro = malloc(ulNewMacroSize + 1)) != NULL) {
ULONG i;
tzNewMacro[ulNewMacroSize]=0;
@@ -134,8 +157,7 @@
if( (tzNewMacro[i]=src[i])=='\n' )
nLineNo+=1;
}
- }
- else
+ } else
fatalerror( "No mem for REPT block" );
yyskipbytes( ulNewMacroSize+4 );
@@ -353,8 +375,8 @@
%union
{
- char tzSym[MAXSYMLEN+1];
- char tzString[256];
+ char tzSym[MAXSYMLEN + 1];
+ char tzString[MAXSTRLEN + 1];
struct Expression sVal;
SLONG nConstValue;
}
--- a/src/asm/yaccprt3.y
+++ b/src/asm/yaccprt3.y
@@ -266,10 +266,7 @@
include : T_POP_INCLUDE string
{
- if( !fstk_RunInclude($2) )
- {
- yyerror("Could not open file '%s' : %s\n", $2, strerror(errno));
- }
+ fstk_RunInclude($2);
}
;
--- /dev/null
+++ b/src/extern/err.c
@@ -1,0 +1,92 @@
+/*
+ * Copyright © 2005-2013 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "extern/err.h"
+
+#ifndef __MINGW32__
+char *__progname;
+#endif
+
+void rgbds_vwarn(const char *fmt, va_list ap)
+{
+ fprintf (stderr, "%s: ", __progname);
+ if (fmt) {
+ vfprintf(stderr, fmt, ap);
+ fputs (": ", stderr);
+ }
+ perror(0);
+}
+
+void rgbds_vwarnx(const char *fmt, va_list ap)
+{
+ fprintf (stderr, "%s: ", __progname);
+ if (fmt) vfprintf(stderr, fmt, ap);
+ putc('\n', stderr);
+}
+
+void rgbds_verr(int status, const char *fmt, va_list ap)
+{
+ vwarn(fmt, ap);
+ exit(status);
+}
+
+void rgbds_verrx(int status, const char *fmt, va_list ap)
+{
+ vwarnx(fmt, ap);
+ exit(status);
+}
+
+void rgbds_warn(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarn(fmt, ap);
+ va_end(ap);
+}
+
+void rgbds_warnx(const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vwarnx(fmt, ap);
+ va_end(ap);
+}
+
+void rgbds_err(int status, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verr(status, fmt, ap);
+ va_end(ap);
+}
+
+void rgbds_errx(int status, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ verrx(status, fmt, ap);
+ va_end(ap);
+}
--- /dev/null
+++ b/src/extern/strlcat.c
@@ -1,0 +1,55 @@
+/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+rgbds_strlcat(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
--- /dev/null
+++ b/src/extern/strlcpy.c
@@ -1,0 +1,51 @@
+/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <[email protected]>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+rgbds_strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0) {
+ while (--n != 0) {
+ if ((*d++ = *s++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
--- a/src/fix/main.c
+++ b/src/fix/main.c
@@ -22,6 +22,8 @@
#include <string.h>
#include <unistd.h>
+#include "extern/err.h"
+
static void
usage(void)
{
@@ -47,9 +49,7 @@
usage();
if ((rom = fopen(argv[argc - 1], "rb+")) == NULL) {
- fprintf(stderr, "Error opening file %s: \n", argv[argc - 1]);
- perror(NULL);
- exit(1);
+ err(1, "Error opening file %s", argv[argc - 1]);
}
/*
@@ -93,9 +93,8 @@
setid = true;
if (strlen(optarg) != 4) {
- fprintf(stderr, "Game ID %s must be exactly 4 "
- "characters\n", optarg);
- exit(1);
+ errx(1, "Game ID %s must be exactly 4 "
+ "characters", optarg);
}
id = optarg;
@@ -107,10 +106,8 @@
setnewlicensee = true;
if (strlen(optarg) != 2) {
- fprintf(stderr,
- "New licensee code %s is not the correct "
- "length of 2 characters\n", optarg);
- exit(1);
+ errx(1, "New licensee code %s is not the "
+ "correct length of 2 characters", optarg);
}
newlicensee = optarg;
@@ -120,15 +117,11 @@
licensee = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'l'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'l'");
}
if (licensee < 0 || licensee > 0xFF) {
- fprintf(stderr,
- "Argument for option 'l' must be "
- "between 0 and 255\n");
- exit(1);
+ errx(1, "Argument for option 'l' must be "
+ "between 0 and 255");
}
break;
case 'm':
@@ -136,15 +129,11 @@
cartridge = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'm'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'm'");
}
if (cartridge < 0 || cartridge > 0xFF) {
- fprintf(stderr,
- "Argument for option 'm' must be "
- "between 0 and 255\n");
- exit(1);
+ errx(1, "Argument for option 'm' must be "
+ "between 0 and 255");
}
break;
case 'n':
@@ -152,15 +141,11 @@
version = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'n'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'n'");
}
if (version < 0 || version > 0xFF) {
- fprintf(stderr,
- "Argument for option 'n' must be "
- "between 0 and 255\n");
- exit(1);
+ errx(1, "Argument for option 'n' must be "
+ "between 0 and 255");
}
break;
case 'p':
@@ -168,15 +153,11 @@
padvalue = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'p'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'p'");
}
if (padvalue < 0 || padvalue > 0xFF) {
- fprintf(stderr,
- "Argument for option 'p' must be "
- "between 0 and 255\n");
- exit(1);
+ errx(1, "Argument for option 'p' must be "
+ "between 0 and 255");
}
break;
case 'r':
@@ -184,14 +165,11 @@
ramsize = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr,
- "Invalid argument for option 'r'\n");
+ errx(1, "Invalid argument for option 'r'");
}
if (ramsize < 0 || ramsize > 0xFF) {
- fprintf(stderr,
- "Argument for option 'r' must be "
- "between 0 and 255\n");
- exit(1);
+ errx(1, "Argument for option 'r' must be "
+ "between 0 and 255");
}
break;
case 's':
@@ -201,15 +179,13 @@
settitle = true;
if (strlen(optarg) > 16) {
- fprintf(stderr, "Title %s is greater than the "
- "maximum of 16 characters\n", optarg);
- exit(1);
+ errx(1, "Title %s is greater than the "
+ "maximum of 16 characters", optarg);
}
if (strlen(optarg) == 16)
- fprintf(stderr,
- "Title %s is 16 chars, it is best "
- "to keep it to 15 or fewer\n", optarg);
+ warnx("Title %s is 16 chars, it is best to "
+ "keep it to 15 or fewer", optarg);
title = optarg;
break;
@@ -221,8 +197,6 @@
/* NOTREACHED */
}
}
- argc -= optind;
- argv += optind;
/*
* Write changes to ROM
@@ -315,8 +289,7 @@
byte |= 1 << 6;
if (byte & 0x3F)
- fprintf(stderr,
- "Color flag conflicts with game title\n");
+ warnx("Color flag conflicts with game title");
fseek(rom, 0x143, SEEK_SET);
fputc(byte, rom);
@@ -353,9 +326,8 @@
*/
if (!setlicensee)
- fprintf(stderr,
- "You should probably set both '-s' and "
- "'-l 0x33'\n");
+ warnx("You should probably set both '-s' and "
+ "'-l 0x33'");
fseek(rom, 0x146, SEEK_SET);
fputc(3, rom);
@@ -380,6 +352,7 @@
/* We will pad the ROM to match the size given in the header. */
int romsize, newsize, headbyte;
+ uint8_t *buf;
fseek(rom, 0, SEEK_END);
romsize = ftell(rom);
newsize = 0x8000;
@@ -390,14 +363,17 @@
headbyte++;
}
- while (newsize != ftell(rom)) /* ROM needs resizing */
- fputc(padvalue, rom);
-
if (newsize > 0x800000) /* ROM is bigger than 8MiB */
- fprintf(stderr, "ROM size is bigger than 8MiB\n");
+ warnx("ROM size is bigger than 8MiB");
+ buf = malloc(newsize - romsize);
+ memset(buf, padvalue, newsize - romsize);
+ fwrite(buf, 1, newsize - romsize, rom);
+
fseek(rom, 0x148, SEEK_SET);
fputc(headbyte, rom);
+
+ free(buf);
}
if (setramsize) {
--- a/src/fix/rgbfix.1
+++ b/src/fix/rgbfix.1
@@ -130,7 +130,6 @@
.Sh SEE ALSO
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
-.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY
--- a/src/lib/library.c
+++ /dev/null
@@ -1,306 +1,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "lib/types.h"
-#include "lib/libwrap.h"
-
-SLONG
-file_Length(FILE * f)
-{
- ULONG r, p;
-
- p = ftell(f);
- fseek(f, 0, SEEK_END);
- r = ftell(f);
- fseek(f, p, SEEK_SET);
-
- return (r);
-}
-
-SLONG
-file_ReadASCIIz(char *b, FILE * f)
-{
- SLONG r = 0;
-
- while ((*b++ = fgetc(f)) != 0)
- r += 1;
-
- return (r + 1);
-}
-
-void
-file_WriteASCIIz(char *b, FILE * f)
-{
- while (*b)
- fputc(*b++, f);
-
- fputc(0, f);
-}
-
-UWORD
-file_ReadWord(FILE * f)
-{
- UWORD r;
-
- r = fgetc(f);
- r |= fgetc(f) << 8;
-
- return (r);
-}
-
-void
-file_WriteWord(UWORD w, FILE * f)
-{
- fputc(w, f);
- fputc(w >> 8, f);
-}
-
-ULONG
-file_ReadLong(FILE * f)
-{
- ULONG r;
-
- r = fgetc(f);
- r |= fgetc(f) << 8;
- r |= fgetc(f) << 16;
- r |= fgetc(f) << 24;
-
- return (r);
-}
-
-void
-file_WriteLong(UWORD w, FILE * f)
-{
- fputc(w, f);
- fputc(w >> 8, f);
- fputc(w >> 16, f);
- fputc(w >> 24, f);
-}
-
-sLibrary *
-lib_ReadLib0(FILE * f, SLONG size)
-{
- if (size) {
- sLibrary *l = NULL, *first = NULL;
-
- while (size > 0) {
- if (l == NULL) {
- l = malloc(sizeof *l);
- if (!l) {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
-
- first = l;
- } else {
- l->pNext = malloc(sizeof *l->pNext);
- if (!l->pNext) {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
-
- l = l->pNext;
- }
-
- size -= file_ReadASCIIz(l->tName, f);
- l->uwTime = file_ReadWord(f);
- size -= 2;
- l->uwDate = file_ReadWord(f);
- size -= 2;
- l->nByteLength = file_ReadLong(f);
- size -= 4;
- if ((l->pData = malloc(l->nByteLength))) {
- fread(l->pData, sizeof(UBYTE), l->nByteLength,
- f);
- size -= l->nByteLength;
- } else {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
-
- l->pNext = NULL;
- }
- return (first);
- }
- return (NULL);
-}
-
-sLibrary *
-lib_Read(char *filename)
-{
- FILE *f;
-
- if ((f = fopen(filename, "rb"))) {
- SLONG size;
- char ID[5];
-
- size = file_Length(f);
- if (size == 0) {
- fclose(f);
- return (NULL);
- }
- fread(ID, sizeof(char), 4, f);
- ID[4] = 0;
- size -= 4;
-
- if (strcmp(ID, "XLB0") == 0) {
- sLibrary *r;
-
- r = lib_ReadLib0(f, size);
- fclose(f);
- printf("Library '%s' opened\n", filename);
- return (r);
- } else {
- fclose(f);
- fprintf(stderr, "Not a valid xLib library\n");
- exit(1);
- }
- } else {
- printf
- ("Library '%s' not found, it will be created if necessary\n",
- filename);
- return (NULL);
- }
-}
-
-BBOOL
-lib_Write(sLibrary * lib, char *filename)
-{
- FILE *f;
-
- if ((f = fopen(filename, "wb"))) {
- fwrite("XLB0", sizeof(char), 4, f);
- while (lib) {
- file_WriteASCIIz(lib->tName, f);
- file_WriteWord(lib->uwTime, f);
- file_WriteWord(lib->uwDate, f);
- file_WriteLong(lib->nByteLength, f);
- fwrite(lib->pData, sizeof(UBYTE), lib->nByteLength, f);
- lib = lib->pNext;
- }
-
- fclose(f);
- printf("Library '%s' closed\n", filename);
- return (1);
- }
- return (0);
-}
-
-sLibrary *
-lib_Find(sLibrary * lib, char *filename)
-{
- if (strlen(filename) >= MAXNAMELENGTH) {
- fprintf(stderr, "Module name too long: %s\n", filename);
- exit(1);
- }
-
- while (lib) {
- if (strcmp(lib->tName, filename) == 0)
- break;
-
- lib = lib->pNext;
- }
-
- return (lib);
-}
-
-sLibrary *
-lib_AddReplace(sLibrary * lib, char *filename)
-{
- FILE *f;
-
- if ((f = fopen(filename, "rb"))) {
- sLibrary *module;
-
- if (strlen(filename) >= MAXNAMELENGTH) {
- fprintf(stderr, "Module name too long: %s\n",
- filename);
- exit(1);
- }
-
- if ((module = lib_Find(lib, filename)) == NULL) {
- module = malloc(sizeof *module);
- if (!module) {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
-
- module->pNext = lib;
- lib = module;
- } else {
- /* Module already exists */
- free(module->pData);
- }
-
- module->nByteLength = file_Length(f);
- strcpy(module->tName, filename);
- module->pData = malloc(module->nByteLength);
- if (!module->pData) {
- fprintf(stderr, "Out of memory\n");
- exit(1);
- }
-
- fread(module->pData, sizeof(UBYTE), module->nByteLength, f);
-
- printf("Added module '%s'\n", filename);
-
- fclose(f);
- }
- return (lib);
-}
-
-sLibrary *
-lib_DeleteModule(sLibrary * lib, char *filename)
-{
- sLibrary **pp, **first;
- BBOOL found = 0;
-
- pp = &lib;
- first = pp;
-
- if (strlen(filename) >= MAXNAMELENGTH) {
- fprintf(stderr, "Module name too long: %s\n", filename);
- exit(1);
- }
-
- while ((*pp) && (!found)) {
- if (strcmp((*pp)->tName, filename) == 0) {
- sLibrary *t;
-
- t = *pp;
-
- if (t->pData)
- free(t->pData);
-
- *pp = t->pNext;
-
- free(t);
- found = 1;
- }
- pp = &((*pp)->pNext);
- }
-
- if (!found) {
- fprintf(stderr, "Module not found\n");
- exit(1);
- } else
- printf("Module '%s' deleted from library\n", filename);
-
- return (*first);
-}
-
-void
-lib_Free(sLibrary * lib)
-{
- while (lib) {
- sLibrary *l;
-
- if (lib->pData)
- free(lib->pData);
-
- l = lib;
- lib = lib->pNext;
- free(l);
- }
-}
--- a/src/lib/main.c
+++ /dev/null
@@ -1,120 +1,0 @@
-#include <ctype.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "asmotor.h"
-
-#include "lib/types.h"
-#include "lib/library.h"
-
-/*
- * Print the usagescreen
- *
- */
-
-static void
-usage(void)
-{
- printf("RGBLib v" LIB_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n");
- printf("usage: rgblib file [add | delete | extract | list] [module ...]\n");
- exit(1);
-}
-/*
- * The main routine
- *
- */
-
-int
-main(int argc, char *argv[])
-{
- SLONG argn = 0;
- char *libname;
-
- argc -= 1;
- argn += 1;
-
- if (argc >= 2) {
- sLibrary *lib;
-
- lib = lib_Read(libname = argv[argn++]);
- argc -= 1;
-
- if (strcmp(argv[argn], "add") == 0) {
- argn += 1;
- argc -= 1;
-
- while (argc) {
- lib = lib_AddReplace(lib, argv[argn++]);
- argc -= 1;
- }
- lib_Write(lib, libname);
- lib_Free(lib);
- } else if (strcmp(argv[argn], "delete") == 0) {
- argn += 1;
- argc -= 1;
-
- while (argc) {
- lib =
- lib_DeleteModule(lib, argv[argn++]);
- argc -= 1;
- }
- lib_Write(lib, libname);
- lib_Free(lib);
- } else if (strcmp(argv[argn], "extract") == 0) {
- argn += 1;
- argc -= 1;
-
- while (argc) {
- sLibrary *l;
-
- l = lib_Find(lib, argv[argn]);
- if (l) {
- FILE *f;
-
- if ((f = fopen(argv[argn], "wb"))) {
- fwrite(l->pData,
- sizeof(UBYTE),
- l->nByteLength,
- f);
- fclose(f);
- printf
- ("Extracted module '%s'\n",
- argv[argn]);
- } else {
- fprintf(stderr,
- "Unable to write module '%s': ", argv[argn]);
- perror(NULL);
- exit(1);
- }
- } else {
- fprintf(stderr, "Module not found\n");
- exit(1);
- }
-
- argn += 1;
- argc -= 1;
- }
- lib_Free(lib);
- } else if (strcmp(argv[argn], "list") == 0) {
- argn += 1;
- argc -= 1;
-
- sLibrary *l;
-
- l = lib;
-
- while (l) {
- printf("%10ld %s\n",
- l->nByteLength,
- l->tName);
- l = l->pNext;
- }
- } else
- usage();
- } else
- usage();
-
- return (0);
-}
--- a/src/lib/rgblib.1
+++ /dev/null
@@ -1,36 +1,0 @@
-.Dd $Mdocdate$
-.Dt RGBLIB 1
-.Os RGBDS Manual
-.Sh NAME
-.Nm rgblib
-.Nd Game Boy library manager
-.Sh SYNOPSIS
-.Nm rgblib
-.Ar library
-.Op add | delete | extract | list
-.Ar module ...
-.Sh DESCRIPTION
-The
-.Nm
-program manages libraries for use with
-.Xr rgblink 1 .
-.Bl -tag -width Ds
-.It add
-Add the given modules to the library.
-.It delete
-Delete the given modules from the library.
-.It extract
-Extract the given modules from the library.
-.It list
-List all the modules in the library.
-.El
-.Sh SEE ALSO
-.Xr rgbds 7 ,
-.Xr rgbasm 1 ,
-.Xr rgbfix 1 ,
-.Xr rgblink 1 ,
-.Xr gbz80 7
-.Sh HISTORY
-.Nm
-was originally released by Carsten S\(/orensen as part of the ASMotor package,
-and was later packaged in RGBDS by Justin Lloyd.
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "extern/err.h"
#include "link/mylink.h"
#include "link/main.h"
#include "link/symbol.h"
@@ -63,7 +64,6 @@
struct sFreeArea *pNewArea;
if ((pNewArea =
- (struct sFreeArea *)
malloc(sizeof(struct sFreeArea)))
!= NULL) {
*pNewArea = *pArea;
@@ -77,9 +77,7 @@
return (org);
} else {
- fprintf(stderr,
- "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
}
}
@@ -310,9 +308,7 @@
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
} else {
- fprintf(stderr,
- "Unable to place VRAM section anywhere\n");
- exit(1);
+ errx(1, "Unable to place VRAM section anywhere");
}
}
}
@@ -331,9 +327,7 @@
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
- fprintf(stderr,
- "Unable to place SRAM section anywhere\n");
- exit(1);
+ errx(1, "Unable to place SRAM section anywhere");
}
}
}
@@ -352,9 +346,7 @@
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
- fprintf(stderr,
- "Unable to place WRAMX section anywhere\n");
- exit(1);
+ errx(1, "Unable to place WRAMX section anywhere");
}
}
}
@@ -373,9 +365,7 @@
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
} else {
- fprintf(stderr,
- "Unable to place ROMX section anywhere\n");
- exit(1);
+ errx(1, "Unable to place ROMX section anywhere");
}
}
}
@@ -397,8 +387,7 @@
BankFree[i] = malloc(sizeof *BankFree[i]);
if (!BankFree[i]) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
if (i == 0) {
@@ -472,10 +461,9 @@
if (area_AllocAbs
(&BankFree[BANK_WRAM0], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
- fprintf(stderr,
- "Unable to load fixed WRAM0 section "
- "at $%lX\n", pSection->nOrg);
- exit(1);
+ errx(1,
+ "Unable to load fixed WRAM0 "
+ "section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_WRAM0;
@@ -484,10 +472,8 @@
if (area_AllocAbs
(&BankFree[BANK_HRAM], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
- fprintf(stderr, "Unable to load fixed "
- "HRAM section at $%lX\n",
- pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed HRAM "
+ "section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_HRAM;
@@ -530,17 +516,15 @@
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
- fprintf(stderr,
-"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
- fprintf(stderr,
-"Unable to load fixed SRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed SRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -583,17 +567,15 @@
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
- fprintf(stderr,
-"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXWBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
- fprintf(stderr,
-"Unable to load fixed WRAMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed WRAMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -636,17 +618,15 @@
pSection->nOrg,
pSection->nByteSize)
!= pSection->nOrg) {
- fprintf(stderr,
-"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXVBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
- fprintf(stderr,
-"Unable to load fixed VRAM section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+"Unable to load fixed VRAM section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
}
@@ -655,10 +635,8 @@
if (area_AllocAbs
(&BankFree[BANK_ROM0], pSection->nOrg,
pSection->nByteSize) != pSection->nOrg) {
- fprintf(stderr, "Unable to load fixed "
- "ROM0 section at $%lX\n",
- pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed ROM0 "
+ "section at $%lX", pSection->nOrg);
}
pSection->oAssigned = 1;
pSection->nBank = BANK_ROM0;
@@ -703,15 +681,15 @@
pSection->
nByteSize) !=
pSection->nOrg) {
- fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+ "Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
DOMAXBANK(pSection->
nBank);
pSection->oAssigned = 1;
} else {
- fprintf(stderr, "Unable to load fixed ROMX section at $%lX in bank $%02lX\n", pSection->nOrg, pSection->nBank);
- exit(1);
+ errx(1,
+ "Unable to load fixed ROMX section at $%lX in bank $%02lX", pSection->nOrg, pSection->nBank);
}
}
@@ -737,14 +715,13 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1,
+ "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
} else {
- fprintf(stderr, "Unable to load fixed ROMX section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1, "Unable to load fixed ROMX section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_SRAM
@@ -755,14 +732,12 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "Unable to load fixed SRAM section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1, "Unable to load fixed SRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
} else {
- fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_VRAM
@@ -773,14 +748,12 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
} else {
- fprintf(stderr, "Unable to load fixed VRAM section into bank $%02lX\n", pSection->nBank);
- exit(1);
+ errx(1, "Unable to load fixed VRAM section into bank $%02lX", pSection->nBank);
}
} else if (pSection->oAssigned == 0
&& pSection->Type == SECT_WRAMX
@@ -791,14 +764,12 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[pSection->nBank],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
- exit(1);
+ errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
} else {
- fprintf(stderr, "Unable to load fixed WRAMX section into bank $%02lX\n", pSection->nBank - BANK_WRAMX);
- exit(1);
+ errx(1, "Unable to load fixed WRAMX section into bank $%02lX", pSection->nBank - BANK_WRAMX);
}
}
pSection = pSection->pNext;
@@ -820,8 +791,7 @@
area_AllocAbsROMXAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
- fprintf(stderr, "Unable to load fixed ROMX section at $%lX into any bank\n", pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed ROMX section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXBANK(pSection->nBank);
@@ -834,8 +804,7 @@
area_AllocAbsVRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
- fprintf(stderr, "Unable to load fixed VRAM section at $%lX into any bank\n", pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed VRAM section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXVBANK(pSection->nBank);
@@ -848,8 +817,7 @@
area_AllocAbsSRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
- fprintf(stderr, "Unable to load fixed SRAM section at $%lX into any bank\n", pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed SRAM section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXSBANK(pSection->nBank);
@@ -862,8 +830,7 @@
area_AllocAbsWRAMAnyBank(pSection->nOrg,
pSection->nByteSize)) ==
-1) {
- fprintf(stderr, "Unable to load fixed WRAMX section at $%lX into any bank\n", pSection->nOrg);
- exit(1);
+ errx(1, "Unable to load fixed WRAMX section at $%lX into any bank", pSection->nOrg);
}
pSection->oAssigned = 1;
DOMAXWBANK(pSection->nBank);
@@ -885,8 +852,7 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_WRAM0],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "WRAM0 section too large\n");
- exit(1);
+ errx(1, "WRAM0 section too large");
}
pSection->nBank = BANK_WRAM0;
pSection->oAssigned = 1;
@@ -895,8 +861,7 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_HRAM],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "HRAM section too large\n");
- exit(1);
+ errx(1, "HRAM section too large");
}
pSection->nBank = BANK_HRAM;
pSection->oAssigned = 1;
@@ -911,8 +876,7 @@
if ((pSection->nOrg =
area_Alloc(&BankFree[BANK_ROM0],
pSection->nByteSize)) == -1) {
- fprintf(stderr, "ROM0 section too large\n");
- exit(1);
+ errx(1, "ROM0 section too large");
}
pSection->nBank = BANK_ROM0;
pSection->oAssigned = 1;
@@ -920,8 +884,7 @@
case SECT_ROMX:
break;
default:
- fprintf(stderr, "(INTERNAL) Unknown section type!\n");
- exit(1);
+ errx(1, "(INTERNAL) Unknown section type!");
break;
}
}
--- a/src/link/library.c
+++ b/src/link/library.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
+#include "extern/err.h"
#include "link/types.h"
#include "link/mylink.h"
#include "link/main.h"
@@ -91,9 +92,8 @@
}
if (options & OPT_SMART_C_LINK) {
if (!addmodulecontaining(smartlinkstartsymbol)) {
- fprintf(stderr, "Can't find start symbol '%s'\n",
+ errx(1, "Can't find start symbol '%s'",
smartlinkstartsymbol);
- exit(1);
} else
printf("Smart linking with symbol '%s'\n",
smartlinkstartsymbol);
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -4,8 +4,7 @@
#include <string.h>
#include <unistd.h>
-#include "asmotor.h"
-
+#include "extern/err.h"
#include "link/object.h"
#include "link/output.h"
#include "link/assign.h"
@@ -34,9 +33,7 @@
static void
usage(void)
{
- printf("RGBLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION
- ")\n\n");
- printf("usage: rgblink [-t] [-l library] [-m mapfile] [-n symfile] [-o outfile]\n");
+ printf("usage: rgblink [-t] [-m mapfile] [-n symfile] [-o outfile]\n");
printf("\t [-s symbol] [-z pad_value] objectfile [...]\n");
exit(1);
@@ -58,9 +55,6 @@
while ((ch = getopt(argc, argv, "l:m:n:o:p:s:t")) != -1) {
switch (ch) {
- case 'l':
- lib_Readfile(optarg);
- break;
case 'm':
SetMapfileName(optarg);
break;
@@ -73,8 +67,7 @@
case 'p':
fillchar = strtoul(optarg, &ep, 0);
if (optarg[0] == '\0' || *ep != '\0') {
- fprintf(stderr, "Invalid argument for option 'p'\n");
- exit(1);
+ errx(1, "Invalid argument for option 'p'");
}
if (fillchar < 0 || fillchar > 0xFF) {
fprintf(stderr, "Argument for option 'p' must be between 0 and 0xFF");
--- a/src/link/mapfile.c
+++ b/src/link/mapfile.c
@@ -3,8 +3,7 @@
#include <stdlib.h>
#include <string.h>
-#include "asmotor.h"
-
+#include "extern/err.h"
#include "link/main.h"
#include "link/mylink.h"
#include "link/assign.h"
@@ -20,9 +19,7 @@
mf = fopen(name, "w");
if (mf == NULL) {
- fprintf(stderr, "Cannot open mapfile '%s': ", name);
- perror(NULL);
- exit(1);
+ err(1, "Cannot open mapfile '%s'", name);
}
}
@@ -32,11 +29,10 @@
sf = fopen(name, "w");
if (sf == NULL) {
- fprintf(stderr, "Cannot open symfile '%s'\n", name);
- exit(1);
+ err(1, "Cannot open symfile '%s'", name);
}
- fprintf(sf, ";File generated by xLink v" LINK_VERSION "\n\n");
+ fprintf(sf, ";File generated by rgblink\n\n");
}
void
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -8,6 +8,7 @@
#include <stdlib.h>
#include <string.h>
+#include "extern/err.h"
#include "link/mylink.h"
#include "link/main.h"
@@ -80,8 +81,7 @@
*ppSections = malloc(sizeof **ppSections);
if (!*ppSections) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
(*ppSections)->tSymbols = tSymbols;
(*ppSections)->pNext = NULL;
@@ -102,15 +102,13 @@
pSym = malloc(sizeof *pSym);
if (!pSym) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
readasciiz(s, f);
pSym->pzName = malloc(strlen(s) + 1);
if (!pSym->pzName) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
strcpy(pSym->pzName, s);
@@ -150,7 +148,7 @@
if (pSection->nByteSize) {
pSection->pData = malloc(pSection->nByteSize);
if (!pSection->pData) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
SLONG nNumberOfPatches;
@@ -169,7 +167,7 @@
while (nNumberOfPatches--) {
pPatch = malloc(sizeof *pPatch);
if (!pPatch) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
*ppPatch = pPatch;
@@ -177,7 +175,7 @@
pPatch->pzFilename = malloc(strlen(s) + 1);
if (!pPatch->pzFilename) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
strcpy(pPatch->pzFilename, s);
@@ -193,8 +191,7 @@
if ((pPatch->nRPNSize = readlong(f)) > 0) {
pPatch->pRPN = malloc(pPatch->nRPNSize);
if (!pPatch->pRPN) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
fread(pPatch->pRPN, sizeof(UBYTE),
@@ -228,8 +225,7 @@
if (nNumberOfSymbols) {
tSymbols = malloc(nNumberOfSymbols * sizeof(struct sSymbol *));
if (!tSymbols) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
for (i = 0; i < nNumberOfSymbols; i += 1)
@@ -305,8 +301,7 @@
if (pSection->nByteSize) {
pSection->pData = malloc(pSection->nByteSize);
if (!pSection->pData) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
+ err(1, NULL);
}
SLONG nNumberOfPatches;
@@ -325,7 +320,7 @@
while (nNumberOfPatches--) {
pPatch = malloc(sizeof *pPatch);
if (!pPatch) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
*ppPatch = pPatch;
@@ -332,7 +327,7 @@
readasciiz(s, f);
pPatch->pzFilename = malloc(strlen(s) + 1);
if (!pPatch->pzFilename) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
strcpy(pPatch->pzFilename, s);
@@ -342,7 +337,7 @@
if ((pPatch->nRPNSize = readlong(f)) > 0) {
pPatch->pRPN = malloc(pPatch->nRPNSize);
if (!pPatch->pRPN) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
fread(pPatch->pRPN, sizeof(UBYTE),
@@ -376,7 +371,7 @@
if (nNumberOfSymbols) {
tSymbols = malloc(nNumberOfSymbols * sizeof *tSymbols);
if (!tSymbols) {
- fprintf(stderr, "Out of memory!\n");
+ err(1, NULL);
}
for (i = 0; i < nNumberOfSymbols; i += 1)
@@ -440,14 +435,10 @@
obj_ReadRGB1(pObjfile);
break;
default:
- fprintf(stderr, "'%s' is an unsupported version",
- tzObjectfile);
- exit(1);
- break;
+ errx(1, "'%s' is an unsupported version", tzObjectfile);
}
} else {
- fprintf(stderr, "'%s' is not a valid object\n", tzObjectfile);
- exit(1);
+ errx(1, "'%s' is not a valid object", tzObjectfile);
}
}
@@ -463,10 +454,7 @@
pObjfile = fopen(tzObjectfile, "rb");
if (pObjfile == NULL) {
- fprintf(stderr, "Unable to open object '%s': ",
- tzObjectfile);
- perror(NULL);
- exit(1);
+ err(1, "Unable to open object '%s'", tzObjectfile);
}
obj_ReadOpenFile(pObjfile, tzObjectfile);
fclose(pObjfile);
@@ -505,35 +493,4 @@
size -= 4;
obj_ReadOpenFile(f, name);
}
-}
-
-void
-lib_Readfile(char *tzLibfile)
-{
- FILE *pObjfile;
-
- oReadLib = 1;
-
- pObjfile = fopen(tzLibfile, "rb");
- if (pObjfile == NULL) {
- fprintf(stderr, "Unable to open object '%s': ", tzLibfile);
- perror(NULL);
- exit(1);
- }
- if (!pObjfile) {
- fprintf(stderr, "Unable to open '%s'\n", tzLibfile);
- exit(1);
- }
- char tzHeader[5];
-
- fread(tzHeader, sizeof(char), 4, pObjfile);
- tzHeader[4] = 0;
- if (strcmp(tzHeader, "XLB0") == 0)
- lib_ReadXLB0(pObjfile);
- else {
- fprintf(stderr, "'%s' is an invalid library\n",
- tzLibfile);
- exit(1);
- }
- fclose(pObjfile);
}
--- a/src/link/output.c
+++ b/src/link/output.c
@@ -7,8 +7,7 @@
#include "link/main.h"
#include "link/assign.h"
-char tzOutname[_MAX_PATH];
-BBOOL oOutput = 0;
+char *tzOutname;
void
writehome(FILE * f)
@@ -71,8 +70,7 @@
void
out_Setname(char *tzOutputfile)
{
- strcpy(tzOutname, tzOutputfile);
- oOutput = 1;
+ tzOutname = tzOutputfile;
}
void
--- a/src/link/patch.c
+++ b/src/link/patch.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
+#include "extern/err.h"
#include "link/mylink.h"
#include "link/symbol.h"
#include "link/main.h"
@@ -46,8 +47,7 @@
default:
break;
}
- fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n");
- exit(1);
+ errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
SLONG
@@ -64,8 +64,7 @@
default:
break;
}
- fprintf(stderr, "*INTERNAL* UNKNOWN SYMBOL TYPE\n");
- exit(1);
+ errx(1, "*INTERNAL* UNKNOWN SYMBOL TYPE");
}
SLONG
@@ -159,10 +158,9 @@
t = rpnpop();
rpnpush(t & 0xFF);
if (t < 0 || (t > 0xFF && t < 0xFF00) || t > 0xFFFF) {
- fprintf(stderr,
- "%s(%ld) : Value must be in the HRAM area\n",
+ errx(1,
+ "%s(%ld) : Value must be in the HRAM area",
pPatch->pzFilename, pPatch->nLineNo);
- exit(1);
}
break;
case RPN_PCEZP:
@@ -169,10 +167,9 @@
t = rpnpop();
rpnpush(t & 0xFF);
if (t < 0x2000 || t > 0x20FF) {
- fprintf(stderr,
- "%s(%ld) : Value must be in the ZP area\n",
+ errx(1,
+ "%s(%ld) : Value must be in the ZP area",
pPatch->pzFilename, pPatch->nLineNo);
- exit(1);
}
break;
case RPN_CONST:
@@ -217,11 +214,10 @@
high |= (*rpn++) << 24;
t = rpnpop();
if (t < low || t > high) {
- fprintf(stderr,
- "%s(%ld) : Value must be in the range [%ld;%ld]\n",
+ errx(1,
+ "%s(%ld) : Value must be in the range [%ld;%ld]",
pPatch->pzFilename,
pPatch->nLineNo, low, high);
- exit(1);
}
rpnpush(t);
size -= 8;
@@ -255,11 +251,10 @@
pSect->pData[pPatch->nOffset] =
(UBYTE) t;
} else {
- fprintf(stderr,
- "%s(%ld) : Value must be 8-bit\n",
+ errx(1,
+ "%s(%ld) : Value must be 8-bit",
pPatch->pzFilename,
pPatch->nLineNo);
- exit(1);
}
break;
case PATCH_WORD_L:
@@ -280,11 +275,10 @@
1] = t & 0xFF;
}
} else {
- fprintf(stderr,
- "%s(%ld) : Value must be 16-bit\n",
+ errx(1,
+ "%s(%ld) : Value must be 16-bit",
pPatch->pzFilename,
pPatch->nLineNo);
- exit(1);
}
break;
case PATCH_LONG_L:
--- a/src/link/rgblink.1
+++ b/src/link/rgblink.1
@@ -29,12 +29,6 @@
.Pp
The arguments are as follows:
.Bl -tag -width Ds
-.It Fl l Ar library
-Include a referenced library module created with
-.Xr rgblib 1 .
-Note that specified libraries will be included only if needed\(emthat is, if
-a SECTION from a library is referenced by an object file.
-Only the relevant SECTION will be included, rather than the entire module.
.It Fl m Ar mapfile
Write a mapfile to the given filename.
.It Fl n Ar symfile
@@ -70,7 +64,6 @@
.Xr rgbds 7 ,
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
-.Xr rgblib 1 ,
.Xr gbz80 7
.Sh HISTORY
.Nm
--- a/src/link/symbol.c
+++ b/src/link/symbol.c
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <string.h>
+#include "extern/err.h"
#include "link/main.h"
#include "link/patch.h"
#include "link/types.h"
@@ -53,8 +54,7 @@
}
}
- fprintf(stderr, "Unknown symbol '%s'\n", tzName);
- exit(1);
+ errx(1, "Unknown symbol '%s'", tzName);
}
}
@@ -72,8 +72,7 @@
}
}
- fprintf(stderr, "Unknown symbol '%s'\n", tzName);
- exit(1);
+ errx(1, "Unknown symbol '%s'", tzName);
}
void
@@ -93,10 +92,7 @@
if (nBank == -1)
return;
- fprintf(stderr,
- "Symbol '%s' defined more than once\n",
- tzName);
- exit(1);
+ errx(1, "Symbol '%s' defined more than once", tzName);
}
}
--- a/src/rgbds.7
+++ b/src/rgbds.7
@@ -13,7 +13,6 @@
.Sh SEE ALSO
.Xr rgbasm 1 ,
.Xr rgbfix 1 ,
-.Xr rgblib 1 ,
.Xr rgblink 1 ,
.Xr gbz80 7
.Sh HISTORY