Merge branch 'nasm-2.03.x'
authorH. Peter Anvin <hpa@zytor.com>
Tue, 17 Jun 2008 04:45:42 +0000 (21:45 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 17 Jun 2008 04:45:42 +0000 (21:45 -0700)
Conflicts:

Makefile.in
Mkfiles/msvc.mak
Mkfiles/netware.mak
Mkfiles/openwcom.mak
Mkfiles/owlinux.mak

41 files changed:
CHANGES
Makefile.in
Mkfiles/msvc.mak
Mkfiles/netware.mak
Mkfiles/openwcom.mak
Mkfiles/owlinux.mak
assemble.c
compiler.h
configure.in
crc64.c
doc/nasmdoc.src
doc/psfonts.ph
eval.c
insns.pl [changed mode: 0644->0755]
lib/vsnprintf.c
macros.pl [changed mode: 0644->0755]
nasm.c
nasm.h
nasmlib.c
nasmlib.h
ndisasm.c
output/outaout.c
output/outas86.c
output/outbin.c
output/outcoff.c
output/outelf32.c
output/outelf64.c
output/outmacho.c
output/outrdf2.c
parser.c
pptok.dat
preproc.c
raa.c [new file with mode: 0644]
raa.h [new file with mode: 0644]
saa.c [new file with mode: 0644]
saa.h [new file with mode: 0644]
stdscan.c
strfunc.c [new file with mode: 0644]
test/utf.asm [new file with mode: 0644]
tokens.dat
wsaa.h [deleted file]

diff --git a/CHANGES b/CHANGES
index e6829bf..5e6bfb9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,9 @@
+2.04
+----
+* Sanitize macro handing in the %error directive.
+* New %warning preprocessor directive.
+* __utf16__ and __utf32__ operators to generate UTF-16 and UTF-32 strings.
+
 2.03.01
 -------
 * Fix buffer overflow in the listing module.
index 645c947..e6447a8 100644 (file)
@@ -59,7 +59,8 @@ X               = @EXEEXT@
        $(NROFF) -man $< > $@
 
 #-- Begin File Lists --#
-NASM = nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
+NASM = nasm.$(O) nasmlib.$(O) raa.$(O) saa.$(O) \
+       float.$(O) insnsa.$(O) insnsb.$(O) \
        assemble.$(O) labels.$(O) hashtbl.$(O) crc64.$(O) parser.$(O) \
        outform.$(O) output/outbin.$(O) \
        output/outaout.$(O) output/outcoff.$(O) \
@@ -67,8 +68,8 @@ NASM =        nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
        output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
        output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
        preproc.$(O) quote.$(O) pptok.$(O) macros.$(O) \
-       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) tokhash.$(O) \
-       regvals.$(O) regflags.$(O)
+       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) strfunc.$(O) \
+       tokhash.$(O) regvals.$(O) regflags.$(O)
 
 NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) \
        insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O)
@@ -236,7 +237,7 @@ alldeps: perlreq
 #-- Everything below is generated by mkdep.pl - do not edit --#
 assemble.$(O): assemble.c assemble.h compiler.h config.h insns.h insnsi.h \
  nasm.h nasmlib.h regs.h tables.h tokens.h version.h
-crc64.$(O): crc64.c compiler.h config.h
+crc64.$(O): crc64.c compiler.h config.h nasmlib.h
 disasm.$(O): disasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
  nasmlib.h regdis.h regs.h sync.h tables.h tokens.h version.h
 eval.$(O): eval.c compiler.h config.h eval.h float.h insnsi.h labels.h \
@@ -263,7 +264,7 @@ listing.$(O): listing.c compiler.h config.h insnsi.h listing.h nasm.h \
 macros.$(O): macros.c compiler.h config.h insnsi.h tables.h
 nasm.$(O): nasm.c assemble.h compiler.h config.h eval.h float.h insns.h \
  insnsi.h labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h \
- preproc.h regs.h stdscan.h tokens.h version.h
+ preproc.h raa.h regs.h saa.h stdscan.h tokens.h version.h
 nasmlib.$(O): nasmlib.c compiler.h config.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tokens.h version.h
 ndisasm.$(O): ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
@@ -271,29 +272,29 @@ ndisasm.$(O): ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
 outform.$(O): outform.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outaout.$(O): output/outaout.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h stdscan.h version.h
+ nasmlib.h outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outas86.$(O): output/outas86.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h version.h
+ nasmlib.h outform.h raa.h regs.h saa.h version.h
 output/outbin.$(O): output/outbin.c compiler.h config.h eval.h insnsi.h \
- labels.h nasm.h nasmlib.h outform.h regs.h stdscan.h version.h
+ labels.h nasm.h nasmlib.h outform.h regs.h saa.h stdscan.h version.h
 output/outcoff.$(O): output/outcoff.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h version.h
+ nasmlib.h outform.h raa.h regs.h saa.h version.h
 output/outdbg.$(O): output/outdbg.c compiler.h config.h insnsi.h nasm.h \
  nasmlib.h outform.h regs.h version.h
 output/outelf32.$(O): output/outelf32.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h stdscan.h version.h wsaa.h
+ nasmlib.h outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outelf64.$(O): output/outelf64.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h stdscan.h version.h wsaa.h
+ nasmlib.h outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outieee.$(O): output/outieee.c compiler.h config.h insnsi.h nasm.h \
  nasmlib.h outform.h regs.h version.h
 output/outmacho.$(O): output/outmacho.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h regs.h version.h
+ nasmlib.h outform.h raa.h regs.h saa.h version.h
 output/outobj.$(O): output/outobj.c compiler.h config.h insnsi.h nasm.h \
  nasmlib.h outform.h regs.h stdscan.h version.h
 output/outrdf.$(O): output/outrdf.c compiler.h config.h insnsi.h nasm.h \
  nasmlib.h outform.h regs.h version.h
 output/outrdf2.$(O): output/outrdf2.c compiler.h config.h insnsi.h nasm.h \
- nasmlib.h outform.h rdoff/rdoff.h regs.h version.h
+ nasmlib.h outform.h rdoff/rdoff.h regs.h saa.h version.h
 parser.$(O): parser.c compiler.h config.h float.h insns.h insnsi.h nasm.h \
  nasmlib.h parser.h regs.h stdscan.h tables.h tokens.h version.h
 pptok.$(O): pptok.c compiler.h config.h hashtbl.h nasmlib.h pptok.h \
@@ -302,13 +303,17 @@ preproc.$(O): preproc.c compiler.h config.h hashtbl.h insnsi.h nasm.h \
  nasmlib.h pptok.h preproc.h quote.h regs.h stdscan.h tables.h tokens.h \
  version.h
 quote.$(O): quote.c compiler.h config.h nasmlib.h quote.h
+raa.$(O): raa.c compiler.h config.h nasmlib.h raa.h
 regdis.$(O): regdis.c regdis.h regs.h
 regflags.$(O): regflags.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
  regs.h tables.h version.h
 regs.$(O): regs.c compiler.h config.h insnsi.h tables.h
 regvals.$(O): regvals.c compiler.h config.h insnsi.h tables.h
+saa.$(O): saa.c compiler.h config.h nasmlib.h saa.h
 stdscan.$(O): stdscan.c compiler.h config.h insns.h insnsi.h nasm.h \
  nasmlib.h quote.h regs.h stdscan.h tokens.h version.h
+strfunc.$(O): strfunc.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
+ version.h
 sync.$(O): sync.c compiler.h config.h nasmlib.h sync.h
 tokhash.$(O): tokhash.c compiler.h config.h hashtbl.h insns.h insnsi.h \
  nasm.h nasmlib.h regs.h tokens.h version.h
index d1654e5..62ef1ce 100644 (file)
@@ -34,7 +34,8 @@ X               = .exe
 
 #-- Begin File Lists --#
 # Edit in Makefile.in, not here!
-NASM = nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
+NASM = nasm.$(O) nasmlib.$(O) raa.$(O) saa.$(O) \
+       float.$(O) insnsa.$(O) insnsb.$(O) \
        assemble.$(O) labels.$(O) hashtbl.$(O) crc64.$(O) parser.$(O) \
        outform.$(O) output/outbin.$(O) \
        output/outaout.$(O) output/outcoff.$(O) \
@@ -42,8 +43,8 @@ NASM =        nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
        output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
        output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
        preproc.$(O) quote.$(O) pptok.$(O) macros.$(O) \
-       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) tokhash.$(O) \
-       regvals.$(O) regflags.$(O)
+       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) strfunc.$(O) \
+       tokhash.$(O) regvals.$(O) regflags.$(O)
 
 NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) \
        insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O)
@@ -182,7 +183,7 @@ everything: all doc rdf
 #-- Everything below is generated by mkdep.pl - do not edit --#
 assemble.$(O): assemble.c assemble.h compiler.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tables.h tokens.h version.h
-crc64.$(O): crc64.c compiler.h
+crc64.$(O): crc64.c compiler.h nasmlib.h
 disasm.$(O): disasm.c compiler.h disasm.h insns.h insnsi.h nasm.h nasmlib.h \
  regdis.h regs.h sync.h tables.h tokens.h version.h
 eval.$(O): eval.c compiler.h eval.h float.h insnsi.h labels.h nasm.h \
@@ -209,7 +210,7 @@ listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h \
 macros.$(O): macros.c compiler.h insnsi.h tables.h
 nasm.$(O): nasm.c assemble.h compiler.h eval.h float.h insns.h insnsi.h \
  labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h preproc.h \
- regs.h stdscan.h tokens.h version.h
+ raa.h regs.h saa.h stdscan.h tokens.h version.h
 nasmlib.$(O): nasmlib.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h \
  tokens.h version.h
 ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h \
@@ -217,42 +218,46 @@ ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h \
 outform.$(O): outform.c compiler.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 output/outaout.$(O): output/outaout.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outas86.$(O): output/outas86.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outbin.$(O): output/outbin.c compiler.h eval.h insnsi.h labels.h \
- nasm.h nasmlib.h outform.h regs.h stdscan.h version.h
+ nasm.h nasmlib.h outform.h regs.h saa.h stdscan.h version.h
 output/outcoff.$(O): output/outcoff.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outdbg.$(O): output/outdbg.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outelf32.$(O): output/outelf32.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outelf64.$(O): output/outelf64.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outieee.$(O): output/outieee.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outmacho.$(O): output/outmacho.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outobj.$(O): output/outobj.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h stdscan.h version.h
 output/outrdf.$(O): output/outrdf.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outrdf2.$(O): output/outrdf2.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h rdoff/rdoff.h regs.h version.h
+ outform.h rdoff/rdoff.h regs.h saa.h version.h
 parser.$(O): parser.c compiler.h float.h insns.h insnsi.h nasm.h nasmlib.h \
  parser.h regs.h stdscan.h tables.h tokens.h version.h
 pptok.$(O): pptok.c compiler.h hashtbl.h nasmlib.h pptok.h preproc.h
 preproc.$(O): preproc.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h \
  pptok.h preproc.h quote.h regs.h stdscan.h tables.h tokens.h version.h
 quote.$(O): quote.c compiler.h nasmlib.h quote.h
+raa.$(O): raa.c compiler.h nasmlib.h raa.h
 regdis.$(O): regdis.c regdis.h regs.h
 regflags.$(O): regflags.c compiler.h insnsi.h nasm.h nasmlib.h regs.h \
  tables.h version.h
 regs.$(O): regs.c compiler.h insnsi.h tables.h
 regvals.$(O): regvals.c compiler.h insnsi.h tables.h
+saa.$(O): saa.c compiler.h nasmlib.h saa.h
 stdscan.$(O): stdscan.c compiler.h insns.h insnsi.h nasm.h nasmlib.h quote.h \
  regs.h stdscan.h tokens.h version.h
+strfunc.$(O): strfunc.c compiler.h insnsi.h nasm.h nasmlib.h regs.h \
+ version.h
 sync.$(O): sync.c compiler.h nasmlib.h sync.h
 tokhash.$(O): tokhash.c compiler.h hashtbl.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tokens.h version.h
index 90ab7a1..6384714 100644 (file)
@@ -30,7 +30,8 @@ O = o
 
 #-- Begin File Lists --#
 # Edit in Makefile.in, not here!
-NASM = nasm.o nasmlib.o float.o insnsa.o insnsb.o \
+NASM = nasm.o nasmlib.o raa.o saa.o \
+       float.o insnsa.o insnsb.o \
        assemble.o labels.o hashtbl.o crc64.o parser.o \
        outform.o outbin.o \
        outaout.o outcoff.o \
@@ -38,8 +39,8 @@ NASM =        nasm.o nasmlib.o float.o insnsa.o insnsb.o \
        outobj.o outas86.o outrdf2.o \
        outdbg.o outieee.o outmacho.o \
        preproc.o quote.o pptok.o macros.o \
-       listing.o eval.o exprlib.o stdscan.o tokhash.o \
-       regvals.o regflags.o
+       listing.o eval.o exprlib.o stdscan.o strfunc.o \
+       tokhash.o regvals.o regflags.o
 
 NDISASM = ndisasm.o disasm.o sync.o nasmlib.o \
        insnsd.o insnsb.o insnsn.o regs.o regdis.o
@@ -122,7 +123,7 @@ $(OBJDIR)/version.inc: $(PROOT)/version $(PROOT)/version.pl $(OBJDIR)
 #-- Everything below is generated by mkdep.pl - do not edit --#
 assemble.o: assemble.c assemble.h compiler.h config.h insns.h insnsi.h \
  nasm.h nasmlib.h regs.h tables.h tokens.h version.h
-crc64.o: crc64.c compiler.h config.h
+crc64.o: crc64.c compiler.h config.h nasmlib.h
 disasm.o: disasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
  nasmlib.h regdis.h regs.h sync.h tables.h tokens.h version.h
 eval.o: eval.c compiler.h config.h eval.h float.h insnsi.h labels.h nasm.h \
@@ -149,7 +150,7 @@ listing.o: listing.c compiler.h config.h insnsi.h listing.h nasm.h nasmlib.h \
 macros.o: macros.c compiler.h config.h insnsi.h tables.h
 nasm.o: nasm.c assemble.h compiler.h config.h eval.h float.h insns.h \
  insnsi.h labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h \
- preproc.h regs.h stdscan.h tokens.h version.h
+ preproc.h raa.h regs.h saa.h stdscan.h tokens.h version.h
 nasmlib.o: nasmlib.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
  regs.h tokens.h version.h
 ndisasm.o: ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
@@ -157,42 +158,46 @@ ndisasm.o: ndisasm.c compiler.h config.h disasm.h insns.h insnsi.h nasm.h \
 outform.o: outform.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 outaout.o: outaout.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
- regs.h stdscan.h version.h
+ raa.h regs.h saa.h stdscan.h version.h
 outas86.o: outas86.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
- regs.h version.h
+ raa.h regs.h saa.h version.h
 outbin.o: outbin.c compiler.h config.h eval.h insnsi.h labels.h nasm.h \
- nasmlib.h outform.h regs.h stdscan.h version.h
+ nasmlib.h outform.h regs.h saa.h stdscan.h version.h
 outcoff.o: outcoff.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
- regs.h version.h
+ raa.h regs.h saa.h version.h
 outdbg.o: outdbg.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 outelf32.o: outelf32.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 outelf64.o: outelf64.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 outieee.o: outieee.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 outmacho.o: outmacho.c compiler.h config.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 outobj.o: outobj.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h stdscan.h version.h
 outrdf.o: outrdf.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 outrdf2.o: outrdf2.c compiler.h config.h insnsi.h nasm.h nasmlib.h outform.h \
- rdoff.h regs.h version.h
+ rdoff.h regs.h saa.h version.h
 parser.o: parser.c compiler.h config.h float.h insns.h insnsi.h nasm.h \
  nasmlib.h parser.h regs.h stdscan.h tables.h tokens.h version.h
 pptok.o: pptok.c compiler.h config.h hashtbl.h nasmlib.h pptok.h preproc.h
 preproc.o: preproc.c compiler.h config.h hashtbl.h insnsi.h nasm.h nasmlib.h \
  pptok.h preproc.h quote.h regs.h stdscan.h tables.h tokens.h version.h
 quote.o: quote.c compiler.h config.h nasmlib.h quote.h
+raa.o: raa.c compiler.h config.h nasmlib.h raa.h
 regdis.o: regdis.c regdis.h regs.h
 regflags.o: regflags.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
  tables.h version.h
 regs.o: regs.c compiler.h config.h insnsi.h tables.h
 regvals.o: regvals.c compiler.h config.h insnsi.h tables.h
+saa.o: saa.c compiler.h config.h nasmlib.h saa.h
 stdscan.o: stdscan.c compiler.h config.h insns.h insnsi.h nasm.h nasmlib.h \
  quote.h regs.h stdscan.h tokens.h version.h
+strfunc.o: strfunc.c compiler.h config.h insnsi.h nasm.h nasmlib.h regs.h \
+ version.h
 sync.o: sync.c compiler.h config.h nasmlib.h sync.h
 tokhash.o: tokhash.c compiler.h config.h hashtbl.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tokens.h version.h
index 9fada2a..de58696 100644 (file)
@@ -46,7 +46,8 @@ X               = .exe
 # Note: wcl386 is broken if forward slashes are used as path separators.
 #-- Begin File Lists --#
 # Edit in Makefile.in, not here!
-NASM = nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) &
+NASM = nasm.$(O) nasmlib.$(O) raa.$(O) saa.$(O) &
+       float.$(O) insnsa.$(O) insnsb.$(O) &
        assemble.$(O) labels.$(O) hashtbl.$(O) crc64.$(O) parser.$(O) &
        outform.$(O) output\outbin.$(O) &
        output\outaout.$(O) output\outcoff.$(O) &
@@ -54,8 +55,8 @@ NASM =        nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) &
        output\outobj.$(O) output\outas86.$(O) output\outrdf2.$(O) &
        output\outdbg.$(O) output\outieee.$(O) output\outmacho.$(O) &
        preproc.$(O) quote.$(O) pptok.$(O) macros.$(O) &
-       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) tokhash.$(O) &
-       regvals.$(O) regflags.$(O)
+       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) strfunc.$(O) &
+       tokhash.$(O) regvals.$(O) regflags.$(O)
 
 NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) &
        insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O)
@@ -211,7 +212,7 @@ everything: all doc rdf
 #-- Everything below is generated by mkdep.pl - do not edit --#
 assemble.$(O): assemble.c assemble.h compiler.h insns.h insnsi.h nasm.h &
  nasmlib.h regs.h tables.h tokens.h version.h
-crc64.$(O): crc64.c compiler.h
+crc64.$(O): crc64.c compiler.h nasmlib.h
 disasm.$(O): disasm.c compiler.h disasm.h insns.h insnsi.h nasm.h nasmlib.h &
  regdis.h regs.h sync.h tables.h tokens.h version.h
 eval.$(O): eval.c compiler.h eval.h float.h insnsi.h labels.h nasm.h &
@@ -238,7 +239,7 @@ listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h &
 macros.$(O): macros.c compiler.h insnsi.h tables.h
 nasm.$(O): nasm.c assemble.h compiler.h eval.h float.h insns.h insnsi.h &
  labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h preproc.h &
- regs.h stdscan.h tokens.h version.h
+ raa.h regs.h saa.h stdscan.h tokens.h version.h
 nasmlib.$(O): nasmlib.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h &
  tokens.h version.h
 ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h &
@@ -246,42 +247,46 @@ ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h &
 outform.$(O): outform.c compiler.h insnsi.h nasm.h nasmlib.h outform.h &
  regs.h version.h
 output\outaout.$(O): output\outaout.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h stdscan.h version.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output\outas86.$(O): output\outas86.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output\outbin.$(O): output\outbin.c compiler.h eval.h insnsi.h labels.h &
- nasm.h nasmlib.h outform.h regs.h stdscan.h version.h
+ nasm.h nasmlib.h outform.h regs.h saa.h stdscan.h version.h
 output\outcoff.$(O): output\outcoff.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output\outdbg.$(O): output\outdbg.c compiler.h insnsi.h nasm.h nasmlib.h &
  outform.h regs.h version.h
 output\outelf32.$(O): output\outelf32.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output\outelf64.$(O): output\outelf64.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output\outieee.$(O): output\outieee.c compiler.h insnsi.h nasm.h nasmlib.h &
  outform.h regs.h version.h
 output\outmacho.$(O): output\outmacho.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output\outobj.$(O): output\outobj.c compiler.h insnsi.h nasm.h nasmlib.h &
  outform.h regs.h stdscan.h version.h
 output\outrdf.$(O): output\outrdf.c compiler.h insnsi.h nasm.h nasmlib.h &
  outform.h regs.h version.h
 output\outrdf2.$(O): output\outrdf2.c compiler.h insnsi.h nasm.h nasmlib.h &
- outform.h rdoff\rdoff.h regs.h version.h
+ outform.h rdoff\rdoff.h regs.h saa.h version.h
 parser.$(O): parser.c compiler.h float.h insns.h insnsi.h nasm.h nasmlib.h &
  parser.h regs.h stdscan.h tables.h tokens.h version.h
 pptok.$(O): pptok.c compiler.h hashtbl.h nasmlib.h pptok.h preproc.h
 preproc.$(O): preproc.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h &
  pptok.h preproc.h quote.h regs.h stdscan.h tables.h tokens.h version.h
 quote.$(O): quote.c compiler.h nasmlib.h quote.h
+raa.$(O): raa.c compiler.h nasmlib.h raa.h
 regdis.$(O): regdis.c regdis.h regs.h
 regflags.$(O): regflags.c compiler.h insnsi.h nasm.h nasmlib.h regs.h &
  tables.h version.h
 regs.$(O): regs.c compiler.h insnsi.h tables.h
 regvals.$(O): regvals.c compiler.h insnsi.h tables.h
+saa.$(O): saa.c compiler.h nasmlib.h saa.h
 stdscan.$(O): stdscan.c compiler.h insns.h insnsi.h nasm.h nasmlib.h quote.h &
  regs.h stdscan.h tokens.h version.h
+strfunc.$(O): strfunc.c compiler.h insnsi.h nasm.h nasmlib.h regs.h &
+ version.h
 sync.$(O): sync.c compiler.h nasmlib.h sync.h
 tokhash.$(O): tokhash.c compiler.h hashtbl.h insns.h insnsi.h nasm.h &
  nasmlib.h regs.h tokens.h version.h
index 5b233e6..4dd5eef 100644 (file)
@@ -57,7 +57,8 @@ X               = .exe
 
 #-- Begin File Lists --#
 # Edit in Makefile.in, not here!
-NASM = nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
+NASM = nasm.$(O) nasmlib.$(O) raa.$(O) saa.$(O) \
+       float.$(O) insnsa.$(O) insnsb.$(O) \
        assemble.$(O) labels.$(O) hashtbl.$(O) crc64.$(O) parser.$(O) \
        outform.$(O) output/outbin.$(O) \
        output/outaout.$(O) output/outcoff.$(O) \
@@ -65,8 +66,8 @@ NASM =        nasm.$(O) nasmlib.$(O) float.$(O) insnsa.$(O) insnsb.$(O) \
        output/outobj.$(O) output/outas86.$(O) output/outrdf2.$(O) \
        output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
        preproc.$(O) quote.$(O) pptok.$(O) macros.$(O) \
-       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) tokhash.$(O) \
-       regvals.$(O) regflags.$(O)
+       listing.$(O) eval.$(O) exprlib.$(O) stdscan.$(O) strfunc.$(O) \
+       tokhash.$(O) regvals.$(O) regflags.$(O)
 
 NDISASM = ndisasm.$(O) disasm.$(O) sync.$(O) nasmlib.$(O) \
        insnsd.$(O) insnsb.$(O) insnsn.$(O) regs.$(O) regdis.$(O)
@@ -221,7 +222,7 @@ everything: all doc rdf
 #-- Everything below is generated by mkdep.pl - do not edit --#
 assemble.$(O): assemble.c assemble.h compiler.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tables.h tokens.h version.h
-crc64.$(O): crc64.c compiler.h
+crc64.$(O): crc64.c compiler.h nasmlib.h
 disasm.$(O): disasm.c compiler.h disasm.h insns.h insnsi.h nasm.h nasmlib.h \
  regdis.h regs.h sync.h tables.h tokens.h version.h
 eval.$(O): eval.c compiler.h eval.h float.h insnsi.h labels.h nasm.h \
@@ -248,7 +249,7 @@ listing.$(O): listing.c compiler.h insnsi.h listing.h nasm.h nasmlib.h \
 macros.$(O): macros.c compiler.h insnsi.h tables.h
 nasm.$(O): nasm.c assemble.h compiler.h eval.h float.h insns.h insnsi.h \
  labels.h listing.h nasm.h nasmlib.h outform.h parser.h pptok.h preproc.h \
- regs.h stdscan.h tokens.h version.h
+ raa.h regs.h saa.h stdscan.h tokens.h version.h
 nasmlib.$(O): nasmlib.c compiler.h insns.h insnsi.h nasm.h nasmlib.h regs.h \
  tokens.h version.h
 ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h \
@@ -256,42 +257,46 @@ ndisasm.$(O): ndisasm.c compiler.h disasm.h insns.h insnsi.h nasm.h \
 outform.$(O): outform.c compiler.h insnsi.h nasm.h nasmlib.h outform.h \
  regs.h version.h
 output/outaout.$(O): output/outaout.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outas86.$(O): output/outas86.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outbin.$(O): output/outbin.c compiler.h eval.h insnsi.h labels.h \
- nasm.h nasmlib.h outform.h regs.h stdscan.h version.h
+ nasm.h nasmlib.h outform.h regs.h saa.h stdscan.h version.h
 output/outcoff.$(O): output/outcoff.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outdbg.$(O): output/outdbg.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outelf32.$(O): output/outelf32.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outelf64.$(O): output/outelf64.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h stdscan.h version.h wsaa.h
+ outform.h raa.h regs.h saa.h stdscan.h version.h
 output/outieee.$(O): output/outieee.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outmacho.$(O): output/outmacho.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h regs.h version.h
+ outform.h raa.h regs.h saa.h version.h
 output/outobj.$(O): output/outobj.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h stdscan.h version.h
 output/outrdf.$(O): output/outrdf.c compiler.h insnsi.h nasm.h nasmlib.h \
  outform.h regs.h version.h
 output/outrdf2.$(O): output/outrdf2.c compiler.h insnsi.h nasm.h nasmlib.h \
- outform.h rdoff/rdoff.h regs.h version.h
+ outform.h rdoff/rdoff.h regs.h saa.h version.h
 parser.$(O): parser.c compiler.h float.h insns.h insnsi.h nasm.h nasmlib.h \
  parser.h regs.h stdscan.h tables.h tokens.h version.h
 pptok.$(O): pptok.c compiler.h hashtbl.h nasmlib.h pptok.h preproc.h
 preproc.$(O): preproc.c compiler.h hashtbl.h insnsi.h nasm.h nasmlib.h \
  pptok.h preproc.h quote.h regs.h stdscan.h tables.h tokens.h version.h
 quote.$(O): quote.c compiler.h nasmlib.h quote.h
+raa.$(O): raa.c compiler.h nasmlib.h raa.h
 regdis.$(O): regdis.c regdis.h regs.h
 regflags.$(O): regflags.c compiler.h insnsi.h nasm.h nasmlib.h regs.h \
  tables.h version.h
 regs.$(O): regs.c compiler.h insnsi.h tables.h
 regvals.$(O): regvals.c compiler.h insnsi.h tables.h
+saa.$(O): saa.c compiler.h nasmlib.h saa.h
 stdscan.$(O): stdscan.c compiler.h insns.h insnsi.h nasm.h nasmlib.h quote.h \
  regs.h stdscan.h tokens.h version.h
+strfunc.$(O): strfunc.c compiler.h insnsi.h nasm.h nasmlib.h regs.h \
+ version.h
 sync.$(O): sync.c compiler.h nasmlib.h sync.h
 tokhash.$(O): tokhash.c compiler.h hashtbl.h insns.h insnsi.h nasm.h \
  nasmlib.h regs.h tokens.h version.h
index 442ed2a..31955e5 100644 (file)
@@ -335,7 +335,8 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
                         out(offset, segment, &e->offset,
                             OUT_ADDRESS, wsize, e->segment, e->wrt);
                     offset += wsize;
-                } else if (e->type == EOT_DB_STRING) {
+                } else if (e->type == EOT_DB_STRING ||
+                          e->type == EOT_DB_STRING_FREE) {
                     int align;
 
                     out(offset, segment, e->stringval,
@@ -365,15 +366,8 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
     }
 
     if (instruction->opcode == I_INCBIN) {
-        static char fname[FILENAME_MAX];
+        const char *fname = instruction->eops->stringval;
         FILE *fp;
-        int32_t len;
-
-        len = FILENAME_MAX - 1;
-        if (len > instruction->eops->stringlen)
-            len = instruction->eops->stringlen;
-        strncpy(fname, instruction->eops->stringval, len);
-        fname[len] = '\0';
 
        fp = fopen(fname, "rb");
        if (!fp) {
@@ -383,17 +377,18 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
             error(ERR_NONFATAL, "`incbin': unable to seek on file `%s'",
                   fname);
        } else {
-            static char buf[2048];
-            int32_t t = instruction->times;
-            int32_t base = 0;
+            static char buf[4096];
+            size_t t = instruction->times;
+            size_t base = 0;
+           size_t len;
 
             len = ftell(fp);
             if (instruction->eops->next) {
                 base = instruction->eops->next->offset;
                 len -= base;
                 if (instruction->eops->next->next &&
-                    len > instruction->eops->next->next->offset)
-                    len = instruction->eops->next->next->offset;
+                    len > (size_t)instruction->eops->next->next->offset)
+                    len = (size_t)instruction->eops->next->next->offset;
             }
             /*
              * Dummy call to list->output to give the offset to the
@@ -402,7 +397,7 @@ int64_t assemble(int32_t segment, int64_t offset, int bits, uint32_t cp,
             list->output(offset, NULL, OUT_RAWDATA, 0);
             list->uplevel(LIST_INCBIN);
             while (t--) {
-                int32_t l;
+                size_t l;
 
                 fseek(fp, base, SEEK_SET);
                 l = len;
@@ -660,7 +655,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
             osize = 0;
             if (e->type == EOT_DB_NUMBER)
                 osize = 1;
-            else if (e->type == EOT_DB_STRING)
+            else if (e->type == EOT_DB_STRING ||
+                    e->type == EOT_DB_STRING_FREE)
                 osize = e->stringlen;
 
             align = (-osize) % wsize;
@@ -672,16 +668,10 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
     }
 
     if (instruction->opcode == I_INCBIN) {
-        char fname[FILENAME_MAX];
+       const char *fname = instruction->eops->stringval;
         FILE *fp;
-        int32_t len;
-
-        len = FILENAME_MAX - 1;
-        if (len > instruction->eops->stringlen)
-            len = instruction->eops->stringlen;
-        strncpy(fname, instruction->eops->stringval, len);
-        fname[len] = '\0';
-       
+        size_t len;
+
        fp = fopen(fname, "rb");
        if (!fp)
             error(ERR_NONFATAL, "`incbin': unable to open file `%s'",
@@ -695,8 +685,8 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
             if (instruction->eops->next) {
                 len -= instruction->eops->next->offset;
                 if (instruction->eops->next->next &&
-                    len > instruction->eops->next->next->offset) {
-                    len = instruction->eops->next->next->offset;
+                    len > (size_t)instruction->eops->next->next->offset) {
+                    len = (size_t)instruction->eops->next->next->offset;
                 }
             }
             return instruction->times * len;
index ced029c..82b0d7a 100644 (file)
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
-#endif
+/* autoconf doesn't define these if they are redundant, but we want to
+   be able to #ifdef them... */
+#else
+/* Default these to unsupported unless we have config.h */
+# ifndef inline
+#  define inline
+# endif
+# ifndef restrict
+#  define restrict
+# endif
+#endif /* HAVE_CONFIG_H */
 
 /* This is required to get the standard <inttypes.h> macros when compiling
    with a C++ compiler.  This must be defined *before* <inttypes.h> is
@@ -71,7 +81,9 @@ int vsnprintf(char *, size_t, const char *, va_list);
 # ifdef HAVE_STDBOOL_H
 #  include <stdbool.h>
 # else
-typedef enum { false, true } bool;
+/* This is sort of dangerous, since casts will behave different than
+   casting to the standard boolean type.  Always use !!, not (bool). */
+typedef enum bool { false, true } bool;
 # endif
 #endif
 
@@ -103,8 +115,23 @@ char *strsep(char **, const char *);
  */
 #if defined(__386__) || defined(__i386__) || defined(__x86_64__)
 # define X86_MEMORY 1
+# ifndef WORDS_LITTLEENDIAN
+#  define WORDS_LITTLEENDIAN 1
+# endif
 #else
 # define X86_MEMORY 0
 #endif
 
+/*
+ * Hints to the compiler that a particular branch of code is more or
+ * less likely to be taken.
+ */
+#if defined(__GNUC__) && __GNUC__ >= 3
+# define likely(x)     __builtin_expect(!!(x), 1)
+# define unlikely(x)   __builtin_expect(!!(x), 0)
+#else
+# define likely(x)     (!!(x))
+# define unlikely(x)   (!!(x))
+#endif
+
 #endif /* NASM_COMPILER_H */
index da26da9..9e79f34 100644 (file)
@@ -1,6 +1,6 @@
-dnl Process this file with autoconf 2.59 or later to produce
+dnl Process this file with autoconf 2.61 or later to produce
 dnl a configure script.
-AC_PREREQ(2.59)
+AC_PREREQ(2.61)
 AC_INIT(config.h.in)
 AC_CONFIG_HEADERS(config.h)
 
@@ -48,9 +48,7 @@ AC_PREFIX_PROGRAM(nasm)
 
 dnl Checks for programs.
 dnl Consider AC_USE_SYSTEM_EXTENSIONS if autoconf 2.61 is OK in the future
-AC_GNU_SOURCE
-AC_ISC_POSIX
-AC_MINIX
+AC_USE_SYSTEM_EXTENSIONS
 AC_PROG_CC
 AC_PROG_LN_S
 AC_PROG_MAKE_SET
@@ -94,7 +92,16 @@ AC_CHECK_HEADERS(stdbool.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
+AC_C_INLINE
+AC_C_RESTRICT
 AC_TYPE_SIZE_T
+AC_C_BIGENDIAN(AC_DEFINE(WORDS_BIGENDIAN),AC_DEFINE(WORDS_LITTLEENDIAN))
+AH_TEMPLATE(WORDS_BIGENDIAN,
+[Define to 1 if your processor stores words with the most significant
+byte first (like Motorola and SPARC, unlike Intel and VAX).])
+AH_TEMPLATE(WORDS_LITTLEENDIAN,
+[Define to 1 if your processor stores words with the least significant
+byte first (like Intel and VAX, unlike Motorola and SPARC).])
 
 dnl Checks for library functions.
 AC_SUBST(XOBJS)
diff --git a/crc64.c b/crc64.c
index fc165b7..e8639c8 100644 (file)
--- a/crc64.c
+++ b/crc64.c
@@ -1,6 +1,5 @@
 #include "compiler.h"
-#include <inttypes.h>
-#include <ctype.h>
+#include "nasmlib.h"
 
 static const uint64_t crc64_tab[256] = {
     UINT64_C(0x0000000000000000), UINT64_C(0x7ad870c830358979),
@@ -149,8 +148,7 @@ uint64_t crc64i(uint64_t crc, const char *str)
     uint8_t c;
 
     while ((c = *str++) != 0) {
-       c = tolower(c);
-       crc = crc64_tab[(uint8_t)crc ^ c] ^ (crc >> 8);
+       crc = crc64_tab[(uint8_t)crc ^ nasm_tolower(c)] ^ (crc >> 8);
     }
 
     return crc;
index 45c1b0e..7a0c5a5 100644 (file)
@@ -205,6 +205,8 @@ Object File Format
 \IR{unicode} Unicode
 \IR{unix} Unix
 \IR{utf-8} UTF-8
+\IR{utf-16} UTF-16
+\IR{utf-32} UTF-32
 \IA{sco unix}{unix, sco}
 \IR{unix, sco} Unix, SCO
 \IA{unix source archive}{unix, source archive}
@@ -1174,7 +1176,7 @@ are \i\c{DB}, \i\c{DW}, \i\c{DD}, \i\c{DQ}, \i\c{DT}, \i\c{DO} and
 prefix.
 
 
-\S{db} \c{DB} and friends: Declaring initialized Data
+\S{db} \c{DB} and Friends: Declaring Initialized Data
 
 \i\c{DB}, \i\c{DW}, \i\c{DD}, \i\c{DQ}, \i\c{DT}, \i\c{DO} and
 \i\c{DY} are used, much as in MASM, to declare initialized data in the
@@ -1198,7 +1200,7 @@ output file. They can be invoked in a wide range of ways:
 \c{DT}, \c{DO} and \c{DY} do not accept \i{numeric constants} as operands.
 
 
-\S{resb} \c{RESB} and friends: Declaring \i{Uninitialized} Data
+\S{resb} \c{RESB} and Friends: Declaring \i{Uninitialized} Data
 
 \i\c{RESB}, \i\c{RESW}, \i\c{RESD}, \i\c{RESQ}, \i\c{REST}, \i\c{RESO}
 and \i\c{RESY} are designed to be used in the BSS section of a module:
@@ -1487,6 +1489,23 @@ effect as \c{db 'a'}, which would be silly. Similarly, three-character
 or four-character constants are treated as strings when they are
 operands to \c{DW}, and so forth.
 
+\S{unicode} \I{UTF-16}\I{UTF-32}\i{Unicode} Strings
+
+The special operators \i\c{__utf16__} and \i\c{__utf32__} allows
+definition of Unicode strings.  They take a string in UTF-8 format and
+converts it to (littleendian) UTF-16 or UTF-32, respectively.
+
+For example:
+
+\c %define u(x) __utf16__(x)
+\c %define w(x) __utf32__(x)
+\c
+\c       dw u('C:\WINDOWS'), 0       ; Pathname in UTF-16
+\c       dd w(`A + B = \u206a`), 0   ; String in UTF-32
+
+\c{__utf16__} and \c{__utf32__} can be applied either to strings
+passed to the \c{DB} family instructions, or to character constants in
+an expression context.  
 
 \S{fltconst} \I{floating-point, constants}Floating-Point Constants
 
@@ -2875,19 +2894,19 @@ any tokens at all, whitespace excepted.
 The usual \i\c{%elifempty}, \i\c\{%ifnempty}, and \i\c{%elifnempty}
 variants are also provided.
 
-\S{pperror} \i\c{%error}: Reporting \i{User-Defined Errors}
+\S{pperror} \i\c{%error} and \i\c{%warning}: Reporting \i{User-Defined Errors}
 
 The preprocessor directive \c{%error} will cause NASM to report an
 error if it occurs in assembled code. So if other users are going to
-try to assemble your source files, you can ensure that they define
-the right macros by means of code like this:
+try to assemble your source files, you can ensure that they define the
+right macros by means of code like this:
 
-\c %ifdef SOME_MACRO
+\c %ifdef F1
 \c     ; do some setup
-\c %elifdef SOME_OTHER_MACRO
+\c %elifdef F2
 \c     ; do some different setup
 \c %else
-\c     %error Neither SOME_MACRO nor SOME_OTHER_MACRO was defined.
+\c     %error Neither F1 nor F2 was defined.
 \c %endif
 
 Then any user who fails to understand the way your code is supposed
@@ -2895,6 +2914,16 @@ to be assembled will be quickly warned of their mistake, rather than
 having to wait until the program crashes on being run and then not
 knowing what went wrong.
 
+Similarly, \c{%warning} issues a warning:
+
+\c %ifdef F1
+\c     ; do some setup
+\c %elifdef F2
+\c     ; do some different setup
+\c %else
+\c     %warning Neither F1 nor F2 was defined, assuming F1.
+\c     %define F1
+\c %endif
 
 \H{rep} \i{Preprocessor Loops}\I{repeating code}: \i\c{%rep}
 
index 1e6aac1..8d2f4e6 100644 (file)
@@ -10,37 +10,98 @@ require 'metrics/ptmri8a.ph';       # Times-Italic
 require 'metrics/ptmbi8a.ph';  # Times-BoldItalic
 require 'metrics/pcrr8a.ph';   # Courier
 require 'metrics/pcrb8a.ph';   # Courier-Bold
+require 'metrics/phvr8a.ph';   # Helvetica
+require 'metrics/phvro8a.ph';  # Helvetica-Oblique
 require 'metrics/phvb8a.ph';   # Helvetica-Bold
 require 'metrics/phvbo8a.ph';  # Helvetica-BoldOblique
 
 # The fonts we want to use for various things
 # The order is: <normal> <emphatic> <code>
 
-%TitlFont = (name => 'tfont',
-            leading => 22,
+if ( 1 ) {
+    # Times family fonts
+
+    %TitlFont = (name => 'tfont',
+                leading => 22,
             fonts => [[20,\%PS_Times_Bold],
                       [20,\%PS_Times_BoldItalic],
                       [20,\%PS_Courier_Bold]]);
-%ChapFont = (name => 'cfont',
-             leading => 19.2,
-            fonts => [[18,\%PS_Times_Bold],
-                      [18,\%PS_Times_BoldItalic],
-                      [18,\%PS_Courier_Bold]]);
-%HeadFont = (name => 'hfont',
-            leading => 15.4,
-            fonts => [[14,\%PS_Times_Bold],
-                      [14,\%PS_Times_BoldItalic],
-                      [14,\%PS_Courier_Bold]]);
-%SubhFont = (name => 'sfont',
-            leading => 13.2,
-            fonts => [[12,\%PS_Times_Bold],
-                      [12,\%PS_Times_BoldItalic],
-                      [12,\%PS_Courier_Bold]]);
-%BodyFont = (name => 'bfont',
-            leading => 11,
-            fonts => [[10,\%PS_Times_Roman],
-                      [10,\%PS_Times_Italic],
-                      [10,\%PS_Courier]]);
+    %ChapFont = (name => 'cfont',
+                leading => 19.2,
+                fonts => [[18,\%PS_Times_Bold],
+                          [18,\%PS_Times_BoldItalic],
+                          [18,\%PS_Courier_Bold]]);
+    %HeadFont = (name => 'hfont',
+                leading => 15.4,
+                fonts => [[14,\%PS_Times_Bold],
+                          [14,\%PS_Times_BoldItalic],
+                          [14,\%PS_Courier_Bold]]);
+    %SubhFont = (name => 'sfont',
+                leading => 13.2,
+                fonts => [[12,\%PS_Times_Bold],
+                          [12,\%PS_Times_BoldItalic],
+                          [12,\%PS_Courier_Bold]]);
+    %BodyFont = (name => 'bfont',
+                leading => 11,
+                fonts => [[10,\%PS_Times_Roman],
+                          [10,\%PS_Times_Italic],
+                          [10,\%PS_Courier]]);
+} elsif ( 0 ) {
+    # Helvetica family fonts
+
+    %TitlFont = (name => 'tfont',
+                leading => 22,
+                fonts => [[20,\%PS_Helvetica_Bold],
+                          [20,\%PS_Helvetica_BoldOblique],
+                          [20,\%PS_Courier_Bold]]);
+    %ChapFont = (name => 'cfont',
+                leading => 19.2,
+                fonts => [[18,\%PS_Helvetica_Bold],
+                          [18,\%PS_Helvetica_BoldOblique],
+                          [18,\%PS_Courier_Bold]]);
+    %HeadFont = (name => 'hfont',
+                leading => 15.4,
+                fonts => [[14,\%PS_Helvetica_Bold],
+                          [14,\%PS_Helvetica_BoldOblique],
+                          [14,\%PS_Courier_Bold]]);
+    %SubhFont = (name => 'sfont',
+                leading => 13.2,
+                fonts => [[12,\%PS_Helvetica_Bold],
+                          [12,\%PS_Helvetica_BoldOblique],
+                          [12,\%PS_Courier_Bold]]);
+    %BodyFont = (name => 'bfont',
+                leading => 11,
+                fonts => [[10,\%PS_Helvetica],
+                          [10,\%PS_Helvetica_Oblique],
+                          [10,\%PS_Courier]]);
+} else {
+    # Body text Times; headings Helvetica
+    %TitlFont = (name => 'tfont',
+                leading => 22,
+                fonts => [[20,\%PS_Helvetica_Bold],
+                          [20,\%PS_Helvetica_BoldOblique],
+                          [20,\%PS_Courier_Bold]]);
+    %ChapFont = (name => 'cfont',
+                leading => 19.2,
+                fonts => [[18,\%PS_Helvetica_Bold],
+                          [18,\%PS_Helvetica_BoldOblique],
+                          [18,\%PS_Courier_Bold]]);
+    %HeadFont = (name => 'hfont',
+                leading => 15.4,
+                fonts => [[14,\%PS_Helvetica_Bold],
+                          [14,\%PS_Helvetica_BoldOblique],
+                          [14,\%PS_Courier_Bold]]);
+    %SubhFont = (name => 'sfont',
+                leading => 13.2,
+                fonts => [[12,\%PS_Helvetica_Bold],
+                          [12,\%PS_Helvetica_BoldOblique],
+                          [12,\%PS_Courier_Bold]]);
+    %BodyFont = (name => 'bfont',
+                leading => 11,
+                fonts => [[10,\%PS_Times_Roman],
+                          [10,\%PS_Times_Italic],
+                          [10,\%PS_Courier]]);
+}
 
 #
 # List of all fontsets; used to compute the list of fonts needed
diff --git a/eval.c b/eval.c
index d20578b..917dcfc 100644 (file)
--- a/eval.c
+++ b/eval.c
@@ -662,12 +662,56 @@ static expr *eval_floatize(enum floatize type)
     return finishtemp();
 }
 
+static expr *eval_strfunc(enum strfunc type)
+{
+    char *string;
+    size_t string_len;
+    int64_t val;
+    bool parens, rn_warn;
+
+    i = scan(scpriv, tokval);
+    if (i == '(') {
+       parens = true;
+       i = scan(scpriv, tokval);
+    }
+    if (i != TOKEN_STR) {
+       error(ERR_NONFATAL, "expecting string");
+       return NULL;
+    }
+    string_len = string_transform(tokval->t_charptr, tokval->t_inttwo,
+                                 &string, type);
+    if (string_len == (size_t)-1) {
+       error(ERR_NONFATAL, "invalid string for transform");
+       return NULL;
+    }
+
+    val = readstrnum(string, string_len, &rn_warn);
+    if (parens) {
+       i = scan(scpriv, tokval);
+       if (i != ')') {
+           error(ERR_NONFATAL, "expecting `)'");
+           return NULL;
+       }
+    }
+
+    if (rn_warn)
+       error(ERR_WARNING|ERR_PASS1, "character constant too long");
+
+    begintemp();
+    addtotemp(EXPR_SIMPLE, val);
+
+    i = scan(scpriv, tokval);
+    return finishtemp();
+}
+
 static expr *expr6(int critical)
 {
     int32_t type;
     expr *e;
     int32_t label_seg;
     int64_t label_ofs;
+    int64_t tmpval;
+    bool rn_warn;
     char *scope;
 
     switch (i) {
@@ -728,6 +772,9 @@ static expr *expr6(int critical)
     case TOKEN_FLOATIZE:
        return eval_floatize(tokval->t_integer);
 
+    case TOKEN_STRFUNC:
+       return eval_strfunc(tokval->t_integer);
+
     case '(':
         i = scan(scpriv, tokval);
         e = bexpr(critical);
@@ -741,6 +788,7 @@ static expr *expr6(int critical)
         return e;
 
     case TOKEN_NUM:
+    case TOKEN_STR:
     case TOKEN_REG:
     case TOKEN_ID:
     case TOKEN_INSN:           /* Opcodes that occur here are really labels */
@@ -751,6 +799,12 @@ static expr *expr6(int critical)
         case TOKEN_NUM:
             addtotemp(EXPR_SIMPLE, tokval->t_integer);
             break;
+       case TOKEN_STR:
+           tmpval = readstrnum(tokval->t_charptr, tokval->t_inttwo, &rn_warn);
+           if (rn_warn)
+               error(ERR_WARNING|ERR_PASS1, "character constant too long");
+            addtotemp(EXPR_SIMPLE, tmpval);
+           break;
         case TOKEN_REG:
             addtotemp(tokval->t_integer, 1L);
             if (hint && hint->type == EAH_NOHINT)
old mode 100644 (file)
new mode 100755 (executable)
index 976b0ea..f5ae2fe 100644 (file)
@@ -14,8 +14,6 @@
 
 #include "nasmlib.h"
 
-extern efunc nasm_malloc_error;
-
 #define BUFFER_SIZE    65536   /* Bigger than any string we might print... */
 
 static char snprintf_buffer[BUFFER_SIZE];
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/nasm.c b/nasm.c
index 188a204..52009d3 100644 (file)
--- a/nasm.c
+++ b/nasm.c
@@ -19,6 +19,8 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "float.h"
 #include "stdscan.h"
 #include "insns.h"
@@ -296,6 +298,8 @@ int main(int argc, char **argv)
 
     error_file = stderr;
 
+    tolower_init();
+
     nasm_set_malloc_error(report_error);
     offsets = raa_init();
     forwrefs = saa_init((int32_t)sizeof(struct forwrefinfo));
@@ -1908,7 +1912,7 @@ static bool is_suppressed_warning(int severity)
 static void report_error_common(int severity, const char *fmt,
                                 va_list args)
 {
-    switch (severity & ERR_MASK) {
+    switch (severity & (ERR_MASK|ERR_NO_SEVERITY)) {
     case ERR_WARNING:
         fputs("warning: ", error_file);
         break;
@@ -1924,6 +1928,8 @@ static void report_error_common(int severity, const char *fmt,
     case ERR_DEBUG:
         fputs("debug: ", error_file);
         break;
+    default:
+       break;
     }
 
     vfprintf(error_file, fmt, args);
diff --git a/nasm.h b/nasm.h
index 384fb65..ec44f16 100644 (file)
--- a/nasm.h
+++ b/nasm.h
@@ -165,8 +165,14 @@ enum token_type {          /* token types, other than chars */
     TOKEN_INVALID = -1,         /* a placeholder value */
     TOKEN_EOS = 0,              /* end of string */
     TOKEN_EQ = '=', TOKEN_GT = '>', TOKEN_LT = '<',     /* aliases */
-    TOKEN_ID = 256, TOKEN_NUM, TOKEN_REG, TOKEN_INSN,   /* major token types */
-    TOKEN_ERRNUM,               /* numeric constant with error in */
+    TOKEN_ID = 256,            /* identifier */
+    TOKEN_NUM,                 /* numeric constant */
+    TOKEN_ERRNUM,              /* malformed numeric constant */
+    TOKEN_STR,                 /* string constant */
+    TOKEN_ERRSTR,               /* unterminated string constant */
+    TOKEN_FLOAT,                /* floating-point constant */
+    TOKEN_REG,                 /* register name */
+    TOKEN_INSN,                        /* instruction name */
     TOKEN_HERE, TOKEN_BASE,     /* $ and $$ */
     TOKEN_SPECIAL,              /* BYTE, WORD, DWORD, QWORD, FAR, NEAR, etc */
     TOKEN_PREFIX,               /* A32, O16, LOCK, REPNZ, TIMES, etc */
@@ -175,8 +181,8 @@ enum token_type {           /* token types, other than chars */
     TOKEN_GE, TOKEN_LE, TOKEN_NE,       /* >=, <= and <> (!= is same as <>) */
     TOKEN_DBL_AND, TOKEN_DBL_OR, TOKEN_DBL_XOR, /* &&, || and ^^ */
     TOKEN_SEG, TOKEN_WRT,       /* SEG and WRT */
-    TOKEN_FLOAT,                /* floating-point constant */
     TOKEN_FLOATIZE,            /* __floatX__ */
+    TOKEN_STRFUNC,             /* __utf16__, __utf32__ */
 };
 
 enum floatize {
@@ -190,6 +196,14 @@ enum floatize {
     FLOAT_128H,
 };
 
+/* Must match the list in string_transform(), in strfunc.c */
+enum strfunc {
+    STRFUNC_UTF16,
+    STRFUNC_UTF32,
+};
+
+size_t string_transform(char *, size_t, char **, enum strfunc);
+
 /*
  * The expression evaluator must be passed a scanner function; a
  * standard scanner is provided as part of nasmlib.c. The
@@ -600,11 +614,14 @@ enum prefixes {                   /* instruction prefixes */
     PREFIX_ENUM_LIMIT
 };
 
-enum {                          /* extended operand types */
-    EOT_NOTHING, EOT_DB_STRING, EOT_DB_NUMBER
+enum extop_type {              /* extended operand types */
+    EOT_NOTHING,
+    EOT_DB_STRING,             /* Byte string */
+    EOT_DB_STRING_FREE,                /* Byte string which should be nasm_free'd*/
+    EOT_DB_NUMBER,             /* Integer */
 };
 
-enum {                          /* special EA flags */
+enum ea_flags {                        /* special EA flags */
     EAF_BYTEOFFS =  1,          /* force offset part to byte size */
     EAF_WORDOFFS =  2,          /* force offset part to [d]word size */
     EAF_TIMESTWO =  4,          /* really do EAX*2 not EAX+EAX */
@@ -638,12 +655,12 @@ typedef struct operand {  /* operand to an instruction */
 
 typedef struct extop {          /* extended operand */
     struct extop *next;         /* linked list */
-    int32_t type;               /* defined above */
-    char *stringval;          /* if it's a string, then here it is */
-    int stringlen;              /* ... and here's how long it is */
-    int32_t segment;            /* if it's a number/address, then... */
+    char *stringval;           /* if it's a string, then here it is */
+    size_t stringlen;           /* ... and here's how long it is */
     int64_t offset;             /* ... it's given here ... */
+    int32_t segment;            /* if it's a number/address, then... */
     int32_t wrt;                /* ... and here */
+    enum extop_type type;      /* defined above */
 } extop;
 
 /* Prefix positions: each type of prefix goes in a specific slot.
index a4e7915..9a49090 100644 (file)
--- a/nasmlib.c
+++ b/nasmlib.c
@@ -25,6 +25,21 @@ efunc nasm_malloc_error;     /* Exported for the benefit of vsnprintf.c */
 static FILE *logfp;
 #endif
 
+/*
+ * Prepare a table of tolower() results.  This avoids function calls
+ * on some platforms.
+ */
+
+unsigned char nasm_tolower_tab[256];
+
+void tolower_init(void)
+{
+    int i;
+
+    for (i = 0; i < 256; i++)
+       nasm_tolower_tab[i] = tolower(i);
+}
+
 void nasm_set_malloc_error(efunc error)
 {
     nasm_malloc_error = error;
@@ -192,8 +207,8 @@ int nasm_memicmp(const char *s1, const char *s2, size_t n)
     int d;
 
     while (n--) {
-       c1 = tolower(*s1++);
-       c2 = tolower(*s2++);
+       c1 = nasm_tolower(*s1++);
+       c2 = nasm_tolower(*s2++);
        d = c1-c2;
        if (d)
            return d;
@@ -385,7 +400,7 @@ int32_t seg_alloc(void)
     return (next_seg += 2) - 2;
 }
 
-#if X86_MEMORY
+#ifdef WORDS_LITTLEENDIAN
 
 void fwriteint16_t(uint16_t data, FILE * fp)
 {
@@ -407,7 +422,7 @@ void fwriteaddr(uint64_t data, int size, FILE * fp)
     fwrite(&data, 1, size, fp);
 }
 
-#else /* !X86_MEMORY */
+#else /* not WORDS_LITTLEENDIAN */
 
 void fwriteint16_t(uint16_t data, FILE * fp)
 {
@@ -469,404 +484,6 @@ void standard_extension(char *inname, char *outname, char *extension,
         strcpy(p, extension);
 }
 
-#define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
-#define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
-
-#define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
-
-static struct RAA *real_raa_init(int layers)
-{
-    struct RAA *r;
-    int i;
-
-    if (layers == 0) {
-        r = nasm_zalloc(LEAFSIZ);
-        r->shift = 0;
-    } else {
-        r = nasm_malloc(BRANCHSIZ);
-        r->layers = layers;
-        for (i = 0; i < RAA_LAYERSIZE; i++)
-            r->u.b.data[i] = NULL;
-        r->shift = (RAA_BLKSHIFT-RAA_LAYERSHIFT) + layers*RAA_LAYERSHIFT;
-    }
-    return r;
-}
-
-struct RAA *raa_init(void)
-{
-    return real_raa_init(0);
-}
-
-void raa_free(struct RAA *r)
-{
-    if (r->layers) {
-        struct RAA **p;
-        for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
-            if (*p)
-                raa_free(*p);
-    }
-    nasm_free(r);
-}
-
-int64_t raa_read(struct RAA *r, int32_t posn)
-{
-    if ((uint32_t)posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
-        return 0;               /* Return 0 for undefined entries */
-    while (r->layers > 0) {
-       int32_t l = posn >> r->shift;
-       posn &= (UINT32_C(1) << r->shift)-1;
-        r = r->u.b.data[l];
-        if (!r)
-            return 0;           /* Return 0 for undefined entries */
-    }
-    return r->u.l.data[posn];
-}
-
-struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
-{
-    struct RAA *result;
-
-    if (posn < 0)
-        nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
-
-    while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) {
-        /*
-         * Must add a layer.
-         */
-        struct RAA *s;
-        int i;
-
-        s = nasm_malloc(BRANCHSIZ);
-        for (i = 0; i < RAA_LAYERSIZE; i++)
-            s->u.b.data[i] = NULL;
-        s->layers = r->layers + 1;
-        s->shift = LAYERSHIFT(r) + r->shift;
-        s->u.b.data[0] = r;
-        r = s;
-    }
-
-    result = r;
-
-    while (r->layers > 0) {
-        struct RAA **s;
-       int32_t l = posn >> r->shift;
-       posn &= (UINT32_C(1) << r->shift)-1;
-        s = &r->u.b.data[l];
-        if (!*s)
-            *s = real_raa_init(r->layers - 1);
-        r = *s;
-    }
-
-    r->u.l.data[posn] = value;
-
-    return result;
-}
-
-/* Aggregate SAA components smaller than this */
-#define SAA_BLKLEN 65536
-
-struct SAA *saa_init(size_t elem_len)
-{
-    struct SAA *s;
-    char *data;
-
-    s = nasm_zalloc(sizeof(struct SAA));
-
-    if (elem_len >= SAA_BLKLEN)
-       s->blk_len = elem_len;
-    else
-       s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
-
-    s->elem_len = elem_len;
-    s->length = s->blk_len;
-    data = nasm_malloc(s->blk_len);
-    s->nblkptrs = s->nblks = 1;
-    s->blk_ptrs = nasm_malloc(sizeof(char *));
-    s->blk_ptrs[0] = data;
-    s->wblk = s->rblk = &s->blk_ptrs[0];
-
-    return s;
-}
-
-void saa_free(struct SAA *s)
-{
-    char **p;
-    size_t n;
-
-    for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
-       nasm_free(*p);
-
-    nasm_free(s->blk_ptrs);
-    nasm_free(s);
-}
-
-/* Add one allocation block to an SAA */
-static void saa_extend(struct SAA *s)
-{
-    size_t blkn = s->nblks++;
-
-    if (blkn >= s->nblkptrs) {
-       size_t rindex = s->rblk - s->blk_ptrs;
-       size_t windex = s->wblk - s->blk_ptrs;
-
-       s->nblkptrs <<= 1;
-       s->blk_ptrs = nasm_realloc(s->blk_ptrs, s->nblkptrs*sizeof(char *));
-
-       s->rblk = s->blk_ptrs + rindex;
-       s->wblk = s->blk_ptrs + windex;
-    }
-
-    s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
-    s->length += s->blk_len;
-}
-
-void *saa_wstruct(struct SAA *s)
-{
-    void *p;
-
-    if (s->wpos % s->elem_len)
-           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
-                             "misaligned wpos in saa_wstruct");
-
-    if (s->wpos + s->elem_len > s->blk_len) {
-       if (s->wpos != s->blk_len)
-           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
-                             "unfilled block in saa_wstruct");
-
-       if (s->wptr + s->elem_len > s->length)
-           saa_extend(s);
-       s->wblk++;
-       s->wpos = 0;
-    }
-
-    p = *s->wblk + s->wpos;
-    s->wpos += s->elem_len;
-    s->wptr += s->elem_len;
-
-    if (s->wptr > s->datalen)
-       s->datalen = s->wptr;
-
-    return p;
-}
-
-void saa_wbytes(struct SAA *s, const void *data, size_t len)
-{
-    const char *d = data;
-
-    while (len) {
-        size_t l = s->blk_len - s->wpos;
-        if (l > len)
-            l = len;
-        if (l) {
-            if (d) {
-                memcpy(*s->wblk + s->wpos, d, l);
-                d += l;
-            } else
-                memset(*s->wblk + s->wpos, 0, l);
-            s->wpos += l;
-           s->wptr += l;
-            len -= l;
-
-           if (s->datalen < s->wptr)
-               s->datalen = s->wptr;
-        }
-        if (len) {
-           if (s->wptr >= s->length)
-               saa_extend(s);
-           s->wblk++;
-           s->wpos = 0;
-       }
-    }
-}
-
-/* write unsigned LEB128 value to SAA */
-void saa_wleb128u(struct SAA *psaa, int value)
-{
-  char temp[64], *ptemp;
-  uint8_t byte;
-  int len;
-
-  ptemp = temp;
-  len = 0;
-  do
-  {
-     byte = value & 127;
-     value >>= 7;
-     if (value != 0) /* more bytes to come */
-        byte |= 0x80;
-     *ptemp = byte;
-     ptemp++;
-     len++;
-  } while (value != 0);
-  saa_wbytes(psaa, temp, len);
-}
-
-/* write signed LEB128 value to SAA */
-void saa_wleb128s(struct SAA *psaa, int value)
-{
-  char temp[64], *ptemp;
-  uint8_t byte;
-  bool more, negative;
-  int size, len;
-
-  ptemp = temp;
-  more = 1;
-  negative = (value < 0);
-  size = sizeof(int) * 8;
-  len = 0;
-  while(more)
-  {
-    byte = value & 0x7f;
-    value >>= 7;
-    if (negative)
-     /* sign extend */
-     value |= - (1 <<(size - 7));
-    /* sign bit of byte is second high order bit (0x40) */
-    if ((value == 0 && ! (byte & 0x40)) ||
-       ((value == -1) && (byte & 0x40)))
-       more = 0;
-    else
-      byte |= 0x80;
-    *ptemp = byte;
-    ptemp++;
-    len++;
-  }
-  saa_wbytes(psaa, temp, len);
-}
-
-void saa_rewind(struct SAA *s)
-{
-    s->rblk = s->blk_ptrs;
-    s->rpos = s->rptr = 0;
-}
-
-void *saa_rstruct(struct SAA *s)
-{
-    void *p;
-
-    if (s->rptr + s->elem_len > s->datalen)
-       return NULL;
-
-    if (s->rpos % s->elem_len)
-           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
-                             "misaligned rpos in saa_rstruct");
-
-    if (s->rpos + s->elem_len > s->blk_len) {
-       s->rblk++;
-       s->rpos = 0;
-    }
-
-    p = *s->rblk + s->rpos;
-    s->rpos += s->elem_len;
-    s->rptr += s->elem_len;
-
-    return p;
-}
-
-const void *saa_rbytes(struct SAA *s, size_t *lenp)
-{
-    const void *p;
-    size_t len;
-
-    if (s->rptr >= s->datalen) {
-       *lenp = 0;
-       return NULL;
-    }
-
-    if (s->rpos >= s->blk_len) {
-       s->rblk++;
-       s->rpos = 0;
-    }
-
-    len = *lenp;
-    if (len > s->datalen - s->rptr)
-       len = s->datalen - s->rptr;
-    if (len > s->blk_len - s->rpos)
-       len = s->blk_len - s->rpos;
-
-    *lenp = len;
-    p = *s->rblk + s->rpos;
-
-    s->rpos += len;
-    s->rptr += len;
-
-    return p;
-}
-
-void saa_rnbytes(struct SAA *s, void *data, size_t len)
-{
-    char *d = data;
-
-    if (s->rptr + len > s->datalen) {
-       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_rnbytes");
-       return;
-    }
-
-    while (len) {
-        size_t l;
-       const void *p;
-
-       l = len;
-       p = saa_rbytes(s, &l);
-
-       memcpy(d, p, l);
-       d   += l;
-       len -= l;
-    }
-}
-
-/* Same as saa_rnbytes, except position the counter first */
-void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
-{
-    size_t ix;
-
-    if (posn+len > s->datalen) {
-       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fread");
-       return;
-    }
-
-    ix = posn / s->blk_len;
-    s->rptr = posn;
-    s->rpos = posn % s->blk_len;
-    s->rblk = &s->blk_ptrs[ix];
-
-    saa_rnbytes(s, data, len);
-}
-
-/* Same as saa_wbytes, except position the counter first */
-void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
-{
-    size_t ix;
-
-    if (posn > s->datalen) {
-       /* Seek beyond the end of the existing array not supported */
-       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fwrite");
-       return;
-    }
-
-    ix = posn / s->blk_len;
-    s->wptr = posn;
-    s->wpos = posn % s->blk_len;
-    s->wblk = &s->blk_ptrs[ix];
-
-    if (!s->wpos) {
-       s->wpos = s->blk_len;
-       s->wblk--;
-    }
-
-    saa_wbytes(s, data, len);
-}
-
-void saa_fpwrite(struct SAA *s, FILE * fp)
-{
-    const char *data;
-    size_t len;
-
-    saa_rewind(s);
-    while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
-        fwrite(data, 1, len, fp);
-}
-
 /*
  * Common list of prefix names
  */
index 7eb5c47..7391564 100644 (file)
--- a/nasmlib.h
+++ b/nasmlib.h
@@ -37,6 +37,7 @@
  * An error reporting function should look like this.
  */
 typedef void (*efunc) (int severity, const char *fmt, ...);
+extern efunc nasm_malloc_error;
 
 /*
  * These are the error severity codes which get passed as the first
@@ -53,6 +54,7 @@ typedef void (*efunc) (int severity, const char *fmt, ...);
 #define ERR_NOFILE     0x00000010      /* don't give source file name/line */
 #define ERR_USAGE      0x00000020      /* print a usage message */
 #define ERR_PASS1      0x00000040      /* only print this error on pass one */
+#define ERR_NO_SEVERITY 0x00000080     /* suppress printing severity */
 
 /*
  * These codes define specific types of suppressible warning.
@@ -173,6 +175,14 @@ void standard_extension(char *inname, char *outname, char *extension,
 
 #define elements(x)     ( sizeof(x) / sizeof(*(x)) )
 
+/*
+ * tolower table -- avoids a function call on some platforms.
+ * NOTE: unlike the tolower() function in ctype, EOF is *NOT*
+ * a permitted value, for obvious reasons.
+ */
+void tolower_init(void);
+extern unsigned char nasm_tolower_tab[256];
+#define nasm_tolower(x) nasm_tolower_tab[(unsigned char)(x)]
 
 /*
  * some handy macros that will probably be of use in more than one
@@ -280,103 +290,6 @@ void fwriteint64_t(uint64_t data, FILE * fp);
 void fwriteaddr(uint64_t data, int size, FILE * fp);
 
 /*
- * Routines to manage a dynamic random access array of int64_ts which
- * may grow in size to be more than the largest single malloc'able
- * chunk.
- */
-
-#define RAA_BLKSHIFT   15      /* 2**this many longs allocated at once */
-#define RAA_BLKSIZE    (1 << RAA_BLKSHIFT)
-#define RAA_LAYERSHIFT 15      /* 2**this many _pointers_ allocated */
-#define RAA_LAYERSIZE  (1 << RAA_LAYERSHIFT)
-
-typedef struct RAA RAA;
-typedef union RAA_UNION RAA_UNION;
-typedef struct RAA_LEAF RAA_LEAF;
-typedef struct RAA_BRANCH RAA_BRANCH;
-
-struct RAA {
-    /*
-     * Number of layers below this one to get to the real data. 0
-     * means this structure is a leaf, holding RAA_BLKSIZE real
-     * data items; 1 and above mean it's a branch, holding
-     * RAA_LAYERSIZE pointers to the next level branch or leaf
-     * structures.
-     */
-    int layers;
-
-    /*
-     * Number of real data items spanned by one position in the
-     * `data' array at this level. This number is 0 trivially, for
-     * a leaf (level 0): for a level 1 branch it should be
-     * RAA_BLKSHIFT, and for a level 2 branch it's
-     * RAA_LAYERSHIFT+RAA_BLKSHIFT.
-     */
-    int shift;
-
-    union RAA_UNION {
-        struct RAA_LEAF {
-            int64_t data[RAA_BLKSIZE];
-        } l;
-        struct RAA_BRANCH {
-            struct RAA *data[RAA_LAYERSIZE];
-        } b;
-    } u;
-};
-
-struct RAA *raa_init(void);
-void raa_free(struct RAA *);
-int64_t raa_read(struct RAA *, int32_t);
-struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value);
-
-/*
- * Routines to manage a dynamic sequential-access array, under the
- * same restriction on maximum mallocable block. This array may be
- * written to in two ways: a contiguous chunk can be reserved of a
- * given size with a pointer returned OR single-byte data may be
- * written. The array can also be read back in the same two ways:
- * as a series of big byte-data blocks or as a list of structures
- * of a given size.
- */
-
-struct SAA {
-    /*
-     * members `end' and `elem_len' are only valid in first link in
-     * list; `rptr' and `rpos' are used for reading
-     */
-    size_t elem_len;           /* Size of each element */
-    size_t blk_len;            /* Size of each allocation block */
-    size_t nblks;              /* Total number of allocated blocks */
-    size_t nblkptrs;           /* Total number of allocation block pointers */
-    size_t length;             /* Total allocated length of the array */
-    size_t datalen;            /* Total data length of the array */
-    char **wblk;               /* Write block pointer */
-    size_t wpos;               /* Write position inside block */
-    size_t wptr;               /* Absolute write position */
-    char **rblk;               /* Read block pointer */
-    size_t rpos;               /* Read position inside block */
-    size_t rptr;               /* Absolute read position */
-    char **blk_ptrs;           /* Pointer to pointer blocks */
-};
-
-struct SAA *saa_init(size_t elem_len);    /* 1 == byte */
-void saa_free(struct SAA *);
-void *saa_wstruct(struct SAA *);        /* return a structure of elem_len */
-void saa_wbytes(struct SAA *, const void *, size_t);      /* write arbitrary bytes */
-void saa_wleb128u(struct SAA *, int); /* write unsigned LEB128 value */
-void saa_wleb128s(struct SAA *, int); /* write signed LEB128 value */
-void saa_rewind(struct SAA *);  /* for reading from beginning */
-void *saa_rstruct(struct SAA *);        /* return NULL on EOA */
-const void *saa_rbytes(struct SAA *, size_t *); /* return 0 on EOA */
-void saa_rnbytes(struct SAA *, void *, size_t);   /* read a given no. of bytes */
-/* random access */
-void saa_fread(struct SAA *, size_t, void *, size_t);
-void saa_fwrite(struct SAA *, size_t, const void *, size_t);
-
-/* dump to file */
-void saa_fpwrite(struct SAA *, FILE *);
-
-/*
  * Binary search routine. Returns index into `array' of an entry
  * matching `string', or <0 if no match. `array' is taken to
  * contain `size' elements.
index 8f912f8..b5001bd 100644 (file)
--- a/ndisasm.c
+++ b/ndisasm.c
@@ -67,6 +67,7 @@ int main(int argc, char **argv)
     int32_t offset;
     FILE *fp;
 
+    tolower_init();
     nasm_set_malloc_error(ndisasm_error);
 
     offset = 0;
@@ -77,7 +78,7 @@ int main(int argc, char **argv)
         if (*p == '-' && p[1]) {
             p++;
             while (*p)
-                switch (tolower(*p)) {
+                switch (nasm_tolower(*p)) {
                 case 'a':      /* auto or intelligent sync */
                 case 'i':
                     autosync = true;
index 0cfa3d4..20658ac 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "stdscan.h"
 #include "outform.h"
 
index 84acc53..9eb6847 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "outform.h"
 
 #ifdef OF_AS86
index 66a0b0b..d2b5742 100644 (file)
@@ -54,6 +54,7 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
 #include "stdscan.h"
 #include "labels.h"
 #include "eval.h"
index 4655e21..bbd0b57 100644 (file)
@@ -18,6 +18,8 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "outform.h"
 
 #if defined(OF_COFF) || defined(OF_WIN32) || defined(OF_WIN64)
index 63762b1..ec4e838 100644 (file)
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "stdscan.h"
 #include "outform.h"
-#include "wsaa.h"
 
 #ifdef OF_ELF32
 
@@ -255,7 +256,6 @@ static int8_t line_base = -5, line_range = 14, opcode_base = 13;
 static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
            abbrevlen, linelen, linerellen, framelen, loclen;
 static int32_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
-static char workbuf[1024];
 
 static struct dfmt df_dwarf;
 static struct dfmt df_stabs;
@@ -307,7 +307,7 @@ static void elf_init(FILE * fp, efunc errfunc, ldfunc ldef, evalfunc eval)
     bsym = raa_init();
     strs = saa_init(1L);
     saa_wbytes(strs, "\0", 1L);
-    saa_wbytes(strs, elf_module, (int32_t)(strlen(elf_module) + 1));
+    saa_wbytes(strs, elf_module, strlen(elf_module)+1);
     strslen = 2 + strlen(elf_module);
     shstrtab = NULL;
     shstrtablen = shstrtabsize = 0;;
@@ -1497,7 +1497,7 @@ static int elf_set_info(enum geninfo type, char **val)
     return 0;
 }
 static struct dfmt df_dwarf = {
-    "elf32 (X86_64) dwarf debug format for Linux",
+    "ELF32 (i386) dwarf debug format for Linux",
     "dwarf",
     debug32_init,
     dwarf32_linenum,
@@ -1896,8 +1896,8 @@ void dwarf32_output(int type, void *param)
     /* check for file change */
     if (!(inx == dwarf_csect->file))
     {
-       WSAACHAR(plinep,workbuf,DW_LNS_set_file);
-       WSAACHAR(plinep,workbuf,inx);
+       saa_write8(plinep,DW_LNS_set_file);
+       saa_write8(plinep,inx);
        dwarf_csect->file = inx;
     }
     /* check for line change */
@@ -1908,18 +1908,18 @@ void dwarf32_output(int type, void *param)
        soc = (ln - line_base) + (line_range * aa) + opcode_base;
        if (ln >= line_base && ln < maxln && soc < 256)
        {
-          WSAACHAR(plinep,workbuf,soc);
+          saa_write8(plinep,soc);
        }
        else
        {
           if (ln)
           {
-          WSAACHAR(plinep,workbuf,DW_LNS_advance_line);
+          saa_write8(plinep,DW_LNS_advance_line);
           saa_wleb128s(plinep,ln);
           }
           if (aa)
           {
-          WSAACHAR(plinep,workbuf,DW_LNS_advance_pc);
+          saa_write8(plinep,DW_LNS_advance_pc);
           saa_wleb128u(plinep,aa);
           }
        }
@@ -1934,6 +1934,7 @@ void dwarf32_output(int type, void *param)
 
 void dwarf32_generate(void)
 {
+    static const char nasm_signature[] = "NASM " NASM_VER;
     uint8_t *pbuf;
     int indx;
     struct linelist *ftentry;
@@ -1946,14 +1947,14 @@ void dwarf32_generate(void)
     /* and build aranges section */
     paranges = saa_init(1L);
     parangesrel = saa_init(1L);
-    WSAASHORT(paranges,workbuf,2);             /* dwarf version */
-    WSAALONG(parangesrel,workbuf, paranges->datalen+4);
-    WSAALONG(parangesrel,workbuf, (dwarf_infosym << 8) +  R_386_32); /* reloc to info */
-    WSAALONG(parangesrel,workbuf, (uint32_t) 0);
-    WSAALONG(paranges,workbuf,0);              /* offset into info */
-    WSAACHAR(paranges,workbuf,4);              /* pointer size */
-    WSAACHAR(paranges,workbuf,0);              /* not segmented */
-    WSAALONG(paranges,workbuf,0);              /* padding */
+    saa_write16(paranges,2);           /* dwarf version */
+    saa_write32(parangesrel, paranges->datalen+4);
+    saa_write32(parangesrel, (dwarf_infosym << 8) +  R_386_32); /* reloc to info */
+    saa_write32(parangesrel, 0);
+    saa_write32(paranges,0);           /* offset into info */
+    saa_write8(paranges,4);            /* pointer size */
+    saa_write8(paranges,0);            /* not segmented */
+    saa_write32(paranges,0);           /* padding */
     /* iterate though sectlist entries */
      psect = dwarf_fsect;
      totlen = 0;
@@ -1962,25 +1963,25 @@ void dwarf32_generate(void)
      {
          plinep = psect->psaa;
          /* Line Number Program Epilogue */
-         WSAACHAR(plinep,workbuf,2);                   /* std op 2 */
-         WSAACHAR(plinep,workbuf,(sects[psect->section]->len)-psect->offset);
-         WSAACHAR(plinep,workbuf,DW_LNS_extended_op);
-         WSAACHAR(plinep,workbuf,1);                   /* operand length */
-         WSAACHAR(plinep,workbuf,DW_LNE_end_sequence);
+         saa_write8(plinep,2);                 /* std op 2 */
+         saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
+         saa_write8(plinep,DW_LNS_extended_op);
+         saa_write8(plinep,1);                 /* operand length */
+         saa_write8(plinep,DW_LNE_end_sequence);
          totlen += plinep->datalen;
          /* range table relocation entry */
-         WSAALONG(parangesrel,workbuf, paranges->datalen + 4);
-         WSAALONG(parangesrel,workbuf, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
-         WSAALONG(parangesrel,workbuf, (uint32_t) 0);
+         saa_write32(parangesrel, paranges->datalen + 4);
+         saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
+         saa_write32(parangesrel, (uint32_t) 0);
          /* range table entry */
-         WSAALONG(paranges,workbuf,0x0000);            /* range start */
-         WSAALONG(paranges,workbuf,sects[psect->section]->len);        /* range length */
+         saa_write32(paranges,0x0000);         /* range start */
+         saa_write32(paranges,sects[psect->section]->len);     /* range length */
          highaddr += sects[psect->section]->len;
          /* done with this entry */
          psect = psect->next;
      }
-    WSAALONG(paranges,workbuf,0);              /* null address */
-    WSAALONG(paranges,workbuf,0);              /* null length */
+    saa_write32(paranges,0);           /* null address */
+    saa_write32(paranges,0);           /* null length */
     saalen = paranges->datalen;
     arangeslen = saalen + 4;
     arangesbuf = pbuf = nasm_malloc(arangeslen);
@@ -1996,10 +1997,10 @@ void dwarf32_generate(void)
 
     /* build pubnames section */
     ppubnames = saa_init(1L);
-    WSAASHORT(ppubnames,workbuf,3);                    /* dwarf version */
-    WSAALONG(ppubnames,workbuf,0);                     /* offset into info */
-    WSAALONG(ppubnames,workbuf,0);                     /* space used in info */
-    WSAALONG(ppubnames,workbuf,0);                     /* end of list */
+    saa_write16(ppubnames,3);                  /* dwarf version */
+    saa_write32(ppubnames,0);                  /* offset into info */
+    saa_write32(ppubnames,0);                  /* space used in info */
+    saa_write32(ppubnames,0);                  /* end of list */
     saalen = ppubnames->datalen;
     pubnameslen = saalen + 4;
     pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
@@ -2010,37 +2011,35 @@ void dwarf32_generate(void)
     /* build info section */
     pinfo = saa_init(1L);
     pinforel = saa_init(1L);
-    WSAASHORT(pinfo,workbuf,2);                        /* dwarf version */
-    WSAALONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAALONG(pinforel,workbuf, (dwarf_abbrevsym << 8) +  R_386_32); /* reloc to abbrev */
-    WSAALONG(pinforel,workbuf, (uint32_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* offset into abbrev */
-    WSAACHAR(pinfo,workbuf,4);                 /* pointer size */
-    WSAACHAR(pinfo,workbuf,1);                 /* abbrviation number LEB128u */
-    WSAALONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAALONG(pinforel,workbuf, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
-    WSAALONG(pinforel,workbuf, (uint32_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* DW_AT_low_pc */
-    WSAALONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAALONG(pinforel,workbuf, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
-    WSAALONG(pinforel,workbuf, (uint32_t) 0);
-    WSAALONG(pinfo,workbuf,highaddr);          /* DW_AT_high_pc */
-    WSAALONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAALONG(pinforel,workbuf, (dwarf_linesym << 8) +  R_386_32); /* reloc to line */
-    WSAALONG(pinforel,workbuf, (uint32_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* DW_AT_stmt_list */
-    strcpy(workbuf,elf_module);                /* input file name */
-    saa_wbytes(pinfo, workbuf, (int32_t)(strlen(elf_module) + 1));
-    sprintf(workbuf, "NASM %s", NASM_VER);
-    saa_wbytes(pinfo, workbuf, (int32_t)(strlen(workbuf) + 1));
-    WSAASHORT(pinfo,workbuf,DW_LANG_Mips_Assembler);
-    WSAACHAR(pinfo,workbuf,2);                 /* abbrviation number LEB128u */
-    WSAALONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAALONG(pinforel,workbuf, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
-    WSAALONG(pinforel,workbuf, (uint32_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* DW_AT_low_pc */
-    WSAALONG(pinfo,workbuf,0);                 /* DW_AT_frame_base */
-    WSAACHAR(pinfo,workbuf,0);                 /* end of entries */
+    saa_write16(pinfo,2);                      /* dwarf version */
+    saa_write32(pinforel, pinfo->datalen + 4);
+    saa_write32(pinforel, (dwarf_abbrevsym << 8) +  R_386_32); /* reloc to abbrev */
+    saa_write32(pinforel, 0);
+    saa_write32(pinfo,0);                      /* offset into abbrev */
+    saa_write8(pinfo,4);                       /* pointer size */
+    saa_write8(pinfo,1);                       /* abbrviation number LEB128u */
+    saa_write32(pinforel, pinfo->datalen + 4);
+    saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
+    saa_write32(pinforel, 0);
+    saa_write32(pinfo,0);                      /* DW_AT_low_pc */
+    saa_write32(pinforel, pinfo->datalen + 4);
+    saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
+    saa_write32(pinforel, 0);
+    saa_write32(pinfo,highaddr);               /* DW_AT_high_pc */
+    saa_write32(pinforel, pinfo->datalen + 4);
+    saa_write32(pinforel, (dwarf_linesym << 8) +  R_386_32); /* reloc to line */
+    saa_write32(pinforel, 0);
+    saa_write32(pinfo,0);                      /* DW_AT_stmt_list */
+    saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
+    saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
+    saa_write16(pinfo,DW_LANG_Mips_Assembler);
+    saa_write8(pinfo,2);                       /* abbrviation number LEB128u */
+    saa_write32(pinforel, pinfo->datalen + 4);
+    saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) +  R_386_32);
+    saa_write32(pinforel, 0);
+    saa_write32(pinfo,0);                      /* DW_AT_low_pc */
+    saa_write32(pinfo,0);                      /* DW_AT_frame_base */
+    saa_write8(pinfo,0);                       /* end of entries */
     saalen = pinfo->datalen;
     infolen = saalen + 4;
     infobuf = pbuf = nasm_malloc(infolen);
@@ -2056,32 +2055,32 @@ void dwarf32_generate(void)
 
     /* build abbrev section */
     pabbrev = saa_init(1L);
-    WSAACHAR(pabbrev,workbuf,1);                       /* entry number LEB128u */
-    WSAACHAR(pabbrev,workbuf,DW_TAG_compile_unit);     /* tag LEB128u */
-    WSAACHAR(pabbrev,workbuf,1);                       /* has children */
+    saa_write8(pabbrev,1);                     /* entry number LEB128u */
+    saa_write8(pabbrev,DW_TAG_compile_unit);   /* tag LEB128u */
+    saa_write8(pabbrev,1);                     /* has children */
     /* the following attributes and forms are all LEB128u values */
-    WSAACHAR(pabbrev,workbuf,DW_AT_low_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_high_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_stmt_list);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data4);
-    WSAACHAR(pabbrev,workbuf,DW_AT_name);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_string);
-    WSAACHAR(pabbrev,workbuf,DW_AT_producer);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_string);
-    WSAACHAR(pabbrev,workbuf,DW_AT_language);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data2);
-    WSAASHORT(pabbrev,workbuf,0);                      /* end of entry */
+    saa_write8(pabbrev,DW_AT_low_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_high_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_stmt_list);
+    saa_write8(pabbrev,DW_FORM_data4);
+    saa_write8(pabbrev,DW_AT_name);
+    saa_write8(pabbrev,DW_FORM_string);
+    saa_write8(pabbrev,DW_AT_producer);
+    saa_write8(pabbrev,DW_FORM_string);
+    saa_write8(pabbrev,DW_AT_language);
+    saa_write8(pabbrev,DW_FORM_data2);
+    saa_write16(pabbrev,0);                    /* end of entry */
     /* LEB128u usage same as above */
-    WSAACHAR(pabbrev,workbuf,2);                       /* entry number */
-    WSAACHAR(pabbrev,workbuf,DW_TAG_subprogram);
-    WSAACHAR(pabbrev,workbuf,0);                       /* no children */
-    WSAACHAR(pabbrev,workbuf,DW_AT_low_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_frame_base);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data4);
-    WSAASHORT(pabbrev,workbuf,0);                      /* end of entry */
+    saa_write8(pabbrev,2);                     /* entry number */
+    saa_write8(pabbrev,DW_TAG_subprogram);
+    saa_write8(pabbrev,0);                     /* no children */
+    saa_write8(pabbrev,DW_AT_low_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_frame_base);
+    saa_write8(pabbrev,DW_FORM_data4);
+    saa_write16(pabbrev,0);                    /* end of entry */
     abbrevlen = saalen = pabbrev->datalen;
     abbrevbuf = pbuf = nasm_malloc(saalen);
     saa_rnbytes(pabbrev, pbuf, saalen);
@@ -2090,37 +2089,37 @@ void dwarf32_generate(void)
     /* build line section */
     /* prolog */
     plines = saa_init(1L);
-    WSAACHAR(plines,workbuf,1);                        /* Minimum Instruction Length */
-    WSAACHAR(plines,workbuf,1);                        /* Initial value of 'is_stmt' */
-    WSAACHAR(plines,workbuf,line_base);                /* Line Base */
-    WSAACHAR(plines,workbuf,line_range);       /* Line Range */
-    WSAACHAR(plines,workbuf,opcode_base);      /* Opcode Base */
+    saa_write8(plines,1);                      /* Minimum Instruction Length */
+    saa_write8(plines,1);                      /* Initial value of 'is_stmt' */
+    saa_write8(plines,line_base);              /* Line Base */
+    saa_write8(plines,line_range);     /* Line Range */
+    saa_write8(plines,opcode_base);    /* Opcode Base */
     /* standard opcode lengths (# of LEB128u operands) */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 1 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 2 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 3 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 4 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 5 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 6 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 7 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 8 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 9 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 10 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 11 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 12 length */
+    saa_write8(plines,0);                      /* Std opcode 1 length */
+    saa_write8(plines,1);                      /* Std opcode 2 length */
+    saa_write8(plines,1);                      /* Std opcode 3 length */
+    saa_write8(plines,1);                      /* Std opcode 4 length */
+    saa_write8(plines,1);                      /* Std opcode 5 length */
+    saa_write8(plines,0);                      /* Std opcode 6 length */
+    saa_write8(plines,0);                      /* Std opcode 7 length */
+    saa_write8(plines,0);                      /* Std opcode 8 length */
+    saa_write8(plines,1);                      /* Std opcode 9 length */
+    saa_write8(plines,0);                      /* Std opcode 10 length */
+    saa_write8(plines,0);                      /* Std opcode 11 length */
+    saa_write8(plines,1);                      /* Std opcode 12 length */
     /* Directory Table */ 
-    WSAACHAR(plines,workbuf,0);                        /* End of table */
+    saa_write8(plines,0);                      /* End of table */
     /* File Name Table */
     ftentry = dwarf_flist;
     for (indx = 0;indx<dwarf_numfiles;indx++)
     {
       saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
-      WSAACHAR(plines,workbuf,0);                      /* directory  LEB128u */
-      WSAACHAR(plines,workbuf,0);                      /* time LEB128u */
-      WSAACHAR(plines,workbuf,0);                      /* size LEB128u */
+      saa_write8(plines,0);                    /* directory  LEB128u */
+      saa_write8(plines,0);                    /* time LEB128u */
+      saa_write8(plines,0);                    /* size LEB128u */
       ftentry = ftentry->next;
     }
-    WSAACHAR(plines,workbuf,0);                        /* End of table */
+    saa_write8(plines,0);                      /* End of table */
     linepoff = plines->datalen;
     linelen = linepoff + totlen + 10;
     linebuf = pbuf = nasm_malloc(linelen);
@@ -2138,9 +2137,9 @@ void dwarf32_generate(void)
     psect = dwarf_fsect;
     for (indx = 0; indx < dwarf_nsections; indx++)
     {
-         WSAALONG(plinesrel,workbuf, linepoff);
-         WSAALONG(plinesrel,workbuf, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
-         WSAALONG(plinesrel,workbuf, (uint32_t) 0);
+         saa_write32(plinesrel, linepoff);
+         saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) +  R_386_32);
+         saa_write32(plinesrel, (uint32_t) 0);
          plinep = psect->psaa;
          saalen = plinep->datalen;
          saa_rnbytes(plinep, pbuf, saalen);
@@ -2275,10 +2274,10 @@ void dwarf32_findsect(const int index)
      dwarf_csect->section = index;
      dwarf_csect->next = 0;
      /* set relocatable address at start of line program */
-     WSAACHAR(plinep,workbuf,DW_LNS_extended_op);
-     WSAACHAR(plinep,workbuf,5);                       /* operand length */
-     WSAACHAR(plinep,workbuf,DW_LNE_set_address);
-     WSAALONG(plinep,workbuf,0);               /* Start Address */
+     saa_write8(plinep,DW_LNS_extended_op);
+     saa_write8(plinep,5);                     /* operand length */
+     saa_write8(plinep,DW_LNE_set_address);
+     saa_write32(plinep,0);            /* Start Address */
      /* if first entry */
      if (!dwarf_fsect)
      {
index 3811a03..9393e7a 100644 (file)
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "stdscan.h"
 #include "outform.h"
-#include "wsaa.h"
 
 /* Definitions in lieu of elf.h */
 #define SHT_NULL 0                     /* Inactive section header */
@@ -267,7 +268,6 @@ static int8_t line_base = -5, line_range = 14, opcode_base = 13;
 static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
            abbrevlen, linelen, linerellen, framelen, loclen;
 static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
-static char workbuf[1024];
 
 
 static struct dfmt df_dwarf;
@@ -1915,8 +1915,8 @@ void dwarf64_output(int type, void *param)
     /* check for file change */
     if (!(inx == dwarf_csect->file))
     {
-       WSAACHAR(plinep,workbuf,DW_LNS_set_file);
-       WSAACHAR(plinep,workbuf,inx);
+       saa_write8(plinep,DW_LNS_set_file);
+       saa_write8(plinep,inx);
        dwarf_csect->file = inx;
     }
     /* check for line change */
@@ -1927,18 +1927,18 @@ void dwarf64_output(int type, void *param)
        soc = (ln - line_base) + (line_range * aa) + opcode_base;
        if (ln >= line_base && ln < maxln && soc < 256)
        {
-          WSAACHAR(plinep,workbuf,soc);
+          saa_write8(plinep,soc);
        }
        else
        {
           if (ln)
           {
-          WSAACHAR(plinep,workbuf,DW_LNS_advance_line);
+          saa_write8(plinep,DW_LNS_advance_line);
           saa_wleb128s(plinep,ln);
           }
           if (aa)
           {
-          WSAACHAR(plinep,workbuf,DW_LNS_advance_pc);
+          saa_write8(plinep,DW_LNS_advance_pc);
           saa_wleb128u(plinep,aa);
           }
        }
@@ -1953,6 +1953,7 @@ void dwarf64_output(int type, void *param)
 
 void dwarf64_generate(void)
 {
+    static const char nasm_signature[] = "NASM " NASM_VER;
     uint8_t *pbuf;
     int indx;
     struct linelist *ftentry;
@@ -1965,14 +1966,14 @@ void dwarf64_generate(void)
     /* and build aranges section */
     paranges = saa_init(1L);
     parangesrel = saa_init(1L);
-    WSAASHORT(paranges,workbuf,3);             /* dwarf version */
-    WSAADLONG(parangesrel,workbuf, paranges->datalen+4);
-    WSAADLONG(parangesrel,workbuf, (dwarf_infosym << 32) +  R_X86_64_32); /* reloc to info */
-    WSAADLONG(parangesrel,workbuf, (uint64_t) 0);
-    WSAALONG(paranges,workbuf,0);              /* offset into info */
-    WSAACHAR(paranges,workbuf,8);              /* pointer size */
-    WSAACHAR(paranges,workbuf,0);              /* not segmented */
-    WSAALONG(paranges,workbuf,0);              /* padding */
+    saa_write16(paranges,3);           /* dwarf version */
+    saa_write64(parangesrel, paranges->datalen+4);
+    saa_write64(parangesrel, (dwarf_infosym << 32) +  R_X86_64_32); /* reloc to info */
+    saa_write64(parangesrel, 0);
+    saa_write32(paranges,0);           /* offset into info */
+    saa_write8(paranges,8);            /* pointer size */
+    saa_write8(paranges,0);            /* not segmented */
+    saa_write32(paranges,0);           /* padding */
     /* iterate though sectlist entries */
      psect = dwarf_fsect;
      totlen = 0;
@@ -1981,25 +1982,25 @@ void dwarf64_generate(void)
      {
          plinep = psect->psaa;
          /* Line Number Program Epilogue */
-         WSAACHAR(plinep,workbuf,2);                   /* std op 2 */
-         WSAACHAR(plinep,workbuf,(sects[psect->section]->len)-psect->offset);
-         WSAACHAR(plinep,workbuf,DW_LNS_extended_op);
-         WSAACHAR(plinep,workbuf,1);                   /* operand length */
-         WSAACHAR(plinep,workbuf,DW_LNE_end_sequence);
+         saa_write8(plinep,2);                 /* std op 2 */
+         saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
+         saa_write8(plinep,DW_LNS_extended_op);
+         saa_write8(plinep,1);                 /* operand length */
+         saa_write8(plinep,DW_LNE_end_sequence);
          totlen += plinep->datalen;
          /* range table relocation entry */
-         WSAADLONG(parangesrel,workbuf, paranges->datalen + 4);
-         WSAADLONG(parangesrel,workbuf, ((uint64_t) (psect->section + 2) << 32) +  R_X86_64_64);
-         WSAADLONG(parangesrel,workbuf, (uint64_t) 0);
+         saa_write64(parangesrel, paranges->datalen + 4);
+         saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) +  R_X86_64_64);
+         saa_write64(parangesrel, (uint64_t) 0);
          /* range table entry */
-         WSAADLONG(paranges,workbuf,0x0000);           /* range start */
-         WSAADLONG(paranges,workbuf,sects[psect->section]->len);       /* range length */
+         saa_write64(paranges,0x0000);         /* range start */
+         saa_write64(paranges,sects[psect->section]->len);     /* range length */
          highaddr += sects[psect->section]->len;
          /* done with this entry */
          psect = psect->next;
      }
-    WSAADLONG(paranges,workbuf,0);             /* null address */
-    WSAADLONG(paranges,workbuf,0);             /* null length */
+    saa_write64(paranges,0);           /* null address */
+    saa_write64(paranges,0);           /* null length */
     saalen = paranges->datalen;
     arangeslen = saalen + 4;
     arangesbuf = pbuf = nasm_malloc(arangeslen);
@@ -2015,10 +2016,10 @@ void dwarf64_generate(void)
 
     /* build pubnames section */
     ppubnames = saa_init(1L);
-    WSAASHORT(ppubnames,workbuf,3);                    /* dwarf version */
-    WSAALONG(ppubnames,workbuf,0);                     /* offset into info */
-    WSAALONG(ppubnames,workbuf,0);                     /* space used in info */
-    WSAALONG(ppubnames,workbuf,0);                     /* end of list */
+    saa_write16(ppubnames,3);                  /* dwarf version */
+    saa_write32(ppubnames,0);                  /* offset into info */
+    saa_write32(ppubnames,0);                  /* space used in info */
+    saa_write32(ppubnames,0);                  /* end of list */
     saalen = ppubnames->datalen;
     pubnameslen = saalen + 4;
     pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
@@ -2029,37 +2030,35 @@ void dwarf64_generate(void)
     /* build info section */
     pinfo = saa_init(1L);
     pinforel = saa_init(1L);
-    WSAASHORT(pinfo,workbuf,3);                        /* dwarf version */
-    WSAADLONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAADLONG(pinforel,workbuf, (dwarf_abbrevsym << 32) +  R_X86_64_32); /* reloc to abbrev */
-    WSAADLONG(pinforel,workbuf, (uint64_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* offset into abbrev */
-    WSAACHAR(pinfo,workbuf,8);                 /* pointer size */
-    WSAACHAR(pinfo,workbuf,1);                 /* abbrviation number LEB128u */
-    WSAADLONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAADLONG(pinforel,workbuf, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
-    WSAADLONG(pinforel,workbuf, (uint64_t) 0);
-    WSAADLONG(pinfo,workbuf,0);                        /* DW_AT_low_pc */
-    WSAADLONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAADLONG(pinforel,workbuf, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
-    WSAADLONG(pinforel,workbuf, (uint64_t) 0);
-    WSAADLONG(pinfo,workbuf,highaddr);         /* DW_AT_high_pc */
-    WSAADLONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAADLONG(pinforel,workbuf, (dwarf_linesym << 32) +  R_X86_64_32); /* reloc to line */
-    WSAADLONG(pinforel,workbuf, (uint64_t) 0);
-    WSAALONG(pinfo,workbuf,0);                 /* DW_AT_stmt_list */
-    strcpy(workbuf,elf_module);                /* input file name */
-    saa_wbytes(pinfo, workbuf, (int32_t)(strlen(elf_module) + 1));
-    sprintf(workbuf, "NASM %s", NASM_VER);
-    saa_wbytes(pinfo, workbuf, (int32_t)(strlen(workbuf) + 1));
-    WSAASHORT(pinfo,workbuf,DW_LANG_Mips_Assembler);
-    WSAACHAR(pinfo,workbuf,2);                 /* abbrviation number LEB128u */
-    WSAADLONG(pinforel,workbuf, pinfo->datalen + 4);
-    WSAADLONG(pinforel,workbuf, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
-    WSAADLONG(pinforel,workbuf, (uint64_t) 0);
-    WSAADLONG(pinfo,workbuf,0);                        /* DW_AT_low_pc */
-    WSAADLONG(pinfo,workbuf,0);                        /* DW_AT_frame_base */
-    WSAACHAR(pinfo,workbuf,0);                 /* end of entries */
+    saa_write16(pinfo,3);                      /* dwarf version */
+    saa_write64(pinforel, pinfo->datalen + 4);
+    saa_write64(pinforel, (dwarf_abbrevsym << 32) +  R_X86_64_32); /* reloc to abbrev */
+    saa_write64(pinforel, 0);
+    saa_write32(pinfo,0);                      /* offset into abbrev */
+    saa_write8(pinfo,8);                       /* pointer size */
+    saa_write8(pinfo,1);                       /* abbrviation number LEB128u */
+    saa_write64(pinforel, pinfo->datalen + 4);
+    saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
+    saa_write64(pinforel, 0);
+    saa_write64(pinfo,0);                      /* DW_AT_low_pc */
+    saa_write64(pinforel, pinfo->datalen + 4);
+    saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
+    saa_write64(pinforel, 0);
+    saa_write64(pinfo,highaddr);               /* DW_AT_high_pc */
+    saa_write64(pinforel, pinfo->datalen + 4);
+    saa_write64(pinforel, (dwarf_linesym << 32) +  R_X86_64_32); /* reloc to line */
+    saa_write64(pinforel, 0);
+    saa_write32(pinfo,0);                      /* DW_AT_stmt_list */
+    saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
+    saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
+    saa_write16(pinfo,DW_LANG_Mips_Assembler);
+    saa_write8(pinfo,2);                       /* abbrviation number LEB128u */
+    saa_write64(pinforel, pinfo->datalen + 4);
+    saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) +  R_X86_64_64);
+    saa_write64(pinforel, 0);
+    saa_write64(pinfo,0);                      /* DW_AT_low_pc */
+    saa_write64(pinfo,0);                      /* DW_AT_frame_base */
+    saa_write8(pinfo,0);                       /* end of entries */
     saalen = pinfo->datalen;
     infolen = saalen + 4;
     infobuf = pbuf = nasm_malloc(infolen);
@@ -2075,32 +2074,32 @@ void dwarf64_generate(void)
 
     /* build abbrev section */
     pabbrev = saa_init(1L);
-    WSAACHAR(pabbrev,workbuf,1);                       /* entry number LEB128u */
-    WSAACHAR(pabbrev,workbuf,DW_TAG_compile_unit);     /* tag LEB128u */
-    WSAACHAR(pabbrev,workbuf,1);                       /* has children */
+    saa_write8(pabbrev,1);                     /* entry number LEB128u */
+    saa_write8(pabbrev,DW_TAG_compile_unit);   /* tag LEB128u */
+    saa_write8(pabbrev,1);                     /* has children */
     /* the following attributes and forms are all LEB128u values */
-    WSAACHAR(pabbrev,workbuf,DW_AT_low_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_high_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_stmt_list);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data4);
-    WSAACHAR(pabbrev,workbuf,DW_AT_name);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_string);
-    WSAACHAR(pabbrev,workbuf,DW_AT_producer);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_string);
-    WSAACHAR(pabbrev,workbuf,DW_AT_language);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data2);
-    WSAASHORT(pabbrev,workbuf,0);                      /* end of entry */
+    saa_write8(pabbrev,DW_AT_low_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_high_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_stmt_list);
+    saa_write8(pabbrev,DW_FORM_data4);
+    saa_write8(pabbrev,DW_AT_name);
+    saa_write8(pabbrev,DW_FORM_string);
+    saa_write8(pabbrev,DW_AT_producer);
+    saa_write8(pabbrev,DW_FORM_string);
+    saa_write8(pabbrev,DW_AT_language);
+    saa_write8(pabbrev,DW_FORM_data2);
+    saa_write16(pabbrev,0);                    /* end of entry */
     /* LEB128u usage same as above */
-    WSAACHAR(pabbrev,workbuf,2);                       /* entry number */
-    WSAACHAR(pabbrev,workbuf,DW_TAG_subprogram);
-    WSAACHAR(pabbrev,workbuf,0);                       /* no children */
-    WSAACHAR(pabbrev,workbuf,DW_AT_low_pc);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_addr);
-    WSAACHAR(pabbrev,workbuf,DW_AT_frame_base);
-    WSAACHAR(pabbrev,workbuf,DW_FORM_data4);
-    WSAASHORT(pabbrev,workbuf,0);                      /* end of entry */
+    saa_write8(pabbrev,2);                     /* entry number */
+    saa_write8(pabbrev,DW_TAG_subprogram);
+    saa_write8(pabbrev,0);                     /* no children */
+    saa_write8(pabbrev,DW_AT_low_pc);
+    saa_write8(pabbrev,DW_FORM_addr);
+    saa_write8(pabbrev,DW_AT_frame_base);
+    saa_write8(pabbrev,DW_FORM_data4);
+    saa_write16(pabbrev,0);                    /* end of entry */
     abbrevlen = saalen = pabbrev->datalen;
     abbrevbuf = pbuf = nasm_malloc(saalen);
     saa_rnbytes(pabbrev, pbuf, saalen);
@@ -2109,37 +2108,37 @@ void dwarf64_generate(void)
     /* build line section */
     /* prolog */
     plines = saa_init(1L);
-    WSAACHAR(plines,workbuf,1);                        /* Minimum Instruction Length */
-    WSAACHAR(plines,workbuf,1);                        /* Initial value of 'is_stmt' */
-    WSAACHAR(plines,workbuf,line_base);                /* Line Base */
-    WSAACHAR(plines,workbuf,line_range);       /* Line Range */
-    WSAACHAR(plines,workbuf,opcode_base);      /* Opcode Base */
+    saa_write8(plines,1);                      /* Minimum Instruction Length */
+    saa_write8(plines,1);                      /* Initial value of 'is_stmt' */
+    saa_write8(plines,line_base);              /* Line Base */
+    saa_write8(plines,line_range);     /* Line Range */
+    saa_write8(plines,opcode_base);    /* Opcode Base */
     /* standard opcode lengths (# of LEB128u operands) */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 1 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 2 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 3 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 4 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 5 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 6 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 7 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 8 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 9 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 10 length */
-    WSAACHAR(plines,workbuf,0);                        /* Std opcode 11 length */
-    WSAACHAR(plines,workbuf,1);                        /* Std opcode 12 length */
+    saa_write8(plines,0);                      /* Std opcode 1 length */
+    saa_write8(plines,1);                      /* Std opcode 2 length */
+    saa_write8(plines,1);                      /* Std opcode 3 length */
+    saa_write8(plines,1);                      /* Std opcode 4 length */
+    saa_write8(plines,1);                      /* Std opcode 5 length */
+    saa_write8(plines,0);                      /* Std opcode 6 length */
+    saa_write8(plines,0);                      /* Std opcode 7 length */
+    saa_write8(plines,0);                      /* Std opcode 8 length */
+    saa_write8(plines,1);                      /* Std opcode 9 length */
+    saa_write8(plines,0);                      /* Std opcode 10 length */
+    saa_write8(plines,0);                      /* Std opcode 11 length */
+    saa_write8(plines,1);                      /* Std opcode 12 length */
     /* Directory Table */ 
-    WSAACHAR(plines,workbuf,0);                        /* End of table */
+    saa_write8(plines,0);                      /* End of table */
     /* File Name Table */
     ftentry = dwarf_flist;
     for (indx = 0;indx<dwarf_numfiles;indx++)
     {
       saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
-      WSAACHAR(plines,workbuf,0);                      /* directory  LEB128u */
-      WSAACHAR(plines,workbuf,0);                      /* time LEB128u */
-      WSAACHAR(plines,workbuf,0);                      /* size LEB128u */
+      saa_write8(plines,0);                    /* directory  LEB128u */
+      saa_write8(plines,0);                    /* time LEB128u */
+      saa_write8(plines,0);                    /* size LEB128u */
       ftentry = ftentry->next;
     }
-    WSAACHAR(plines,workbuf,0);                        /* End of table */
+    saa_write8(plines,0);                      /* End of table */
     linepoff = plines->datalen;
     linelen = linepoff + totlen + 10;
     linebuf = pbuf = nasm_malloc(linelen);
@@ -2157,9 +2156,9 @@ void dwarf64_generate(void)
     psect = dwarf_fsect;
     for (indx = 0; indx < dwarf_nsections; indx++)
     {
-         WSAADLONG(plinesrel,workbuf, linepoff);
-         WSAADLONG(plinesrel,workbuf, ((uint64_t) (psect->section + 2) << 32) +  R_X86_64_64);
-         WSAADLONG(plinesrel,workbuf, (uint64_t) 0);
+         saa_write64(plinesrel, linepoff);
+         saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) +  R_X86_64_64);
+         saa_write64(plinesrel, (uint64_t) 0);
          plinep = psect->psaa;
          saalen = plinep->datalen;
          saa_rnbytes(plinep, pbuf, saalen);
@@ -2294,10 +2293,10 @@ void dwarf64_findsect(const int index)
      dwarf_csect->section = index;
      dwarf_csect->next = 0;
      /* set relocatable address at start of line program */
-     WSAACHAR(plinep,workbuf,DW_LNS_extended_op);
-     WSAACHAR(plinep,workbuf,9);                       /* operand length */
-     WSAACHAR(plinep,workbuf,DW_LNE_set_address);
-     WSAADLONG(plinep,workbuf,0);              /* Start Address */
+     saa_write8(plinep,DW_LNS_extended_op);
+     saa_write8(plinep,9);                     /* operand length */
+     saa_write8(plinep,DW_LNE_set_address);
+     saa_write64(plinep,0);            /* Start Address */
      /* if first entry */
      if (!dwarf_fsect)
      {
index 420afcf..5ac2878 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
+#include "raa.h"
 #include "outform.h"
 #include "compiler.h"
 
index a1e0b9a..05c7ce1 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "nasm.h"
 #include "nasmlib.h"
+#include "saa.h"
 #include "outform.h"
 
 /* VERBOSE_WARNINGS: define this to add some extra warnings... */
index c188095..a88e883 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -334,6 +334,7 @@ restart_parse:
        result->opcode == I_DY || result->opcode == I_INCBIN) {
         extop *eop, **tail = &result->eops, **fixptr;
         int oper_num = 0;
+       int32_t sign;
 
         result->eops_float = false;
 
@@ -355,85 +356,114 @@ restart_parse:
             eop->next = NULL;
             eop->type = EOT_NOTHING;
             oper_num++;
+           sign = +1;
 
-            if (i == TOKEN_NUM && tokval.t_charptr && is_comma_next()) {
+           /* is_comma_next() here is to distinguish this from
+              a string used as part of an expression... */
+            if (i == TOKEN_STR && is_comma_next()) {
                 eop->type = EOT_DB_STRING;
                 eop->stringval = tokval.t_charptr;
                 eop->stringlen = tokval.t_inttwo;
                 i = stdscan(NULL, &tokval);     /* eat the comma */
-                continue;
-            }
-
-            if ((i == TOKEN_FLOAT && is_comma_next())
-               || i == '-' || i == '+') {
-                int32_t sign = +1;
-
-                if (i == '+' || i == '-') {
-                    char *save = stdscan_bufptr;
-                   int token = i;
-                   sign = (i == '-') ? -1 : 1;
-                    i = stdscan(NULL, &tokval);
-                    if (i != TOKEN_FLOAT || !is_comma_next()) {
-                        stdscan_bufptr = save;
-                        i = tokval.t_type = token;
-                    }
-                }
-
-                if (i == TOKEN_FLOAT) {
-                    eop->type = EOT_DB_STRING;
-                    result->eops_float = true;
-                   switch (result->opcode) {
-                   case I_DB:
-                       eop->stringlen = 1;
-                       break;
-                   case I_DW:
-                       eop->stringlen = 2;
-                       break;
-                   case I_DD:
-                        eop->stringlen = 4;
-                       break;
-                   case I_DQ:
-                        eop->stringlen = 8;
-                       break;
-                   case I_DT:
-                        eop->stringlen = 10;
-                       break;
-                   case I_DO:
-                        eop->stringlen = 16;
-                       break;
-                   case I_DY:
-                        error(ERR_NONFATAL, "floating-point constant"
-                              " encountered in DY instruction");
-                       eop->stringlen = 0;
-                       break;
-                   default:
-                        error(ERR_NONFATAL, "floating-point constant"
-                              " encountered in unknown instruction");
-                        /*
-                         * fix suggested by Pedro Gimeno... original line
-                         * was:
-                         * eop->type = EOT_NOTHING;
-                         */
-                        eop->stringlen = 0;
-                       break;
-                    }
-                    eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen);
-                    tail = &eop->next;
-                    *fixptr = eop;
-                    eop->stringval = (char *)eop + sizeof(extop);
-                    if (!eop->stringlen ||
-                        !float_const(tokval.t_charptr, sign,
-                                     (uint8_t *)eop->stringval,
-                                     eop->stringlen, error))
-                        eop->type = EOT_NOTHING;
-                    i = stdscan(NULL, &tokval); /* eat the comma */
-                    continue;
-                }
-            }
-
-            /* anything else */
-            {
+           } else if (i == TOKEN_STRFUNC) {
+               bool parens = false;
+               const char *funcname = tokval.t_charptr;
+               enum strfunc func = tokval.t_integer;
+               i = stdscan(NULL, &tokval);
+               if (i == '(') {
+                   parens = true;
+                   i = stdscan(NULL, &tokval);
+               }
+               if (i != TOKEN_STR) {
+                   error(ERR_NONFATAL,
+                         "%s must be followed by a string constant",
+                         funcname);
+                       eop->type = EOT_NOTHING;
+               } else {
+                   eop->type = EOT_DB_STRING_FREE;
+                   eop->stringlen =
+                       string_transform(tokval.t_charptr, tokval.t_inttwo,
+                                        &eop->stringval, func);
+                   if (eop->stringlen == (size_t)-1) {
+                       error(ERR_NONFATAL, "invalid string for transform");
+                       eop->type = EOT_NOTHING;
+                   }
+               }
+               if (parens && i && i != ')') {
+                   i = stdscan(NULL, &tokval);
+                   if (i != ')') {
+                       error(ERR_NONFATAL, "unterminated %s function",
+                             funcname);
+                   }
+               }
+               if (i && i != ',')
+                   i = stdscan(NULL, &tokval);
+           } else if (i == '-' || i == '+') {
+               char *save = stdscan_bufptr;
+               int token = i;
+               sign = (i == '-') ? -1 : 1;
+               i = stdscan(NULL, &tokval);
+               if (i != TOKEN_FLOAT) {
+                   stdscan_bufptr = save;
+                   i = tokval.t_type = token;
+                   goto is_expression;
+               } else {
+                   goto is_float;
+               }
+            } else if (i == TOKEN_FLOAT) {
+           is_float:
+               eop->type = EOT_DB_STRING;
+               result->eops_float = true;
+               switch (result->opcode) {
+               case I_DB:
+                   eop->stringlen = 1;
+                   break;
+               case I_DW:
+                   eop->stringlen = 2;
+                   break;
+               case I_DD:
+                   eop->stringlen = 4;
+                   break;
+               case I_DQ:
+                   eop->stringlen = 8;
+                   break;
+               case I_DT:
+                   eop->stringlen = 10;
+                   break;
+               case I_DO:
+                   eop->stringlen = 16;
+                   break;
+               case I_DY:
+                   error(ERR_NONFATAL, "floating-point constant"
+                         " encountered in DY instruction");
+                   eop->stringlen = 0;
+                   break;
+               default:
+                   error(ERR_NONFATAL, "floating-point constant"
+                         " encountered in unknown instruction");
+                   /*
+                    * fix suggested by Pedro Gimeno... original line
+                    * was:
+                    * eop->type = EOT_NOTHING;
+                    */
+                   eop->stringlen = 0;
+                   break;
+               }
+               eop = nasm_realloc(eop, sizeof(extop) + eop->stringlen);
+               tail = &eop->next;
+               *fixptr = eop;
+               eop->stringval = (char *)eop + sizeof(extop);
+               if (!eop->stringlen ||
+                   !float_const(tokval.t_charptr, sign,
+                                (uint8_t *)eop->stringval,
+                                eop->stringlen, error))
+                   eop->type = EOT_NOTHING;
+               i = stdscan(NULL, &tokval); /* eat the comma */
+           } else {
+               /* anything else, assume it is an expression */
                 expr *value;
+
+           is_expression:
                 value = evaluate(stdscan, NULL, &tokval, NULL,
                                  critical, error, NULL);
                 i = tokval.t_type;
@@ -917,9 +947,10 @@ void cleanup_insn(insn * i)
 {
     extop *e;
 
-    while (i->eops) {
-        e = i->eops;
-        i->eops = i->eops->next;
+    while ((e = i->eops)) {
+        i->eops = e->next;
+       if (e->type == EOT_DB_STRING_FREE)
+           nasm_free(e->stringval);
         nasm_free(e);
     }
 }
index 1396eef..78a975f 100644 (file)
--- a/pptok.dat
+++ b/pptok.dat
@@ -47,4 +47,5 @@
 %strlen
 %substr
 %undef
+%warning
 %xdefine
index b34710d..8859005 100644 (file)
--- a/preproc.c
+++ b/preproc.c
@@ -1123,7 +1123,7 @@ static int ppscan(void *private_data, struct tokenval *tokval)
         for (r = p, s = ourcopy; *r; r++) {
            if (r >= p+MAX_KEYWORD)
                return tokval->t_type = TOKEN_ID; /* Not a keyword */
-            *s++ = tolower(*r);
+            *s++ = nasm_tolower(*r);
        }
         *s = '\0';
         /* right, so we have an identifier sitting in temp storage. now,
@@ -1134,10 +1134,11 @@ static int ppscan(void *private_data, struct tokenval *tokval)
     if (tline->type == TOK_NUMBER) {
        bool rn_error;
        tokval->t_integer = readnum(tline->text, &rn_error);
-       if (rn_error)
-           return tokval->t_type = TOKEN_ERRNUM;   /* some malformation occurred */
        tokval->t_charptr = tline->text;
-       return tokval->t_type = TOKEN_NUM;
+       if (rn_error)
+           return tokval->t_type = TOKEN_ERRNUM;
+       else
+           return tokval->t_type = TOKEN_NUM;
     }
 
     if (tline->type == TOK_FLOAT) {
@@ -1146,23 +1147,15 @@ static int ppscan(void *private_data, struct tokenval *tokval)
 
     if (tline->type == TOK_STRING) {
        char bq, *ep;
-       bool errquote;
-       bool rn_warn;
-        size_t l;
 
        bq = tline->text[0];
-        l = nasm_unquote(tline->text, &ep);
-       if (ep[0] != bq || ep[1] != '\0')
-           errquote = true;
+        tokval->t_charptr = tline->text;
+        tokval->t_inttwo = nasm_unquote(tline->text, &ep);
        
-       if (errquote)
-           return tokval->t_type = TOKEN_ERRNUM;
-
-        tokval->t_integer = readstrnum(tline->text, l, &rn_warn);
-        if (rn_warn)
-            error(ERR_WARNING | ERR_PASS1, "character constant too long");
-        tokval->t_charptr = NULL;
-        return tokval->t_type = TOKEN_NUM;
+       if (ep[0] != bq || ep[1] != '\0')
+           return tokval->t_type = TOKEN_ERRSTR;
+       else
+           return tokval->t_type = TOKEN_STR;
     }
 
     if (tline->type == TOK_OTHER) {
@@ -1707,20 +1700,6 @@ fail:
 }
 
 /*
- * Expand macros in a string. Used in %error directives (and it should
- * almost certainly be removed from there, too.)
- *
- * First tokenize the string, apply "expand_smacro" and then de-tokenize back.
- * The returned variable should ALWAYS be freed after usage.
- */
-void expand_macros_in_string(char **p)
-{
-    Token *line = tokenize(*p);
-    line = expand_smacro(line);
-    *p = detoken(line, false);
-}
-
-/*
  * Common code for defining an smacro
  */
 static bool define_smacro(Context *ctx, char *mname, bool casesense,
@@ -2199,22 +2178,30 @@ static int do_directive(Token * tline)
         break;
 
     case PP_ERROR:
+    case PP_WARNING:
+    {
+       int severity = PP_ERROR ? ERR_NONFATAL|ERR_NO_SEVERITY :
+           ERR_WARNING|ERR_NO_SEVERITY;
+
         tline->next = expand_smacro(tline->next);
         tline = tline->next;
         skip_white_(tline);
-        if (tok_type_(tline, TOK_STRING)) {
+       t = tline ? tline->next : NULL;
+       skip_white_(t);
+        if (tok_type_(tline, TOK_STRING) && !t) {
+           /* The line contains only a quoted string */
            p = tline->text;
            nasm_unquote(p, NULL);
-           expand_macros_in_string(&p); /* WHY? */
-            error(ERR_NONFATAL, "%s", p);
-            nasm_free(p);
-        } else {
+           error(severity, "%s: %s",  pp_directives[i], p);
+       } else {
+           /* Not a quoted string, or more than a quoted string */
             p = detoken(tline, false);
-            error(ERR_WARNING, "%s", p); /* WARNING!??!! */
-            nasm_free(p);
-        }
+           error(severity, "%s: %s",  pp_directives[i], p);
+           nasm_free(p);
+       }           
         free_tlist(origline);
         break;
+    }
 
     CASE_PP_IF:
         if (istk->conds && !emitting(istk->conds->state))
diff --git a/raa.c b/raa.c
new file mode 100644 (file)
index 0000000..ee5a5a9
--- /dev/null
+++ b/raa.c
@@ -0,0 +1,95 @@
+#include "nasmlib.h"
+#include "raa.h"
+
+#define LEAFSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_LEAF))
+#define BRANCHSIZ (sizeof(RAA)-sizeof(RAA_UNION)+sizeof(RAA_BRANCH))
+
+#define LAYERSHIFT(r) ( (r)->layers==0 ? RAA_BLKSHIFT : RAA_LAYERSHIFT )
+
+static struct RAA *real_raa_init(int layers)
+{
+    struct RAA *r;
+    int i;
+
+    if (layers == 0) {
+        r = nasm_zalloc(LEAFSIZ);
+        r->shift = 0;
+    } else {
+        r = nasm_malloc(BRANCHSIZ);
+        r->layers = layers;
+        for (i = 0; i < RAA_LAYERSIZE; i++)
+            r->u.b.data[i] = NULL;
+        r->shift = (RAA_BLKSHIFT-RAA_LAYERSHIFT) + layers*RAA_LAYERSHIFT;
+    }
+    return r;
+}
+
+struct RAA *raa_init(void)
+{
+    return real_raa_init(0);
+}
+
+void raa_free(struct RAA *r)
+{
+    if (r->layers) {
+        struct RAA **p;
+        for (p = r->u.b.data; p - r->u.b.data < RAA_LAYERSIZE; p++)
+            if (*p)
+                raa_free(*p);
+    }
+    nasm_free(r);
+}
+
+int64_t raa_read(struct RAA *r, int32_t posn)
+{
+    if ((uint32_t)posn >= (UINT32_C(1) << (r->shift + LAYERSHIFT(r))))
+        return 0;               /* Return 0 for undefined entries */
+    while (r->layers > 0) {
+       int32_t l = posn >> r->shift;
+       posn &= (UINT32_C(1) << r->shift)-1;
+        r = r->u.b.data[l];
+        if (!r)
+            return 0;           /* Return 0 for undefined entries */
+    }
+    return r->u.l.data[posn];
+}
+
+struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value)
+{
+    struct RAA *result;
+
+    if (posn < 0)
+        nasm_malloc_error(ERR_PANIC, "negative position in raa_write");
+
+    while ((UINT32_C(1) << (r->shift+LAYERSHIFT(r))) <= (uint32_t)posn) {
+        /*
+         * Must add a layer.
+         */
+        struct RAA *s;
+        int i;
+
+        s = nasm_malloc(BRANCHSIZ);
+        for (i = 0; i < RAA_LAYERSIZE; i++)
+            s->u.b.data[i] = NULL;
+        s->layers = r->layers + 1;
+        s->shift = LAYERSHIFT(r) + r->shift;
+        s->u.b.data[0] = r;
+        r = s;
+    }
+
+    result = r;
+
+    while (r->layers > 0) {
+        struct RAA **s;
+       int32_t l = posn >> r->shift;
+       posn &= (UINT32_C(1) << r->shift)-1;
+        s = &r->u.b.data[l];
+        if (!*s)
+            *s = real_raa_init(r->layers - 1);
+        r = *s;
+    }
+
+    r->u.l.data[posn] = value;
+
+    return result;
+}
diff --git a/raa.h b/raa.h
new file mode 100644 (file)
index 0000000..665e728
--- /dev/null
+++ b/raa.h
@@ -0,0 +1,56 @@
+#ifndef NASM_RAA_H
+#define NASM_RAA_H 1
+
+#include "compiler.h"
+
+/*
+ * Routines to manage a dynamic random access array of int64_ts which
+ * may grow in size to be more than the largest single malloc'able
+ * chunk.
+ */
+
+#define RAA_BLKSHIFT   15      /* 2**this many longs allocated at once */
+#define RAA_BLKSIZE    (1 << RAA_BLKSHIFT)
+#define RAA_LAYERSHIFT 15      /* 2**this many _pointers_ allocated */
+#define RAA_LAYERSIZE  (1 << RAA_LAYERSHIFT)
+
+typedef struct RAA RAA;
+typedef union RAA_UNION RAA_UNION;
+typedef struct RAA_LEAF RAA_LEAF;
+typedef struct RAA_BRANCH RAA_BRANCH;
+
+struct RAA {
+    /*
+     * Number of layers below this one to get to the real data. 0
+     * means this structure is a leaf, holding RAA_BLKSIZE real
+     * data items; 1 and above mean it's a branch, holding
+     * RAA_LAYERSIZE pointers to the next level branch or leaf
+     * structures.
+     */
+    int layers;
+
+    /*
+     * Number of real data items spanned by one position in the
+     * `data' array at this level. This number is 0 trivially, for
+     * a leaf (level 0): for a level 1 branch it should be
+     * RAA_BLKSHIFT, and for a level 2 branch it's
+     * RAA_LAYERSHIFT+RAA_BLKSHIFT.
+     */
+    int shift;
+
+    union RAA_UNION {
+        struct RAA_LEAF {
+            int64_t data[RAA_BLKSIZE];
+        } l;
+        struct RAA_BRANCH {
+            struct RAA *data[RAA_LAYERSIZE];
+        } b;
+    } u;
+};
+
+struct RAA *raa_init(void);
+void raa_free(struct RAA *);
+int64_t raa_read(struct RAA *, int32_t);
+struct RAA *raa_write(struct RAA *r, int32_t posn, int64_t value);
+
+#endif /* NASM_RAA_H */
diff --git a/saa.c b/saa.c
new file mode 100644 (file)
index 0000000..1704b7d
--- /dev/null
+++ b/saa.c
@@ -0,0 +1,380 @@
+#include "compiler.h"
+#include "nasmlib.h"
+#include "saa.h"
+
+/* Aggregate SAA components smaller than this */
+#define SAA_BLKSHIFT   16
+#define SAA_BLKLEN     ((size_t)1 << SAA_BLKSHIFT)
+
+struct SAA *saa_init(size_t elem_len)
+{
+    struct SAA *s;
+    char *data;
+
+    s = nasm_zalloc(sizeof(struct SAA));
+
+    if (elem_len >= SAA_BLKLEN)
+       s->blk_len = elem_len;
+    else
+       s->blk_len = SAA_BLKLEN - (SAA_BLKLEN % elem_len);
+
+    s->elem_len = elem_len;
+    s->length = s->blk_len;
+    data = nasm_malloc(s->blk_len);
+    s->nblkptrs = s->nblks = 1;
+    s->blk_ptrs = nasm_malloc(sizeof(char *));
+    s->blk_ptrs[0] = data;
+    s->wblk = s->rblk = &s->blk_ptrs[0];
+
+    return s;
+}
+
+void saa_free(struct SAA *s)
+{
+    char **p;
+    size_t n;
+
+    for (p = s->blk_ptrs, n = s->nblks; n; p++, n--)
+       nasm_free(*p);
+
+    nasm_free(s->blk_ptrs);
+    nasm_free(s);
+}
+
+/* Add one allocation block to an SAA */
+static void saa_extend(struct SAA *s)
+{
+    size_t blkn = s->nblks++;
+
+    if (blkn >= s->nblkptrs) {
+       size_t rindex = s->rblk - s->blk_ptrs;
+       size_t windex = s->wblk - s->blk_ptrs;
+
+       s->nblkptrs <<= 1;
+       s->blk_ptrs = nasm_realloc(s->blk_ptrs, s->nblkptrs*sizeof(char *));
+
+       s->rblk = s->blk_ptrs + rindex;
+       s->wblk = s->blk_ptrs + windex;
+    }
+
+    s->blk_ptrs[blkn] = nasm_malloc(s->blk_len);
+    s->length += s->blk_len;
+}
+
+void *saa_wstruct(struct SAA *s)
+{
+    void *p;
+
+    if (s->wpos % s->elem_len)
+           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
+                             "misaligned wpos in saa_wstruct");
+
+    if (s->wpos + s->elem_len > s->blk_len) {
+       if (s->wpos != s->blk_len)
+           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
+                             "unfilled block in saa_wstruct");
+
+       if (s->wptr + s->elem_len > s->length)
+           saa_extend(s);
+       s->wblk++;
+       s->wpos = 0;
+    }
+
+    p = *s->wblk + s->wpos;
+    s->wpos += s->elem_len;
+    s->wptr += s->elem_len;
+
+    if (s->wptr > s->datalen)
+       s->datalen = s->wptr;
+
+    return p;
+}
+
+void saa_wbytes(struct SAA *s, const void *data, size_t len)
+{
+    const char *d = data;
+
+    while (len) {
+        size_t l = s->blk_len - s->wpos;
+        if (l > len)
+            l = len;
+        if (l) {
+            if (d) {
+                memcpy(*s->wblk + s->wpos, d, l);
+                d += l;
+            } else
+                memset(*s->wblk + s->wpos, 0, l);
+            s->wpos += l;
+           s->wptr += l;
+            len -= l;
+
+           if (s->datalen < s->wptr)
+               s->datalen = s->wptr;
+        }
+        if (len) {
+           if (s->wptr >= s->length)
+               saa_extend(s);
+           s->wblk++;
+           s->wpos = 0;
+       }
+    }
+}
+
+void saa_rewind(struct SAA *s)
+{
+    s->rblk = s->blk_ptrs;
+    s->rpos = s->rptr = 0;
+}
+
+void *saa_rstruct(struct SAA *s)
+{
+    void *p;
+
+    if (s->rptr + s->elem_len > s->datalen)
+       return NULL;
+
+    if (s->rpos % s->elem_len)
+           nasm_malloc_error(ERR_PANIC|ERR_NOFILE,
+                             "misaligned rpos in saa_rstruct");
+
+    if (s->rpos + s->elem_len > s->blk_len) {
+       s->rblk++;
+       s->rpos = 0;
+    }
+
+    p = *s->rblk + s->rpos;
+    s->rpos += s->elem_len;
+    s->rptr += s->elem_len;
+
+    return p;
+}
+
+const void *saa_rbytes(struct SAA *s, size_t *lenp)
+{
+    const void *p;
+    size_t len;
+
+    if (s->rptr >= s->datalen) {
+       *lenp = 0;
+       return NULL;
+    }
+
+    if (s->rpos >= s->blk_len) {
+       s->rblk++;
+       s->rpos = 0;
+    }
+
+    len = *lenp;
+    if (len > s->datalen - s->rptr)
+       len = s->datalen - s->rptr;
+    if (len > s->blk_len - s->rpos)
+       len = s->blk_len - s->rpos;
+
+    *lenp = len;
+    p = *s->rblk + s->rpos;
+
+    s->rpos += len;
+    s->rptr += len;
+
+    return p;
+}
+
+void saa_rnbytes(struct SAA *s, void *data, size_t len)
+{
+    char *d = data;
+
+    if (s->rptr + len > s->datalen) {
+       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_rnbytes");
+       return;
+    }
+
+    while (len) {
+        size_t l;
+       const void *p;
+
+       l = len;
+       p = saa_rbytes(s, &l);
+
+       memcpy(d, p, l);
+       d   += l;
+       len -= l;
+    }
+}
+
+/* Same as saa_rnbytes, except position the counter first */
+void saa_fread(struct SAA *s, size_t posn, void *data, size_t len)
+{
+    size_t ix;
+
+    if (posn+len > s->datalen) {
+       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fread");
+       return;
+    }
+
+    if (likely(s->blk_len == SAA_BLKLEN)) {
+       ix = posn >> SAA_BLKSHIFT;
+       s->rpos = posn & (SAA_BLKLEN-1);
+    } else {
+       ix = posn / s->blk_len;
+       s->rpos = posn % s->blk_len;
+    }
+    s->rptr = posn;
+    s->rblk = &s->blk_ptrs[ix];
+
+    saa_rnbytes(s, data, len);
+}
+
+/* Same as saa_wbytes, except position the counter first */
+void saa_fwrite(struct SAA *s, size_t posn, const void *data, size_t len)
+{
+    size_t ix;
+
+    if (posn > s->datalen) {
+       /* Seek beyond the end of the existing array not supported */
+       nasm_malloc_error(ERR_PANIC|ERR_NOFILE, "overrun in saa_fwrite");
+       return;
+    }
+    
+    if (likely(s->blk_len == SAA_BLKLEN)) {
+       ix = posn >> SAA_BLKSHIFT;
+       s->wpos = posn & (SAA_BLKLEN-1);
+    } else {
+       ix = posn / s->blk_len;
+       s->wpos = posn % s->blk_len;
+    }
+    s->wptr = posn;
+    s->wblk = &s->blk_ptrs[ix];
+
+    if (!s->wpos) {
+       s->wpos = s->blk_len;
+       s->wblk--;
+    }
+
+    saa_wbytes(s, data, len);
+}
+
+void saa_fpwrite(struct SAA *s, FILE * fp)
+{
+    const char *data;
+    size_t len;
+
+    saa_rewind(s);
+    while (len = s->datalen, (data = saa_rbytes(s, &len)) != NULL)
+        fwrite(data, 1, len, fp);
+}
+
+void saa_write8(struct SAA *s, uint8_t v)
+{
+    saa_wbytes(s, &v, 1);
+}
+
+#ifdef WORDS_LITTEENDIAN
+
+void saa_write16(struct SAA *s, uint16_t v)
+{
+    saa_wbytes(s, &v, 2);
+}
+
+void saa_write32(struct SAA *s, uint32_t v)
+{
+    saa_wbytes(s, &v, 4);
+}
+
+void saa_write64(struct SAA *s, uint64_t v)
+{
+    saa_wbytes(s, &v, 8);
+}
+
+#else /* not WORDS_LITTLEENDIAN */
+
+void saa_write16(struct SAA *s, uint16_t v)
+{
+    uint8_t b[2];
+
+    b[0] = v;
+    b[1] = v >> 8;
+    saa_wbytes(s, b, 2);
+}
+
+void saa_write32(struct SAA *s, uint32_t v)
+{
+    uint8_t b[4];
+
+    b[0] = v;
+    b[1] = v >> 8;
+    b[2] = v >> 16;
+    b[3] = v >> 24;
+    saa_wbytes(s, b, 4);
+}
+
+void saa_write64(struct SAA *s, uint64_t v)
+{
+    uint8_t b[8];
+
+    b[0] = v;
+    b[1] = v >> 8;
+    b[2] = v >> 16;
+    b[3] = v >> 24;
+    b[4] = v >> 32;
+    b[5] = v >> 40;
+    b[6] = v >> 48;
+    b[7] = v >> 56;
+    saa_wbytes(s, b, 8);
+}
+
+#endif /* WORDS_LITTLEENDIAN */
+
+/* write unsigned LEB128 value to SAA */
+void saa_wleb128u(struct SAA *psaa, int value)
+{
+  char temp[64], *ptemp;
+  uint8_t byte;
+  int len;
+
+  ptemp = temp;
+  len = 0;
+  do
+  {
+     byte = value & 127;
+     value >>= 7;
+     if (value != 0) /* more bytes to come */
+        byte |= 0x80;
+     *ptemp = byte;
+     ptemp++;
+     len++;
+  } while (value != 0);
+  saa_wbytes(psaa, temp, len);
+}
+
+/* write signed LEB128 value to SAA */
+void saa_wleb128s(struct SAA *psaa, int value)
+{
+  char temp[64], *ptemp;
+  uint8_t byte;
+  bool more, negative;
+  int size, len;
+
+  ptemp = temp;
+  more = 1;
+  negative = (value < 0);
+  size = sizeof(int) * 8;
+  len = 0;
+  while(more)
+  {
+    byte = value & 0x7f;
+    value >>= 7;
+    if (negative)
+     /* sign extend */
+     value |= - (1 <<(size - 7));
+    /* sign bit of byte is second high order bit (0x40) */
+    if ((value == 0 && ! (byte & 0x40)) ||
+       ((value == -1) && (byte & 0x40)))
+       more = 0;
+    else
+      byte |= 0x80;
+    *ptemp = byte;
+    ptemp++;
+    len++;
+  }
+  saa_wbytes(psaa, temp, len);
+}
diff --git a/saa.h b/saa.h
new file mode 100644 (file)
index 0000000..1a8459c
--- /dev/null
+++ b/saa.h
@@ -0,0 +1,59 @@
+#ifndef NASM_SAA_H
+#define NASM_SAA_H
+
+#include "compiler.h"
+
+/*
+ * Routines to manage a dynamic sequential-access array, under the
+ * same restriction on maximum mallocable block. This array may be
+ * written to in two ways: a contiguous chunk can be reserved of a
+ * given size with a pointer returned OR single-byte data may be
+ * written. The array can also be read back in the same two ways:
+ * as a series of big byte-data blocks or as a list of structures
+ * of a given size.
+ */
+
+struct SAA {
+    /*
+     * members `end' and `elem_len' are only valid in first link in
+     * list; `rptr' and `rpos' are used for reading
+     */
+    size_t elem_len;           /* Size of each element */
+    size_t blk_len;            /* Size of each allocation block */
+    size_t nblks;              /* Total number of allocated blocks */
+    size_t nblkptrs;           /* Total number of allocation block pointers */
+    size_t length;             /* Total allocated length of the array */
+    size_t datalen;            /* Total data length of the array */
+    char **wblk;               /* Write block pointer */
+    size_t wpos;               /* Write position inside block */
+    size_t wptr;               /* Absolute write position */
+    char **rblk;               /* Read block pointer */
+    size_t rpos;               /* Read position inside block */
+    size_t rptr;               /* Absolute read position */
+    char **blk_ptrs;           /* Pointer to pointer blocks */
+};
+
+struct SAA *saa_init(size_t elem_len);    /* 1 == byte */
+void saa_free(struct SAA *);
+void *saa_wstruct(struct SAA *);        /* return a structure of elem_len */
+void saa_wbytes(struct SAA *, const void *, size_t);      /* write arbitrary bytes */
+void saa_rewind(struct SAA *);  /* for reading from beginning */
+void *saa_rstruct(struct SAA *);        /* return NULL on EOA */
+const void *saa_rbytes(struct SAA *, size_t *); /* return 0 on EOA */
+void saa_rnbytes(struct SAA *, void *, size_t);   /* read a given no. of bytes */
+/* random access */
+void saa_fread(struct SAA *, size_t, void *, size_t);
+void saa_fwrite(struct SAA *, size_t, const void *, size_t);
+
+/* dump to file */
+void saa_fpwrite(struct SAA *, FILE *);
+
+/* Write specific-sized values */
+void saa_write8(struct SAA *s, uint8_t v);
+void saa_write16(struct SAA *s, uint16_t v);
+void saa_write32(struct SAA *s, uint32_t v);
+void saa_write64(struct SAA *s, uint64_t v);
+void saa_wleb128u(struct SAA *, int); /* write unsigned LEB128 value */
+void saa_wleb128s(struct SAA *, int); /* write signed LEB128 value */
+
+#endif /* NASM_SAA_H */
index 4db1368..60982a4 100644 (file)
--- a/stdscan.c
+++ b/stdscan.c
@@ -97,7 +97,7 @@ int stdscan(void *private_data, struct tokenval *tv)
             return tv->t_type = TOKEN_ID;       /* bypass all other checks */
 
         for (s = tv->t_charptr, r = ourcopy; *s; s++)
-            *r++ = tolower(*s);
+            *r++ = nasm_tolower(*s);
         *r = '\0';
         /* right, so we have an identifier sitting in temp storage. now,
          * is it actually a register or instruction name, or what? */
@@ -177,17 +177,13 @@ int stdscan(void *private_data, struct tokenval *tv)
     } else if (*stdscan_bufptr == '\'' || *stdscan_bufptr == '"' ||
               *stdscan_bufptr == '`') {
        /* a quoted string */
-        bool rn_warn;
        char start_quote = *stdscan_bufptr;
        tv->t_charptr = stdscan_bufptr;
        tv->t_inttwo = nasm_unquote(tv->t_charptr, &stdscan_bufptr);
        if (*stdscan_bufptr != start_quote)
-           return tv->t_type = TOKEN_ERRNUM;
+           return tv->t_type = TOKEN_ERRSTR;
        stdscan_bufptr++;       /* Skip final quote */
-        tv->t_integer = readstrnum(tv->t_charptr, tv->t_inttwo, &rn_warn);
-       /* Issue: can't readily check rn_warn, because we might be in
-          a db family context... */
-        return tv->t_type = TOKEN_NUM;
+        return tv->t_type = TOKEN_STR;
     } else if (*stdscan_bufptr == ';') {
         /* a comment has happened - stay */
         return tv->t_type = 0;
diff --git a/strfunc.c b/strfunc.c
new file mode 100644 (file)
index 0000000..5929aae
--- /dev/null
+++ b/strfunc.c
@@ -0,0 +1,170 @@
+/*
+ * strfunc.c
+ *
+ * String transformation functions
+ */
+
+#include "nasmlib.h"
+#include "nasm.h"
+
+/*
+ * Convert a string in UTF-8 format to UTF-16LE
+ */
+static size_t utf8_to_16le(uint8_t *str, size_t len, char *op)
+{
+#define EMIT(x) do { if (op) { WRITESHORT(op,x); } outlen++; } while(0)
+
+    size_t outlen = 0;
+    int expect = 0;
+    uint8_t c;
+    uint32_t v = 0, vmin = 0;
+
+    while (len--) {
+       c = *str++;
+
+       if (expect) {
+           if ((c & 0xc0) != 0x80) {
+               expect = 0;
+               return -1;
+           } else {
+               v = (v << 6) | (c & 0x3f);
+               if (!--expect) {
+                   if (v < vmin || v > 0x10ffff ||
+                       (v >= 0xd800 && v <= 0xdfff)) {
+                       return -1;
+                   } else if (v > 0xffff) {
+                       v -= 0x10000;
+                       EMIT(0xd800 | (v >> 10));
+                       EMIT(0xdc00 | (v & 0x3ff));
+                   } else {
+                       EMIT(v);
+                   }
+               }
+               continue;
+           }
+       }
+
+       if (c < 0x80) {
+           EMIT(c);
+       } else if (c < 0xc0 || c >= 0xfe) {
+           /* Invalid UTF-8 */
+           return -1;
+       } else if (c < 0xe0) {
+           v = c & 0x1f;
+           expect = 1;
+           vmin = 0x80;
+       } else if (c < 0xf0) {
+           v = c & 0x0f;
+           expect = 2;
+           vmin = 0x800;
+       } else if (c < 0xf8) {
+           v = c & 0x07;
+           expect = 3;
+           vmin = 0x10000;
+       } else if (c < 0xfc) {
+           v = c & 0x03;
+           expect = 4;
+           vmin = 0x200000;
+       } else {
+           v = c & 0x01;
+           expect = 5;
+           vmin = 0x4000000;
+       }
+    }
+
+    return expect ? (size_t)-1 : outlen << 1;
+
+#undef EMIT
+}
+
+/*
+ * Convert a string in UTF-8 format to UTF-32LE
+ */
+static size_t utf8_to_32le(uint8_t *str, size_t len, char *op)
+{
+#define EMIT(x) do { if (op) { WRITELONG(op,x); } outlen++; } while(0)
+
+    size_t outlen = 0;
+    int expect = 0;
+    uint8_t c;
+    uint32_t v = 0, vmin = 0;
+
+    while (len--) {
+       c = *str++;
+
+       if (expect) {
+           if ((c & 0xc0) != 0x80) {
+               return -1;
+           } else {
+               v = (v << 6) | (c & 0x3f);
+               if (!--expect) {
+                   if (v < vmin || (v >= 0xd800 && v <= 0xdfff)) {
+                       return -1;
+                   } else {
+                       EMIT(v);
+                   }
+               }
+               continue;
+           }
+       }
+
+       if (c < 0x80) {
+           EMIT(c);
+       } else if (c < 0xc0 || c >= 0xfe) {
+           /* Invalid UTF-8 */
+           return -1;
+       } else if (c < 0xe0) {
+           v = c & 0x1f;
+           expect = 1;
+           vmin = 0x80;
+       } else if (c < 0xf0) {
+           v = c & 0x0f;
+           expect = 2;
+           vmin = 0x800;
+       } else if (c < 0xf8) {
+           v = c & 0x07;
+           expect = 3;
+           vmin = 0x10000;
+       } else if (c < 0xfc) {
+           v = c & 0x03;
+           expect = 4;
+           vmin = 0x200000;
+       } else {
+           v = c & 0x01;
+           expect = 5;
+           vmin = 0x4000000;
+       }
+    }
+
+    return expect ? (size_t)-1 : outlen << 2;
+
+#undef EMIT
+}
+
+typedef size_t (*transform_func)(uint8_t *, size_t, char *);
+
+/*
+ * Apply a specific string transform and return it in a nasm_malloc'd
+ * buffer, returning the length.  On error, returns (size_t)-1 and no
+ * buffer is allocated.
+ */
+size_t string_transform(char *str, size_t len, char **out, enum strfunc func)
+{
+    /* This should match enum strfunc in nasm.h */
+    static const transform_func str_transforms[] = {
+       utf8_to_16le,
+       utf8_to_32le,
+    };
+    transform_func transform = str_transforms[func];
+    size_t outlen;
+    uint8_t *s = (uint8_t *)str;
+    char *buf;
+
+    outlen = transform(s, len, NULL);
+    if (outlen == (size_t)-1)
+       return -1;
+
+    *out = buf = nasm_malloc(outlen+1);
+    buf[outlen] = '\0';                /* Forcibly null-terminate the buffer */
+    return transform(s, len, buf);
+}
diff --git a/test/utf.asm b/test/utf.asm
new file mode 100644 (file)
index 0000000..1c8a8f0
--- /dev/null
@@ -0,0 +1,28 @@
+%define u(x) __utf16__(x)
+%define w(x) __utf32__(x)
+
+       db `Test \u306a\U0001abcd\n`
+       dw u(`Test \u306a\U0001abcd\n`)
+       dd w(`Test \u306a\U0001abcd\n`)
+
+       db `\u306a`
+       db `\xe3\x81\xaa`
+
+       dw __utf16__ "Hello, World!"
+
+       nop
+
+       mov ax,u(`a`)
+       mov bx,u(`\u306a`)
+       mov cx,u(`\xe3\x81\xaa`)
+       mov eax,u(`ab`)
+       mov ebx,u(`\U0001abcd`)
+       mov ecx,w(`\U0001abcd`)
+
+%ifdef ERROR
+       dw __utf16__ 33
+       dw __utf16__, 46
+       dw __utf16__("Hello, World!",16)
+       dw __utf16__("Hello, World!",16
+       dw u(`\xff`)
+%endif
index 6c3ad65..128bc67 100644 (file)
@@ -53,6 +53,10 @@ __float80e__
 __float128l__
 __float128h__
 
+% TOKEN_STRFUNC, 0, STRFUNC_{__*__}
+__utf16__
+__utf32__
+
 % TOKEN_*, 0, 0
 seg
 wrt
diff --git a/wsaa.h b/wsaa.h
deleted file mode 100644 (file)
index 63f8335..0000000
--- a/wsaa.h
+++ /dev/null
@@ -1,78 +0,0 @@
-#ifndef NASM_WSAA_H
-#define NASM_WSAA_H
-
-#include "compiler.h"
-#include "nasmlib.h"
-
-#if X86_MEMORY
-
-#define WSAACHAR(s,p,v)                                \
-    do {                                       \
-       *(uint8_t *)(p) = (v);                  \
-       saa_wbytes(s, p, 1);                    \
-    } while (0)
-
-#define WSAASHORT(s,p,v)                       \
-    do {                                       \
-       *(uint16_t *)(p) = (v);                 \
-       saa_wbytes(s, p, 2);                    \
-    } while (0)
-
-#define WSAALONG(s,p,v)                                \
-    do {                                       \
-       *(uint32_t *)(p) = (v);                 \
-       saa_wbytes(s, p, 4);                    \
-    } while (0)
-
-#define WSAADLONG(s,p,v)                       \
-    do {                                       \
-       *(uint64_t *)(p) = (v);                 \
-       saa_wbytes(s, p, 8);                    \
-    } while (0)
-
-#else /* !X86_MEMORY */
-
-#define WSAACHAR(s,p,v)                                \
-    do {                                       \
-       *(uint8_t *)(p) = (v);                  \
-       saa_wbytes(s, p, 1);                    \
-    } while (0)
-
-#define WSAASHORT(s,p,v)                       \
-    do {                                       \
-       uint16_t _wss_v = (v);                  \
-       uint8_t *_wss_p = (uint8_t *)(p);       \
-       _wss_p[0] = _wss_v;                     \
-       _wss_p[1] = _wss_v >> 8;                \
-       saa_wbytes(s, _wss_p, 2);               \
-    } while (0)
-
-#define WSAALONG(s,p,v)                                \
-    do {                                       \
-       uint32_t _wsl_v = (v);                  \
-       uint8_t *_wsl_p = (uint8_t *)(p);       \
-       _wsl_p[0] = _wsl_v;                     \
-       _wsl_p[1] = _wsl_v >> 8;                \
-       _wsl_p[2] = _wsl_v >> 16;               \
-       _wsl_p[3] = _wsl_v >> 24;               \
-       saa_wbytes(s, _wsl_p, 4);               \
-    } while (0)
-
-#define WSAADLONG(s,p,v)                       \
-    do {                                       \
-       uint64_t _wsq_v = (v);                  \
-       uint8_t *_wsq_p = (uint8_t *)(p);       \
-       _wsq_p[0] = _wsq_v;                     \
-       _wsq_p[1] = _wsq_v >> 8;                \
-       _wsq_p[2] = _wsq_v >> 16;               \
-       _wsq_p[3] = _wsq_v >> 24;               \
-       _wsq_p[4] = _wsq_v >> 32;               \
-       _wsq_p[5] = _wsq_v >> 40;               \
-       _wsq_p[6] = _wsq_v >> 48;               \
-       _wsq_p[7] = _wsq_v >> 56;               \
-       saa_wbytes(s, _wsq_p, 8);               \
-    } while (0)
-
-#endif
-
-#endif /* NASM_WSAA_H */