]> git.pld-linux.org Git - packages/crossppc-binutils.git/blame - binutils-gasp.patch
- updated gettext BR
[packages/crossppc-binutils.git] / binutils-gasp.patch
CommitLineData
7f820327
PS
1--- binutils-2.17.50.0.13/gas/Makefile.am.orig 2007-03-16 16:48:29.000000000 +0100
2+++ binutils-2.17.50.0.13/gas/Makefile.am 2007-03-16 20:26:20.200480821 +0100
3@@ -199,7 +199,7 @@
0087dcf3
JB
4 symbols.c \
5 write.c
6
b4f91c33
AM
7-CFILES = $(GAS_CFILES) itbl-ops.c cgen.c
8+CFILES = $(GAS_CFILES) gasp.c itbl-ops.c cgen.c
0087dcf3
JB
9
10 HFILES = \
11 as.h \
7f820327 12@@ -455,7 +455,8 @@
0087dcf3
JB
13
14 # Note: GASP is now deprecated and has been removed. It is still
15 # available in the CVS archive or older binutils releases if it is needed.
16-noinst_PROGRAMS = as-new
17+# ...and it is needed for few packages in distribution.
18+noinst_PROGRAMS = as-new gasp-new
19 noinst_SCRIPTS = $(GDBINIT)
20 EXTRA_SCRIPTS = .gdbinit
21
7f820327 22@@ -517,6 +518,10 @@
0087dcf3
JB
23 as.h asintl.h bignum.h bit_fix.h config.h emul.h expr.h flonum.h \
24 frags.h hash.h listing.h obj.h read.h symbols.h tc.h write.h
25
26+gasp_new_SOURCES = gasp.c macro.c sb.c hash.c
27+gasp_new_LDADD = ../libiberty/libiberty.a $(INTLLIBS)
28+gasp_new_DEPENDENCIES = ../libiberty/libiberty.a $(INTLDEPS)
29+
a94d65a7
AM
30 EXPECT = expect
31 RUNTEST = runtest
32 RUNTESTFLAGS=
4d792041 33@@ -682,6 +682,9 @@
34 itbl-lex.o: itbl-lex.c itbl-parse.h $(srcdir)/itbl-lex.h
35 $(COMPILE) -c $< $(NO_WERROR)
36
37+gasp.o:gasp.c $(INCDIR)/getopt.h $(INCDIR)/safe-ctype.h \
38+ sb.h macro.h $(INCDIR)/xregex.h $(INCDIR)/xregex2.h
39+
40 # Disable -Werror, if it has been enabled, since old versions of bison/
41 # yacc will produce working code which contain compile time warnings.
42 itbl-parse.o: itbl-parse.c itbl-parse.h $(srcdir)/itbl-ops.h $(srcdir)/itbl-lex.h
7f820327
PS
43--- binutils-2.17.50.0.13/gas/doc/Makefile.am.orig 2007-03-16 16:48:29.000000000 +0100
44+++ binutils-2.17.50.0.13/gas/doc/Makefile.am 2007-03-16 20:27:05.810679469 +0100
2aace8d6
PS
45@@ -15,7 +15,7 @@
46
47 man_MANS = as.1
48
07e9ed69 49-info_TEXINFOS = as.texinfo
2aace8d6
PS
50+info_TEXINFOS = as.texinfo gasp.texinfo
51 as_TEXINFOS = asconfig.texi $(CPU_DOCS)
52
53 AM_MAKEINFOFLAGS = -I "$(srcdir)" -I "$(top_srcdir)/../libiberty" \
a94d65a7
AM
54--- binutils-2.16.91.0.2.org/gas/doc/gasp.texinfo 1970-01-01 00:00:00.000000000 +0000
55+++ binutils-2.16.91.0.2/gas/doc/gasp.texinfo 2005-07-21 18:31:04.000000000 +0000
0087dcf3
JB
56@@ -0,0 +1,1456 @@
57+\input texinfo @c -*- Texinfo -*-
58+@setfilename gasp.info
59+@c
60+@c This file documents the assembly preprocessor "GASP"
61+@c
62+@c Copyright 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
63+@c
64+@c Permission is granted to copy, distribute and/or modify this document
65+@c under the terms of the GNU Free Documentation License, Version 1.1
66+@c or any later version published by the Free Software Foundation;
67+@c with no Invariant Sections, with no Front-Cover Texts, and with no
68+@c Back-Cover Texts. A copy of the license is included in the
69+@c section entitled "GNU Free Documentation License".
70+
71+@ifinfo
72+@format
73+START-INFO-DIR-ENTRY
74+* gasp: (gasp). The GNU Assembler Preprocessor
75+END-INFO-DIR-ENTRY
76+@end format
77+@end ifinfo
78+
79+@syncodeindex ky cp
80+@syncodeindex fn cp
81+
82+@finalout
83+@setchapternewpage odd
84+@settitle GASP
85+@titlepage
86+@c FIXME boring title
87+@title GASP, an assembly preprocessor
88+@subtitle for GASP version 1
89+@sp 1
90+@subtitle March 1994
91+@author Roland Pesch
92+@page
93+
94+@tex
95+{\parskip=0pt \hfill Cygnus Support\par
96+}
97+@end tex
98+
99+@vskip 0pt plus 1filll
100+Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
101+
102+ Permission is granted to copy, distribute and/or modify this document
103+ under the terms of the GNU Free Documentation License, Version 1.1
104+ or any later version published by the Free Software Foundation;
105+ with no Invariant Sections, with no Front-Cover Texts, and with no
106+ Back-Cover Texts. A copy of the license is included in the
107+ section entitled "GNU Free Documentation License".
108+
109+@end titlepage
110+
111+@ifinfo
112+Copyright @copyright{} 1994, 1995, 2000, 2002 Free Software Foundation, Inc.
113+
114+@ignore
115+Permission is granted to process this file through TeX and print the
116+results, provided the printed document carries a copying permission
117+notice identical to this one except for the removal of this paragraph
118+(this paragraph not being relevant to the printed manual).
119+@end ignore
120+
121+ Permission is granted to copy, distribute and/or modify this document
122+ under the terms of the GNU Free Documentation License, Version 1.1
123+ or any later version published by the Free Software Foundation;
124+ with no Invariant Sections, with no Front-Cover Texts, and with no
125+ Back-Cover Texts. A copy of the license is included in the
126+ section entitled "GNU Free Documentation License".
127+
128+
129+@node Top
130+@top GASP
131+
132+GASP is a preprocessor for assembly programs.
133+
134+This file describes version 1 of GASP.
135+
136+Steve Chamberlain wrote GASP; Roland Pesch wrote this manual.
137+
138+@menu
139+* Overview:: What is GASP?
140+* Invoking GASP:: Command line options.
141+* Commands:: Preprocessor commands.
142+* GNU Free Documentation License:: GNU Free Documentation License
143+* Index:: Index.
144+@end menu
145+@end ifinfo
146+
147+@node Overview
148+@chapter What is GASP?
149+
150+The primary purpose of the @sc{gnu} assembler is to assemble the output of
151+other programs---notably compilers. When you have to hand-code
152+specialized routines in assembly, that means the @sc{gnu} assembler is
153+an unfriendly processor: it has no directives for macros, conditionals,
154+or many other conveniences that you might expect.
155+
156+In some cases you can simply use the C preprocessor, or a generalized
157+preprocessor like @sc{m4}; but this can be awkward, since none of these
158+things are designed with assembly in mind.
159+
160+@sc{gasp} fills this need. It is expressly designed to provide the
161+facilities you need with hand-coded assembly code. Implementing it as a
162+preprocessor, rather than part of the assembler, allows the maximum
163+flexibility: you can use it with hand-coded assembly, without paying a
164+penalty of added complexity in the assembler you use for compiler
165+output.
166+
167+@emph{Note} The use of @sc{gasp} has now been deprecated. Anything
168+that it could do can now be done by the macro facilities built into
169+@sc{gas} itself. At some point in the future the @sc{gasp} sources will
170+be removed entirely from the binutils distribution.
171+
172+Here is a small example to give the flavor of @sc{gasp}. This input to
173+@sc{gasp}
174+
175+@cartouche
176+@example
177+ .MACRO saveregs from=8 to=14
178+count .ASSIGNA \from
179+ ! save r\from..r\to
180+ .AWHILE \&count LE \to
181+ mov r\&count,@@-sp
182+count .ASSIGNA \&count + 1
183+ .AENDW
184+ .ENDM
185+
186+ saveregs from=12
187+
188+bar: mov #H'dead+10,r0
189+foo .SDATAC "hello"<10>
190+ .END
191+@end example
192+@end cartouche
193+
194+@noindent
195+generates this assembly program:
196+
197+@cartouche
198+@example
199+ ! save r12..r14
200+ mov r12,@@-sp
201+ mov r13,@@-sp
202+ mov r14,@@-sp
203+
204+bar: mov #57005+10,r0
205+foo: .byte 6,104,101,108,108,111,10
206+@end example
207+@end cartouche
208+
209+@node Invoking GASP
210+@chapter Command Line Options
211+
212+@c FIXME! Or is there a simpler way, calling from GAS option?
213+The simplest way to use @sc{gasp} is to run it as a filter and assemble
214+its output. In Unix and its ilk, you can do this, for example:
215+
216+@c FIXME! GASP filename suffix convention?
217+@example
218+$ gasp prog.asm | as -o prog.o
219+@end example
220+
221+Naturally, there are also a few command-line options to allow you to
222+request variations on this basic theme. Here is the full set of
223+possibilities for the @sc{gasp} command line.
224+
225+@example
226+gasp [ -a | --alternate ]
227+ [ -c @var{char} | --commentchar @var{char} ]
228+ [ -d | --debug ] [ -h | --help ] [ -M | --mri ]
229+ [ -o @var{outfile} | --output @var{outfile} ]
230+ [ -p | --print ] [ -s | --copysource ]
231+ [ -u | --unreasonable ] [ -v | --version ]
232+ @var{infile} @dots{}
233+@end example
234+
235+@ftable @code
236+@item @var{infile} @dots{}
237+@c FIXME! Why not stdin as default infile?
238+The input file names. You must specify at least one input file; if you
239+specify more, @sc{gasp} preprocesses them all, concatenating the output
240+in the order you list the @var{infile} arguments.
241+
242+Mark the end of each input file with the preprocessor command
243+@code{.END}. @xref{Other Commands,, Miscellaneous commands}.
244+
245+@item -a
246+@itemx --alternate
247+Use alternative macro syntax. @xref{Alternate,, Alternate macro
248+syntax}, for a discussion of how this syntax differs from the default
249+@sc{gasp} syntax.
250+
251+@cindex comment character, changing
252+@cindex semicolon, as comment
253+@cindex exclamation mark, as comment
254+@cindex shriek, as comment
255+@cindex bang, as comment
256+@cindex @code{!} default comment char
257+@cindex @code{;} as comment char
258+@item -c '@var{char}'
259+@itemx --commentchar '@var{char}'
260+Use @var{char} as the comment character. The default comment character
261+is @samp{!}. For example, to use a semicolon as the comment character,
262+specify @w{@samp{-c ';'}} on the @sc{gasp} command line. Since
263+assembler command characters often have special significance to command
264+shells, it is a good idea to quote or escape @var{char} when you specify
265+a comment character.
266+
267+For the sake of simplicity, all examples in this manual use the default
268+comment character @samp{!}.
269+
270+@item -d
271+@itemx --debug
272+Show debugging statistics. In this version of @sc{gasp}, this option
273+produces statistics about the string buffers that @sc{gasp} allocates
274+internally. For each defined buffersize @var{s}, @sc{gasp} shows the
275+number of strings @var{n} that it allocated, with a line like this:
276+
277+@example
278+strings size @var{s} : @var{n}
279+@end example
280+
281+@noindent
282+@sc{gasp} displays these statistics on the standard error stream, when
283+done preprocessing.
284+
285+@item -h
286+@itemx --help
287+Display a summary of the @sc{gasp} command line options.
288+
289+@item -M
290+@itemx --mri
291+Use MRI compatibility mode. Using this option causes @sc{gasp} to
292+accept the syntax and pseudo-ops used by the Microtec Research
293+@code{ASM68K} assembler.
294+
295+@item -o @var{outfile}
296+@itemx --output @var{outfile}
297+Write the output in a file called @var{outfile}. If you do not use the
298+@samp{-o} option, @sc{gasp} writes its output on the standard output
299+stream.
300+
301+@item -p
302+@itemx --print
303+Print line numbers. @sc{gasp} obeys this option @emph{only} if you also
304+specify @samp{-s} to copy source lines to its output. With @samp{-s
305+-p}, @sc{gasp} displays the line number of each source line copied
306+(immediately after the comment character at the beginning of the line).
307+
308+@item -s
309+@itemx --copysource
310+Copy the source lines to the output file. Use this option
311+to see the effect of each preprocessor line on the @sc{gasp} output.
312+@sc{gasp} places a comment character (@samp{!} by default) at
313+the beginning of each source line it copies, so that you can use this
314+option and still assemble the result.
315+
316+@item -u
317+@itemx --unreasonable
318+Bypass ``unreasonable expansion'' limit. Since you can define @sc{gasp}
319+macros inside other macro definitions, the preprocessor normally
320+includes a sanity check. If your program requires more than 1,000
321+nested expansions, @sc{gasp} normally exits with an error message. Use
322+this option to turn off this check, allowing unlimited nested
323+expansions.
324+
325+@item -v
326+@itemx --version
327+Display the @sc{gasp} version number.
328+@end ftable
329+
330+@node Commands
331+@chapter Preprocessor Commands
332+
333+@sc{gasp} commands have a straightforward syntax that fits in well with
334+assembly conventions. In general, a command extends for a line, and may
335+have up to three fields: an optional label, the command itself, and
336+optional arguments to the command. You can write commands in upper or
337+lower case, though this manual shows them in upper case. @xref{Syntax
338+Details,, Details of the GASP syntax}, for more information.
339+
340+@menu
341+* Conditionals::
342+* Loops::
343+* Variables::
344+* Macros::
345+* Data::
346+* Listings::
347+* Other Commands::
348+* Syntax Details::
349+* Alternate::
350+@end menu
351+
352+@node Conditionals
353+@section Conditional assembly
354+
355+The conditional-assembly directives allow you to include or exclude
356+portions of an assembly depending on how a pair of expressions, or a
357+pair of strings, compare.
358+
359+The overall structure of conditionals is familiar from many other
360+contexts. @code{.AIF} marks the start of a conditional, and precedes
361+assembly for the case when the condition is true. An optional
362+@code{.AELSE} precedes assembly for the converse case, and an
363+@code{.AENDI} marks the end of the condition.
364+
365+@c FIXME! Why doesn't -u turn off this check?
366+You may nest conditionals up to a depth of 100; @sc{gasp} rejects
367+nesting beyond that, because it may indicate a bug in your macro
368+structure.
369+
370+@c FIXME! Why isn't there something like cpp's -D option? Conditionals
371+@c would be much more useful if there were.
372+Conditionals are primarily useful inside macro definitions, where you
373+often need different effects depending on argument values.
374+@xref{Macros,, Defining your own directives}, for details about defining
375+macros.
376+
377+@ftable @code
378+@item .AIF @var{expra} @var{cmp} @var{exprb}
379+@itemx .AIF "@var{stra}" @var{cmp} "@var{strb}"
380+
381+The governing condition goes on the same line as the @code{.AIF}
382+preprocessor command. You may compare either two strings, or two
383+expressions.
384+
385+When you compare strings, only two conditional @var{cmp} comparison
386+operators are available: @samp{EQ} (true if @var{stra} and @var{strb}
387+are identical), and @samp{NE} (the opposite).
388+
389+When you compare two expressions, @emph{both expressions must be
390+absolute} (@pxref{Expressions,, Arithmetic expressions in GASP}). You
391+can use these @var{cmp} comparison operators with expressions:
392+
393+@ftable @code
394+@item EQ
395+Are @var{expra} and @var{exprb} equal? (For strings, are @var{stra} and
396+@var{strb} identical?)
397+
398+@item NE
399+Are @var{expra} and @var{exprb} different? (For strings, are @var{stra}
400+and @var{strb} different?
401+
402+@item LT
403+Is @var{expra} less than @var{exprb}? (Not allowed for strings.)
404+
405+@item LE
406+Is @var{expra} less than or equal to @var{exprb}? (Not allowed for strings.)
407+
408+@item GT
409+Is @var{expra} greater than @var{exprb}? (Not allowed for strings.)
410+
411+@item GE
412+Is @var{expra} greater than or equal to @var{exprb}? (Not allowed for
413+strings.)
414+@end ftable
415+
416+@item .AELSE
417+Marks the start of assembly code to be included if the condition fails.
418+Optional, and only allowed within a conditional (between @code{.AIF} and
419+@code{.AENDI}).
420+
421+@item .AENDI
422+Marks the end of a conditional assembly.
423+@end ftable
424+
425+@node Loops
426+@section Repetitive sections of assembly
427+
428+Two preprocessor directives allow you to repeatedly issue copies of the
429+same block of assembly code.
430+
431+@ftable @code
432+@item .AREPEAT @var{aexp}
433+@itemx .AENDR
434+If you simply need to repeat the same block of assembly over and over a
435+fixed number of times, sandwich one instance of the repeated block
436+between @code{.AREPEAT} and @code{.AENDR}. Specify the number of
437+copies as @var{aexp} (which must be an absolute expression). For
438+example, this repeats two assembly statements three times in succession:
439+
440+@cartouche
441+@example
442+ .AREPEAT 3
443+ rotcl r2
444+ div1 r0,r1
445+ .AENDR
446+@end example
447+@end cartouche
448+
449+@item .AWHILE @var{expra} @var{cmp} @var{exprb}
450+@itemx .AENDW
451+@itemx .AWHILE @var{stra} @var{cmp} @var{strb}
452+@itemx .AENDW
453+To repeat a block of assembly depending on a conditional test, rather
454+than repeating it for a specific number of times, use @code{.AWHILE}.
455+@code{.AENDW} marks the end of the repeated block. The conditional
456+comparison works exactly the same way as for @code{.AIF}, with the same
457+comparison operators (@pxref{Conditionals,, Conditional assembly}).
458+
459+Since the terms of the comparison must be absolute expression,
460+@code{.AWHILE} is primarily useful within macros. @xref{Macros,,
461+Defining your own directives}.
462+@end ftable
463+
464+@cindex loops, breaking out of
465+@cindex breaking out of loops
466+You can use the @code{.EXITM} preprocessor directive to break out of
467+loops early (as well as to break out of macros). @xref{Macros,,
468+Defining your own directives}.
469+
470+@node Variables
471+@section Preprocessor variables
472+
473+You can use variables in @sc{gasp} to represent strings, registers, or
474+the results of expressions.
475+
476+You must distinguish two kinds of variables:
477+@enumerate
478+@item
479+Variables defined with @code{.EQU} or @code{.ASSIGN}. To evaluate this
480+kind of variable in your assembly output, simply mention its name. For
481+example, these two lines define and use a variable @samp{eg}:
482+
483+@cartouche
484+@example
485+eg .EQU FLIP-64
486+ @dots{}
487+ mov.l eg,r0
488+@end example
489+@end cartouche
490+
491+@emph{Do not use} this kind of variable in conditional expressions or
492+while loops; @sc{gasp} only evaluates these variables when writing
493+assembly output.
494+
495+@item
496+Variables for use during preprocessing. You can define these
497+with @code{.ASSIGNC} or @code{.ASSIGNA}. To evaluate this
498+kind of variable, write @samp{\&} before the variable name; for example,
499+
500+@cartouche
501+@example
502+opcit .ASSIGNA 47
503+ @dots{}
504+ .AWHILE \&opcit GT 0
505+ @dots{}
506+ .AENDW
507+@end example
508+@end cartouche
509+
510+@sc{gasp} treats macro arguments almost the same way, but to evaluate
511+them you use the prefix @samp{\} rather than @samp{\&}.
512+@xref{Macros,, Defining your own directives}.
513+@end enumerate
514+
515+@ftable @code
516+@item @var{pvar} .EQU @var{expr}
517+@c FIXME! Anything to beware of re GAS directive of same name?
518+Assign preprocessor variable @var{pvar} the value of the expression
519+@var{expr}. There are no restrictions on redefinition; use @samp{.EQU}
520+with the same @var{pvar} as often as you find it convenient.
521+
522+@item @var{pvar} .ASSIGN @var{expr}
523+Almost the same as @code{.EQU}, save that you may not redefine
524+@var{pvar} using @code{.ASSIGN} once it has a value.
525+@c FIXME!! Supposed to work this way, apparently, but on 9feb94 works
526+@c just like .EQU
527+
528+@item @var{pvar} .ASSIGNA @var{aexpr}
529+Define a variable with a numeric value, for use during preprocessing.
530+@var{aexpr} must be an absolute expression. You can redefine variables
531+with @code{.ASSIGNA} at any time.
532+
533+@item @var{pvar} .ASSIGNC "@var{str}"
534+Define a variable with a string value, for use during preprocessing.
535+You can redefine variables with @code{.ASSIGNC} at any time.
536+
537+@item @var{pvar} .REG (@var{register})
538+Use @code{.REG} to define a variable that represents a register. In
539+particular, @var{register} is @emph{not evaluated} as an expression.
540+You may use @code{.REG} at will to redefine register variables.
541+@end ftable
542+
543+All these directives accept the variable name in the ``label'' position,
544+that is at the left margin. You may specify a colon after the variable
545+name if you wish; the first example above could have started @samp{eg:}
546+with the same effect.
547+
548+@c pagebreak makes for better aesthetics---ensures macro and expansion together
549+@page
550+@node Macros
551+@section Defining your own directives
552+
553+The commands @code{.MACRO} and @code{.ENDM} allow you to define macros
554+that generate assembly output. You can use these macros with a syntax
555+similar to built-in @sc{gasp} or assembler directives. For example,
556+this definition specifies a macro @code{SUM} that adds together a range of
557+consecutive registers:
558+
559+@cartouche
560+@example
561+ .MACRO SUM FROM=0, TO=9
562+ ! \FROM \TO
563+ mov r\FROM,r10
564+COUNT .ASSIGNA \FROM+1
565+ .AWHILE \&COUNT LE \TO
566+ add r\&COUNT,r10
567+COUNT .ASSIGNA \&COUNT+1
568+ .AENDW
569+ .ENDM
570+@end example
571+@end cartouche
572+
573+@noindent
574+With that definition, @samp{SUM 0,5} generates this assembly output:
575+
576+@cartouche
577+@example
578+ ! 0 5
579+ mov r0,r10
580+ add r1,r10
581+ add r2,r10
582+ add r3,r10
583+ add r4,r10
584+ add r5,r10
585+@end example
586+@end cartouche
587+
588+@ftable @code
589+@item .MACRO @var{macname}
590+@itemx .MACRO @var{macname} @var{macargs} @dots{}
591+Begin the definition of a macro called @var{macname}. If your macro
592+definition requires arguments, specify their names after the macro name,
593+separated by commas or spaces. You can supply a default value for any
594+macro argument by following the name with @samp{=@var{deflt}}. For
595+example, these are all valid @code{.MACRO} statements:
596+
597+@table @code
598+@item .MACRO COMM
599+Begin the definition of a macro called @code{COMM}, which takes no
600+arguments.
601+
602+@item .MACRO PLUS1 P, P1
603+@itemx .MACRO PLUS1 P P1
604+Either statement begins the definition of a macro called @code{PLUS1},
605+which takes two arguments; within the macro definition, write
606+@samp{\P} or @samp{\P1} to evaluate the arguments.
607+
608+@item .MACRO RESERVE_STR P1=0 P2
609+Begin the definition of a macro called @code{RESERVE_STR}, with two
610+arguments. The first argument has a default value, but not the second.
611+After the definition is complete, you can call the macro either as
612+@samp{RESERVE_STR @var{a},@var{b}} (with @samp{\P1} evaluating to
613+@var{a} and @samp{\P2} evaluating to @var{b}), or as @samp{RESERVE_STR
614+,@var{b}} (with @samp{\P1} evaluating as the default, in this case
615+@samp{0}, and @samp{\P2} evaluating to @var{b}).
616+@end table
617+
618+When you call a macro, you can specify the argument values either by
619+position, or by keyword. For example, @samp{SUM 9,17} is equivalent to
620+@samp{SUM TO=17, FROM=9}. Macro arguments are preprocessor variables
621+similar to the variables you define with @samp{.ASSIGNA} or
622+@samp{.ASSIGNC}; in particular, you can use them in conditionals or for
623+loop control. (The only difference is the prefix you write to evaluate
624+the variable: for a macro argument, write @samp{\@var{argname}}, but for
625+a preprocessor variable, write @samp{\&@var{varname}}.)
626+
627+@item @var{name} .MACRO
628+@itemx @var{name} .MACRO ( @var{macargs} @dots{} )
629+@c FIXME check: I think no error _and_ no args recognized if I use form
630+@c NAME .MACRO ARG ARG
631+An alternative form of introducing a macro definition: specify the macro
632+name in the label position, and the arguments (if any) between
633+parentheses after the name. Defaulting rules and usage work the same
634+way as for the other macro definition syntax.
635+
636+@item .ENDM
637+Mark the end of a macro definition.
638+
639+@item .EXITM
640+Exit early from the current macro definition, @code{.AREPEAT} loop, or
641+@code{.AWHILE} loop.
642+
643+@cindex number of macros executed
644+@cindex macros, count executed
645+@item \@@
646+@sc{gasp} maintains a counter of how many macros it has
647+executed in this pseudo-variable; you can copy that number to your
648+output with @samp{\@@}, but @emph{only within a macro definition}.
649+
650+@item LOCAL @var{name} [ , @dots{} ]
651+@emph{Warning: @code{LOCAL} is only available if you select ``alternate
652+macro syntax'' with @samp{-a} or @samp{--alternate}.} @xref{Alternate,,
653+Alternate macro syntax}.
654+
655+Generate a string replacement for each of the @var{name} arguments, and
656+replace any instances of @var{name} in each macro expansion. The
657+replacement string is unique in the assembly, and different for each
658+separate macro expansion. @code{LOCAL} allows you to write macros that
659+define symbols, without fear of conflict between separate macro expansions.
660+@end ftable
661+
662+@node Data
663+@section Data output
664+
665+In assembly code, you often need to specify working areas of memory;
666+depending on the application, you may want to initialize such memory or
667+not. @sc{gasp} provides preprocessor directives to help you avoid
668+repetitive coding for both purposes.
669+
670+You can use labels as usual to mark the data areas.
671+
672+@menu
673+* Initialized::
674+* Uninitialized::
675+@end menu
676+
677+@node Initialized
678+@subsection Initialized data
679+
680+These are the @sc{gasp} directives for initialized data, and the standard
681+@sc{gnu} assembler directives they expand to:
682+
683+@ftable @code
684+@item .DATA @var{expr}, @var{expr}, @dots{}
685+@itemx .DATA.B @var{expr}, @var{expr}, @dots{}
686+@itemx .DATA.W @var{expr}, @var{expr}, @dots{}
687+@itemx .DATA.L @var{expr}, @var{expr}, @dots{}
688+Evaluate arithmetic expressions @var{expr}, and emit the corresponding
689+@code{as} directive (labelled with @var{lab}). The unqualified
690+@code{.DATA} emits @samp{.long}; @code{.DATA.B} emits @samp{.byte};
691+@code{.DATA.W} emits @samp{.short}; and @code{.DATA.L} emits
692+@samp{.long}.
693+
694+For example, @samp{foo .DATA 1,2,3} emits @samp{foo: .long 1,2,3}.
695+
696+@item .DATAB @var{repeat}, @var{expr}
697+@itemx .DATAB.B @var{repeat}, @var{expr}
698+@itemx .DATAB.W @var{repeat}, @var{expr}
699+@itemx .DATAB.L @var{repeat}, @var{expr}
700+@c FIXME! Looks like gasp accepts and ignores args after 2nd.
701+Make @code{as} emit @var{repeat} copies of the value of the expression
702+@var{expr} (using the @code{as} directive @code{.fill}).
703+@samp{.DATAB.B} repeats one-byte values; @samp{.DATAB.W} repeats
704+two-byte values; and @samp{.DATAB.L} repeats four-byte values.
705+@samp{.DATAB} without a suffix repeats four-byte values, just like
706+@samp{.DATAB.L}.
707+
708+@c FIXME! Allowing zero might be useful for edge conditions in macros.
709+@var{repeat} must be an absolute expression with a positive value.
710+
711+@item .SDATA "@var{str}" @dots{}
712+String data. Emits a concatenation of bytes, precisely as you specify
713+them (in particular, @emph{nothing is added to mark the end} of the
714+string). @xref{Constants,, String and numeric constants}, for details
715+about how to write strings. @code{.SDATA} concatenates multiple
716+arguments, making it easy to switch between string representations. You
717+can use commas to separate the individual arguments for clarity, if you
718+choose.
719+
720+@item .SDATAB @var{repeat}, "@var{str}" @dots{}
721+Repeated string data. The first argument specifies how many copies of
722+the string to emit; the remaining arguments specify the string, in the
723+same way as the arguments to @code{.SDATA}.
724+
725+@item .SDATAZ "@var{str}" @dots{}
726+Zero-terminated string data. Just like @code{.SDATA}, except that
727+@code{.SDATAZ} writes a zero byte at the end of the string.
728+
729+@item .SDATAC "@var{str}" @dots{}
730+Count-prefixed string data. Just like @code{.SDATA}, except that
731+@sc{gasp} precedes the string with a leading one-byte count. For
732+example, @samp{.SDATAC "HI"} generates @samp{.byte 2,72,73}. Since the
733+count field is only one byte, you can only use @code{.SDATAC} for
734+strings less than 256 bytes in length.
735+@end ftable
736+
737+@node Uninitialized
738+@subsection Uninitialized data
739+
740+@c FIXME! .space different on some platforms, notably HPPA. Config?
741+Use the @code{.RES}, @code{.SRES}, @code{.SRESC}, and @code{.SRESZ}
742+directives to reserve memory and leave it uninitialized. @sc{gasp}
743+resolves these directives to appropriate calls of the @sc{gnu}
744+@code{as} @code{.space} directive.
745+
746+@ftable @code
747+@item .RES @var{count}
748+@itemx .RES.B @var{count}
749+@itemx .RES.W @var{count}
750+@itemx .RES.L @var{count}
751+Reserve room for @var{count} uninitialized elements of data. The
752+suffix specifies the size of each element: @code{.RES.B} reserves
753+@var{count} bytes, @code{.RES.W} reserves @var{count} pairs of bytes,
754+and @code{.RES.L} reserves @var{count} quartets. @code{.RES} without a
755+suffix is equivalent to @code{.RES.L}.
756+
757+@item .SRES @var{count}
758+@itemx .SRES.B @var{count}
759+@itemx .SRES.W @var{count}
760+@itemx .SRES.L @var{count}
761+@c FIXME! This is boring. Shouldn't it at least have a different
762+@c default size? (e.g. the "S" suggests "string", for which .B
763+@c would be more appropriate)
764+@code{.SRES} is a synonym for @samp{.RES}.
765+
766+@item .SRESC @var{count}
767+@itemx .SRESC.B @var{count}
768+@itemx .SRESC.W @var{count}
769+@itemx .SRESC.L @var{count}
770+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
771+
772+@item .SRESZ @var{count}
773+@itemx .SRESZ.B @var{count}
774+@itemx .SRESZ.W @var{count}
775+@itemx .SRESZ.L @var{count}
776+Like @code{.SRES}, but reserves space for @code{@var{count}+1} elements.
777+@end ftable
778+
779+@node Listings
780+@section Assembly listing control
781+
782+The @sc{gasp} listing-control directives correspond to
783+related @sc{gnu} @code{as} directives.
784+
785+@ftable @code
786+@item .PRINT LIST
787+@itemx .PRINT NOLIST
788+Print control. This directive emits the @sc{gnu} @code{as} directive
789+@code{.list} or @code{.nolist}, according to its argument. @xref{List,,
790+@code{.list}, as.info, Using as}, for details on how these directives
791+interact.
792+
793+@item .FORM LIN=@var{ln}
794+@itemx .FORM COL=@var{cols}
795+@itemx .FORM LIN=@var{ln} COL=@var{cols}
796+Specify the page size for assembly listings: @var{ln} represents the
797+number of lines, and @var{cols} the number of columns. You may specify
798+either page dimension independently, or both together. If you do not
799+specify the number of lines, @sc{gasp} assumes 60 lines; if you do not
800+specify the number of columns, @sc{gasp} assumes 132 columns.
801+(Any values you may have specified in previous instances of @code{.FORM}
802+do @emph{not} carry over as defaults.) Emits the @code{.psize}
803+assembler directive.
804+
805+@item .HEADING @var{string}
806+Specify @var{string} as the title of your assembly listings. Emits
807+@samp{.title "@var{string}"}.
808+
809+@item .PAGE
810+Force a new page in assembly listings. Emits @samp{.eject}.
811+@end ftable
812+
813+@node Other Commands
814+@section Miscellaneous commands
815+
816+@ftable @code
817+@item .ALTERNATE
818+Use the alternate macro syntax henceforth in the assembly.
819+@xref{Alternate,, Alternate macro syntax}.
820+
821+@item .ORG
822+@c FIXME! This is very strange, since _GAS_ understands .org
823+This command is recognized, but not yet implemented. @sc{gasp}
824+generates an error message for programs that use @code{.ORG}.
825+
826+@item .RADIX @var{s}
827+@c FIXME no test cases in testsuite/gasp
828+@sc{gasp} understands numbers in any of base two, eight, ten, or
829+sixteen. You can encode the base explicitly in any numeric constant
830+(@pxref{Constants,, String and numeric constants}). If you write
831+numbers without an explicit indication of the base, the most recent
832+@samp{.RADIX @var{s}} command determines how they are interpreted.
833+@var{s} is a single letter, one of the following:
834+
835+@table @code
836+@item .RADIX B
837+Base 2.
838+
839+@item .RADIX Q
840+Base 8.
841+
842+@item .RADIX D
843+Base 10. This is the original default radix.
844+
845+@item .RADIX H
846+Base 16.
847+@end table
848+
849+You may specify the argument @var{s} in lower case (any of @samp{bqdh})
850+with the same effects.
851+
852+@item .EXPORT @var{name}
853+@itemx .GLOBAL @var{name}
854+@c FIXME! No test cases in testsuite/gasp
855+Declare @var{name} global (emits @samp{.global @var{name}}). The two
856+directives are synonymous.
857+
858+@item .PROGRAM
859+No effect: @sc{gasp} accepts this directive, and silently ignores it.
860+
861+@item .END
862+Mark end of each preprocessor file. @sc{gasp} issues a warning if it
863+reaches end of file without seeing this command.
864+
865+@item .INCLUDE "@var{str}"
866+Preprocess the file named by @var{str}, as if its contents appeared
867+where the @code{.INCLUDE} directive does. @sc{gasp} imposes a maximum
868+limit of 30 stacked include files, as a sanity check.
869+@c FIXME! Why is include depth not affected by -u?
870+
871+@item .ALIGN @var{size}
872+@c FIXME! Why is this not utterly pointless?
873+Evaluate the absolute expression @var{size}, and emit the assembly
874+instruction @samp{.align @var{size}} using the result.
875+@end ftable
876+
877+@node Syntax Details
878+@section Details of the GASP syntax
879+
880+Since @sc{gasp} is meant to work with assembly code, its statement
881+syntax has no surprises for the assembly programmer.
882+
883+@cindex whitespace
884+@emph{Whitespace} (blanks or tabs; @emph{not} newline) is partially
885+significant, in that it delimits up to three fields in a line. The
886+amount of whitespace does not matter; you may line up fields in separate
887+lines if you wish, but @sc{gasp} does not require that.
888+
889+@cindex fields of @sc{gasp} source line
890+@cindex label field
891+The @emph{first field}, an optional @dfn{label}, must be flush left in a
892+line (with no leading whitespace) if it appears at all. You may use a
893+colon after the label if you wish; @sc{gasp} neither requires the colon
894+nor objects to it (but will not include it as part of the label name).
895+
896+@cindex directive field
897+The @emph{second field}, which must appear after some whitespace,
898+contains a @sc{gasp} or assembly @dfn{directive}.
899+
900+@cindex argument fields
901+Any @emph{further fields} on a line are @dfn{arguments} to the
902+directive; you can separate them from one another using either commas or
903+whitespace.
904+
905+@menu
906+* Markers::
907+* Constants::
908+* Symbols::
909+* Expressions::
910+* String Builtins::
911+@end menu
912+
913+@node Markers
914+@subsection Special syntactic markers
915+
916+@sc{gasp} recognizes a few special markers: to delimit comments, to
917+continue a statement on the next line, to separate symbols from other
918+characters, and to copy text to the output literally. (One other
919+special marker, @samp{\@@}, works only within macro definitions;
920+@pxref{Macros,, Defining your own directives}.)
921+
922+@cindex comments
923+The trailing part of any @sc{gasp} source line may be a @dfn{comment}.
924+A comment begins with the first unquoted comment character (@samp{!} by
925+default), or an escaped or doubled comment character (@samp{\!} or
926+@samp{!!} by default), and extends to the end of a line. You can
927+specify what comment character to use with the @samp{-c} option
928+(@pxref{Invoking GASP,, Command Line Options}). The two kinds of
929+comment markers lead to slightly different treatment:
930+
931+@table @code
932+@item !
933+A single, un-escaped comment character generates an assembly comment in
934+the @sc{gasp} output. @sc{gasp} evaluates any preprocessor variables
935+(macro arguments, or variables defined with @code{.ASSIGNA} or
936+@code{.ASSIGNC}) present. For example, a macro that begins like this
937+
938+@example
939+ .MACRO SUM FROM=0, TO=9
940+ ! \FROM \TO
941+@end example
942+
943+@noindent
944+issues as the first line of output a comment that records the
945+values you used to call the macro.
946+
947+@c comments, preprocessor-only
948+@c preprocessor-only comments
949+@c GASP-only comments
950+@item \!
951+@itemx !!
952+Either an escaped comment character, or a double comment character,
953+marks a @sc{gasp} source comment. @sc{gasp} does not copy such comments
954+to the assembly output.
955+@end table
956+
957+@cindex continuation character
958+@kindex +
959+To @emph{continue a statement} on the next line of the file, begin the
960+second line with the character @samp{+}.
961+
962+@cindex literal copy to output
963+@cindex copying literally to output
964+@cindex preprocessing, avoiding
965+@cindex avoiding preprocessing
966+Occasionally you may want to prevent @sc{gasp} from preprocessing some
967+particular bit of text. To @emph{copy literally} from the @sc{gasp}
968+source to its output, place @samp{\(} before the string to copy, and
969+@samp{)} at the end. For example, write @samp{\(\!)} if you need the
970+characters @samp{\!} in your assembly output.
971+
972+@cindex symbol separator
973+@cindex text, separating from symbols
974+@cindex symbols, separating from text
975+To @emph{separate a preprocessor variable} from text to appear
976+immediately after its value, write a single quote (@code{'}). For
977+example, @samp{.SDATA "\P'1"} writes a string built by concatenating the
978+value of @code{P} and the digit @samp{1}. (You cannot achieve this by
979+writing just @samp{\P1}, since @samp{P1} is itself a valid name for a
980+preprocessor variable.)
981+
982+@node Constants
983+@subsection String and numeric constants
984+
985+There are two ways of writing @dfn{string constants} in @sc{gasp}: as
986+literal text, and by numeric byte value. Specify a string literal
987+between double quotes (@code{"@var{str}"}). Specify an individual
988+numeric byte value as an absolute expression between angle brackets
989+(@code{<@var{expr}>}. Directives that output strings allow you to
990+specify any number of either kind of value, in whatever order is
991+convenient, and concatenate the result. (Alternate syntax mode
992+introduces a number of alternative string notations; @pxref{Alternate,,
993+Alternate macro syntax}.)
994+
995+@c Details of numeric notation, e.g. base prefixes
996+You can write @dfn{numeric constants} either in a specific base, or in
997+whatever base is currently selected (either 10, or selected by the most
998+recent @code{.RADIX}).
999+
1000+To write a number in a @emph{specific base}, use the pattern
1001+@code{@var{s}'@var{ddd}}: a base specifier character @var{s}, followed
1002+by a single quote followed by digits @var{ddd}. The base specifier
1003+character matches those you can specify with @code{.RADIX}: @samp{B} for
1004+base 2, @samp{Q} for base 8, @samp{D} for base 10, and @samp{H} for base
1005+16. (You can write this character in lower case if you prefer.)
1006+
1007+You can write floating point constants using the same syntax recognised
1008+by GAS @ref{Flonums,,Flonums,as,The GNU Assembler.}. A constraint is
1009+that these constants will be interpreted as decimal values irrespective
1010+of the currently selected base.
1011+
1012+@c FIXME! What are rules for recognizing number in deflt base? Whatever
1013+@c is left over after parsing other things??
1014+
1015+@node Symbols
1016+@subsection Symbols
1017+
1018+@sc{gasp} recognizes symbol names that start with any alphabetic character,
1019+@samp{_}, or @samp{$}, and continue with any of the same characters or
1020+with digits. Label names follow the same rules.
1021+
1022+@node Expressions
1023+@subsection Arithmetic expressions in GASP
1024+
1025+@cindex absolute expressions
1026+@cindex relocatable expressions
1027+There are two kinds of expressions, depending on their result:
1028+@dfn{absolute} expressions, which resolve to a constant (that is, they
1029+do not involve any values unknown to @sc{gasp}), and @dfn{relocatable}
1030+expressions, which must reduce to the form
1031+
1032+@example
1033+@var{addsym}+@var{const}-@var{subsym}
1034+@end example
1035+
1036+@noindent
1037+where @var{addsym} and @var{subsym} are assembly symbols of unknown
1038+value, and @var{const} is a constant.
1039+
1040+Arithmetic for @sc{gasp} expressions follows very similar rules to C.
1041+You can use parentheses to change precedence; otherwise, arithmetic
1042+primitives have decreasing precedence in the order of the following
1043+list.
1044+
1045+@enumerate
1046+@item
1047+Single-argument @code{+} (identity), @code{-} (arithmetic opposite), or
1048+@code{~} (bitwise negation). @emph{The argument must be an absolute
1049+expression.}
1050+
1051+@item
1052+@code{*} (multiplication) and @code{/} (division). @emph{Both arguments
1053+must be absolute expressions.}
1054+
1055+@item
1056+@code{+} (addition) and @code{-} (subtraction). @emph{At least one argument
1057+must be absolute.}
1058+@c FIXME! Actually, subtraction doesn't check for this.
1059+
1060+@item
1061+@code{&} (bitwise and). @emph{Both arguments must be absolute.}
1062+
1063+@item
1064+@c FIXME! I agree ~ is a better notation than ^ for xor, but is the
1065+@c improvement worth differing from C?
1066+@code{|} (bitwise or) and @code{~} (bitwise exclusive or; @code{^} in
1067+C). @emph{Both arguments must be absolute.}
1068+@end enumerate
1069+
1070+@node String Builtins
1071+@subsection String primitives
1072+
1073+You can use these primitives to manipulate strings (in the argument
1074+field of @sc{gasp} statements):
1075+
1076+@ftable @code
1077+@item .LEN("@var{str}")
1078+Calculate the length of string @code{"@var{str}"}, as an absolute
1079+expression. For example, @samp{.RES.B .LEN("sample")} reserves six
1080+bytes of memory.
1081+
1082+@item .INSTR("@var{string}", "@var{seg}", @var{ix})
1083+Search for the first occurrence of @var{seg} after position @var{ix} of
1084+@var{string}. For example, @samp{.INSTR("ABCDEFG", "CDE", 0)} evaluates
1085+to the absolute result @code{2}.
1086+
1087+The result is @code{-1} if @var{seg} does not occur in @var{string}
1088+after position @var{ix}.
1089+
1090+@item .SUBSTR("@var{string}",@var{start},@var{len})
1091+The substring of @var{string} beginning at byte number @var{start} and
1092+extending for @var{len} bytes.
1093+@end ftable
1094+
1095+@node Alternate
1096+@section Alternate macro syntax
1097+
1098+If you specify @samp{-a} or @samp{--alternate} on the @sc{gasp} command
1099+line, the preprocessor uses somewhat different syntax. This syntax is
1100+reminiscent of the syntax of Phar Lap macro assembler, but it
1101+is @emph{not} meant to be a full emulation of Phar Lap or similar
1102+assemblers. In particular, @sc{gasp} does not support directives such
1103+as @code{DB} and @code{IRP}, even in alternate syntax mode.
1104+
1105+In particular, @samp{-a} (or @samp{--alternate}) elicits these
1106+differences:
1107+
1108+@table @emph
1109+@item Preprocessor directives
1110+You can use @sc{gasp} preprocessor directives without a leading @samp{.}
1111+dot. For example, you can write @samp{SDATA} with the same effect as
1112+@samp{.SDATA}.
1113+
1114+@item LOCAL
1115+One additional directive, @code{LOCAL}, is available. @xref{Macros,,
1116+Defining your own directives}, for an explanation of how to use
1117+@code{LOCAL}.
1118+
1119+@need 2000
1120+@item String delimiters
1121+You can write strings delimited in these other ways besides
1122+@code{"@var{string}"}:
1123+
1124+@table @code
1125+@item '@var{string}'
1126+You can delimit strings with single-quote charaters.
1127+
1128+@item <@var{string}>
1129+You can delimit strings with matching angle brackets.
1130+@end table
1131+
1132+@item single-character string escape
1133+To include any single character literally in a string (even if the
1134+character would otherwise have some special meaning), you can prefix the
1135+character with @samp{!} (an exclamation mark). For example, you can
1136+write @samp{<4.3 !> 5.4!!>} to get the literal text @samp{4.3 > 5.4!}.
1137+
1138+@item Expression results as strings
1139+You can write @samp{%@var{expr}} to evaluate the expression @var{expr}
1140+and use the result as a string.
1141+@end table
1142+
1143+@node GNU Free Documentation License
1144+@chapter GNU Free Documentation License
1145+
1146+ GNU Free Documentation License
1147+
1148+ Version 1.1, March 2000
1149+
1150+ Copyright (C) 2000 Free Software Foundation, Inc.
1151+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1152+
1153+ Everyone is permitted to copy and distribute verbatim copies
1154+ of this license document, but changing it is not allowed.
1155+
1156+
1157+0. PREAMBLE
1158+
1159+The purpose of this License is to make a manual, textbook, or other
1160+written document "free" in the sense of freedom: to assure everyone
1161+the effective freedom to copy and redistribute it, with or without
1162+modifying it, either commercially or noncommercially. Secondarily,
1163+this License preserves for the author and publisher a way to get
1164+credit for their work, while not being considered responsible for
1165+modifications made by others.
1166+
1167+This License is a kind of "copyleft", which means that derivative
1168+works of the document must themselves be free in the same sense. It
1169+complements the GNU General Public License, which is a copyleft
1170+license designed for free software.
1171+
1172+We have designed this License in order to use it for manuals for free
1173+software, because free software needs free documentation: a free
1174+program should come with manuals providing the same freedoms that the
1175+software does. But this License is not limited to software manuals;
1176+it can be used for any textual work, regardless of subject matter or
1177+whether it is published as a printed book. We recommend this License
1178+principally for works whose purpose is instruction or reference.
1179+
1180+
1181+1. APPLICABILITY AND DEFINITIONS
1182+
1183+This License applies to any manual or other work that contains a
1184+notice placed by the copyright holder saying it can be distributed
1185+under the terms of this License. The "Document", below, refers to any
1186+such manual or work. Any member of the public is a licensee, and is
1187+addressed as "you".
1188+
1189+A "Modified Version" of the Document means any work containing the
1190+Document or a portion of it, either copied verbatim, or with
1191+modifications and/or translated into another language.
1192+
1193+A "Secondary Section" is a named appendix or a front-matter section of
1194+the Document that deals exclusively with the relationship of the
1195+publishers or authors of the Document to the Document's overall subject
1196+(or to related matters) and contains nothing that could fall directly
1197+within that overall subject. (For example, if the Document is in part a
1198+textbook of mathematics, a Secondary Section may not explain any
1199+mathematics.) The relationship could be a matter of historical
1200+connection with the subject or with related matters, or of legal,
1201+commercial, philosophical, ethical or political position regarding
1202+them.
1203+
1204+The "Invariant Sections" are certain Secondary Sections whose titles
1205+are designated, as being those of Invariant Sections, in the notice
1206+that says that the Document is released under this License.
1207+
1208+The "Cover Texts" are certain short passages of text that are listed,
1209+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
1210+the Document is released under this License.
1211+
1212+A "Transparent" copy of the Document means a machine-readable copy,
1213+represented in a format whose specification is available to the
1214+general public, whose contents can be viewed and edited directly and
1215+straightforwardly with generic text editors or (for images composed of
1216+pixels) generic paint programs or (for drawings) some widely available
1217+drawing editor, and that is suitable for input to text formatters or
1218+for automatic translation to a variety of formats suitable for input
1219+to text formatters. A copy made in an otherwise Transparent file
1220+format whose markup has been designed to thwart or discourage
1221+subsequent modification by readers is not Transparent. A copy that is
1222+not "Transparent" is called "Opaque".
1223+
1224+Examples of suitable formats for Transparent copies include plain
1225+ASCII without markup, Texinfo input format, LaTeX input format, SGML
1226+or XML using a publicly available DTD, and standard-conforming simple
1227+HTML designed for human modification. Opaque formats include
1228+PostScript, PDF, proprietary formats that can be read and edited only
1229+by proprietary word processors, SGML or XML for which the DTD and/or
1230+processing tools are not generally available, and the
1231+machine-generated HTML produced by some word processors for output
1232+purposes only.
1233+
1234+The "Title Page" means, for a printed book, the title page itself,
1235+plus such following pages as are needed to hold, legibly, the material
1236+this License requires to appear in the title page. For works in
1237+formats which do not have any title page as such, "Title Page" means
1238+the text near the most prominent appearance of the work's title,
1239+preceding the beginning of the body of the text.
1240+
1241+
1242+2. VERBATIM COPYING
1243+
1244+You may copy and distribute the Document in any medium, either
1245+commercially or noncommercially, provided that this License, the
1246+copyright notices, and the license notice saying this License applies
1247+to the Document are reproduced in all copies, and that you add no other
1248+conditions whatsoever to those of this License. You may not use
1249+technical measures to obstruct or control the reading or further
1250+copying of the copies you make or distribute. However, you may accept
1251+compensation in exchange for copies. If you distribute a large enough
1252+number of copies you must also follow the conditions in section 3.
1253+
1254+You may also lend copies, under the same conditions stated above, and
1255+you may publicly display copies.
1256+
1257+
1258+3. COPYING IN QUANTITY
1259+
1260+If you publish printed copies of the Document numbering more than 100,
1261+and the Document's license notice requires Cover Texts, you must enclose
1262+the copies in covers that carry, clearly and legibly, all these Cover
1263+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
1264+the back cover. Both covers must also clearly and legibly identify
1265+you as the publisher of these copies. The front cover must present
1266+the full title with all words of the title equally prominent and
1267+visible. You may add other material on the covers in addition.
1268+Copying with changes limited to the covers, as long as they preserve
1269+the title of the Document and satisfy these conditions, can be treated
1270+as verbatim copying in other respects.
1271+
1272+If the required texts for either cover are too voluminous to fit
1273+legibly, you should put the first ones listed (as many as fit
1274+reasonably) on the actual cover, and continue the rest onto adjacent
1275+pages.
1276+
1277+If you publish or distribute Opaque copies of the Document numbering
1278+more than 100, you must either include a machine-readable Transparent
1279+copy along with each Opaque copy, or state in or with each Opaque copy
1280+a publicly-accessible computer-network location containing a complete
1281+Transparent copy of the Document, free of added material, which the
1282+general network-using public has access to download anonymously at no
1283+charge using public-standard network protocols. If you use the latter
1284+option, you must take reasonably prudent steps, when you begin
1285+distribution of Opaque copies in quantity, to ensure that this
1286+Transparent copy will remain thus accessible at the stated location
1287+until at least one year after the last time you distribute an Opaque
1288+copy (directly or through your agents or retailers) of that edition to
1289+the public.
1290+
1291+It is requested, but not required, that you contact the authors of the
1292+Document well before redistributing any large number of copies, to give
1293+them a chance to provide you with an updated version of the Document.
1294+
1295+
1296+4. MODIFICATIONS
1297+
1298+You may copy and distribute a Modified Version of the Document under
1299+the conditions of sections 2 and 3 above, provided that you release
1300+the Modified Version under precisely this License, with the Modified
1301+Version filling the role of the Document, thus licensing distribution
1302+and modification of the Modified Version to whoever possesses a copy
1303+of it. In addition, you must do these things in the Modified Version:
1304+
1305+A. Use in the Title Page (and on the covers, if any) a title distinct
1306+ from that of the Document, and from those of previous versions
1307+ (which should, if there were any, be listed in the History section
1308+ of the Document). You may use the same title as a previous version
1309+ if the original publisher of that version gives permission.
1310+B. List on the Title Page, as authors, one or more persons or entities
1311+ responsible for authorship of the modifications in the Modified
1312+ Version, together with at least five of the principal authors of the
1313+ Document (all of its principal authors, if it has less than five).
1314+C. State on the Title page the name of the publisher of the
1315+ Modified Version, as the publisher.
1316+D. Preserve all the copyright notices of the Document.
1317+E. Add an appropriate copyright notice for your modifications
1318+ adjacent to the other copyright notices.
1319+F. Include, immediately after the copyright notices, a license notice
1320+ giving the public permission to use the Modified Version under the
1321+ terms of this License, in the form shown in the Addendum below.
1322+G. Preserve in that license notice the full lists of Invariant Sections
1323+ and required Cover Texts given in the Document's license notice.
1324+H. Include an unaltered copy of this License.
1325+I. Preserve the section entitled "History", and its title, and add to
1326+ it an item stating at least the title, year, new authors, and
1327+ publisher of the Modified Version as given on the Title Page. If
1328+ there is no section entitled "History" in the Document, create one
1329+ stating the title, year, authors, and publisher of the Document as
1330+ given on its Title Page, then add an item describing the Modified
1331+ Version as stated in the previous sentence.
1332+J. Preserve the network location, if any, given in the Document for
1333+ public access to a Transparent copy of the Document, and likewise
1334+ the network locations given in the Document for previous versions
1335+ it was based on. These may be placed in the "History" section.
1336+ You may omit a network location for a work that was published at
1337+ least four years before the Document itself, or if the original
1338+ publisher of the version it refers to gives permission.
1339+K. In any section entitled "Acknowledgements" or "Dedications",
1340+ preserve the section's title, and preserve in the section all the
1341+ substance and tone of each of the contributor acknowledgements
1342+ and/or dedications given therein.
1343+L. Preserve all the Invariant Sections of the Document,
1344+ unaltered in their text and in their titles. Section numbers
1345+ or the equivalent are not considered part of the section titles.
1346+M. Delete any section entitled "Endorsements". Such a section
1347+ may not be included in the Modified Version.
1348+N. Do not retitle any existing section as "Endorsements"
1349+ or to conflict in title with any Invariant Section.
1350+
1351+If the Modified Version includes new front-matter sections or
1352+appendices that qualify as Secondary Sections and contain no material
1353+copied from the Document, you may at your option designate some or all
1354+of these sections as invariant. To do this, add their titles to the
1355+list of Invariant Sections in the Modified Version's license notice.
1356+These titles must be distinct from any other section titles.
1357+
1358+You may add a section entitled "Endorsements", provided it contains
1359+nothing but endorsements of your Modified Version by various
1360+parties--for example, statements of peer review or that the text has
1361+been approved by an organization as the authoritative definition of a
1362+standard.
1363+
1364+You may add a passage of up to five words as a Front-Cover Text, and a
1365+passage of up to 25 words as a Back-Cover Text, to the end of the list
1366+of Cover Texts in the Modified Version. Only one passage of
1367+Front-Cover Text and one of Back-Cover Text may be added by (or
1368+through arrangements made by) any one entity. If the Document already
1369+includes a cover text for the same cover, previously added by you or
1370+by arrangement made by the same entity you are acting on behalf of,
1371+you may not add another; but you may replace the old one, on explicit
1372+permission from the previous publisher that added the old one.
1373+
1374+The author(s) and publisher(s) of the Document do not by this License
1375+give permission to use their names for publicity for or to assert or
1376+imply endorsement of any Modified Version.
1377+
1378+
1379+5. COMBINING DOCUMENTS
1380+
1381+You may combine the Document with other documents released under this
1382+License, under the terms defined in section 4 above for modified
1383+versions, provided that you include in the combination all of the
1384+Invariant Sections of all of the original documents, unmodified, and
1385+list them all as Invariant Sections of your combined work in its
1386+license notice.
1387+
1388+The combined work need only contain one copy of this License, and
1389+multiple identical Invariant Sections may be replaced with a single
1390+copy. If there are multiple Invariant Sections with the same name but
1391+different contents, make the title of each such section unique by
1392+adding at the end of it, in parentheses, the name of the original
1393+author or publisher of that section if known, or else a unique number.
1394+Make the same adjustment to the section titles in the list of
1395+Invariant Sections in the license notice of the combined work.
1396+
1397+In the combination, you must combine any sections entitled "History"
1398+in the various original documents, forming one section entitled
1399+"History"; likewise combine any sections entitled "Acknowledgements",
1400+and any sections entitled "Dedications". You must delete all sections
1401+entitled "Endorsements."
1402+
1403+
1404+6. COLLECTIONS OF DOCUMENTS
1405+
1406+You may make a collection consisting of the Document and other documents
1407+released under this License, and replace the individual copies of this
1408+License in the various documents with a single copy that is included in
1409+the collection, provided that you follow the rules of this License for
1410+verbatim copying of each of the documents in all other respects.
1411+
1412+You may extract a single document from such a collection, and distribute
1413+it individually under this License, provided you insert a copy of this
1414+License into the extracted document, and follow this License in all
1415+other respects regarding verbatim copying of that document.
1416+
1417+
1418+7. AGGREGATION WITH INDEPENDENT WORKS
1419+
1420+A compilation of the Document or its derivatives with other separate
1421+and independent documents or works, in or on a volume of a storage or
1422+distribution medium, does not as a whole count as a Modified Version
1423+of the Document, provided no compilation copyright is claimed for the
1424+compilation. Such a compilation is called an "aggregate", and this
1425+License does not apply to the other self-contained works thus compiled
1426+with the Document, on account of their being thus compiled, if they
1427+are not themselves derivative works of the Document.
1428+
1429+If the Cover Text requirement of section 3 is applicable to these
1430+copies of the Document, then if the Document is less than one quarter
1431+of the entire aggregate, the Document's Cover Texts may be placed on
1432+covers that surround only the Document within the aggregate.
1433+Otherwise they must appear on covers around the whole aggregate.
1434+
1435+
1436+8. TRANSLATION
1437+
1438+Translation is considered a kind of modification, so you may
1439+distribute translations of the Document under the terms of section 4.
1440+Replacing Invariant Sections with translations requires special
1441+permission from their copyright holders, but you may include
1442+translations of some or all Invariant Sections in addition to the
1443+original versions of these Invariant Sections. You may include a
1444+translation of this License provided that you also include the
1445+original English version of this License. In case of a disagreement
1446+between the translation and the original English version of this
1447+License, the original English version will prevail.
1448+
1449+
1450+9. TERMINATION
1451+
1452+You may not copy, modify, sublicense, or distribute the Document except
1453+as expressly provided for under this License. Any other attempt to
1454+copy, modify, sublicense or distribute the Document is void, and will
1455+automatically terminate your rights under this License. However,
1456+parties who have received copies, or rights, from you under this
1457+License will not have their licenses terminated so long as such
1458+parties remain in full compliance.
1459+
1460+
1461+10. FUTURE REVISIONS OF THIS LICENSE
1462+
1463+The Free Software Foundation may publish new, revised versions
1464+of the GNU Free Documentation License from time to time. Such new
1465+versions will be similar in spirit to the present version, but may
1466+differ in detail to address new problems or concerns. See
1467+http://www.gnu.org/copyleft/.
1468+
1469+Each version of the License is given a distinguishing version number.
1470+If the Document specifies that a particular numbered version of this
1471+License "or any later version" applies to it, you have the option of
1472+following the terms and conditions either of that specified version or
1473+of any later version that has been published (not as a draft) by the
1474+Free Software Foundation. If the Document does not specify a version
1475+number of this License, you may choose any version ever published (not
1476+as a draft) by the Free Software Foundation.
1477+
1478+
1479+ADDENDUM: How to use this License for your documents
1480+
1481+To use this License in a document you have written, include a copy of
1482+the License in the document and put the following copyright and
1483+license notices just after the title page:
1484+
1485+@smallexample
1486+ Copyright (c) YEAR YOUR NAME.
1487+ Permission is granted to copy, distribute and/or modify this document
1488+ under the terms of the GNU Free Documentation License, Version 1.1
1489+ or any later version published by the Free Software Foundation;
1490+ with the Invariant Sections being LIST THEIR TITLES, with the
1491+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
1492+ A copy of the license is included in the section entitled "GNU
1493+ Free Documentation License".
1494+@end smallexample
1495+
1496+If you have no Invariant Sections, write "with no Invariant Sections"
1497+instead of saying which ones are invariant. If you have no
1498+Front-Cover Texts, write "no Front-Cover Texts" instead of
1499+"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
1500+
1501+If your document contains nontrivial examples of program code, we
1502+recommend releasing these examples in parallel under your choice of
1503+free software license, such as the GNU General Public License,
1504+to permit their use in free software.
1505+
1506+@node Index
1507+@unnumbered Index
1508+
1509+@printindex cp
1510+
1511+@contents
1512+@bye
da530c8a
JB
1513--- binutils-2.17.50.0.2/gas/gasp.c.orig 1970-01-01 01:00:00.000000000 +0100
1514+++ binutils-2.17.50.0.2/gas/gasp.c 2006-06-07 11:22:13.774440000 +0200
1515@@ -0,0 +1,3999 @@
0087dcf3
JB
1516+/* gasp.c - Gnu assembler preprocessor main program.
1517+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
1518+ Free Software Foundation, Inc.
1519+
1520+ Written by Steve and Judy Chamberlain of Cygnus Support,
1521+ sac@cygnus.com
1522+
1523+ This file is part of GASP, the GNU Assembler Preprocessor.
1524+
1525+ GASP is free software; you can redistribute it and/or modify
1526+ it under the terms of the GNU General Public License as published by
1527+ the Free Software Foundation; either version 2, or (at your option)
1528+ any later version.
1529+
1530+ GASP is distributed in the hope that it will be useful,
1531+ but WITHOUT ANY WARRANTY; without even the implied warranty of
1532+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1533+ GNU General Public License for more details.
1534+
1535+ You should have received a copy of the GNU General Public License
1536+ along with GASP; see the file COPYING. If not, write to the Free
1537+ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1538+ 02111-1307, USA. */
1539+
1540+/*
1541+This program translates the input macros and stuff into a form
1542+suitable for gas to consume.
1543+
1544+ gasp [-sdhau] [-c char] [-o <outfile>] <infile>*
1545+
1546+ -s copy source to output
1547+ -c <char> comments are started with <char> instead of !
1548+ -u allow unreasonable stuff
1549+ -p print line numbers
1550+ -d print debugging stats
1551+ -s semi colons start comments
1552+ -a use alternate syntax
1553+ Pseudo ops can start with or without a .
1554+ Labels have to be in first column.
1555+ -I specify include dir
1556+ Macro arg parameters subsituted by name, don't need the &.
1557+ String can start with ' too.
1558+ Strings can be surrounded by <..>
1559+ A %<exp> in a string evaluates the expression
1560+ Literal char in a string with !
1561+*/
1562+
1563+#include "config.h"
7f820327 1564+#include "bfdver.h"
0087dcf3
JB
1565+
1566+#include <assert.h>
1567+#include <stdio.h>
1568+#include <string.h>
1569+#include "getopt.h"
1570+
1571+#ifdef HAVE_STDLIB_H
1572+#include <stdlib.h>
1573+#endif
1574+
1575+#ifdef NEED_MALLOC_DECLARATION
1576+extern char *malloc ();
1577+#endif
1578+
1579+#include "ansidecl.h"
1580+#include "libiberty.h"
1581+#include "safe-ctype.h"
1582+#include "sb.h"
1583+#include "macro.h"
1584+#include "asintl.h"
1585+#include "xregex.h"
1586+
1587+char *program_version = "1.2";
1588+
1589+/* This is normally declared in as.h, but we don't include that. We
1590+ need the function because other files linked with gasp.c might call
1591+ it. */
1592+extern void as_abort PARAMS ((const char *, int, const char *));
1593+
1594+/* The default obstack chunk size. If we set this to zero, the
1595+ obstack code will use whatever will fit in a 4096 byte block. This
1596+ is used by the hash table code used by macro.c. */
1597+int chunksize = 0;
1598+
1599+#define MAX_INCLUDES 30 /* Maximum include depth. */
1600+#define MAX_REASONABLE 1000 /* Maximum number of expansions. */
1601+
1602+int unreasonable; /* -u on command line. */
1603+int stats; /* -d on command line. */
1604+int print_line_number; /* -p flag on command line. */
1605+int copysource; /* -c flag on command line. */
1606+int warnings; /* Number of WARNINGs generated so far. */
1607+int errors; /* Number of ERRORs generated so far. */
1608+int fatals; /* Number of fatal ERRORs generated so far (either 0 or 1). */
1609+int alternate = 0; /* -a on command line. */
1610+int mri = 0; /* -M on command line. */
1611+char comment_char = '!';
1612+int radix = 10; /* Default radix. */
1613+
1614+int had_end; /* Seen .END. */
1615+
1616+/* The output stream. */
1617+FILE *outfile;
1618+
1619+/* The attributes of each character are stored as a bit pattern
1620+ chartype, which gives us quick tests. */
1621+
1622+#define FIRSTBIT 1
1623+#define NEXTBIT 2
1624+#define SEPBIT 4
1625+#define WHITEBIT 8
1626+#define COMMENTBIT 16
1627+#define BASEBIT 32
1628+#define ISCOMMENTCHAR(x) (chartype[(unsigned char)(x)] & COMMENTBIT)
1629+#define ISFIRSTCHAR(x) (chartype[(unsigned char)(x)] & FIRSTBIT)
1630+#define ISNEXTCHAR(x) (chartype[(unsigned char)(x)] & NEXTBIT)
1631+#define ISSEP(x) (chartype[(unsigned char)(x)] & SEPBIT)
1632+#define ISWHITE(x) (chartype[(unsigned char)(x)] & WHITEBIT)
1633+#define ISBASE(x) (chartype[(unsigned char)(x)] & BASEBIT)
1634+static char chartype[256];
1635+
1636+/* Conditional assembly uses the `ifstack'. Each aif pushes another
1637+ entry onto the stack, and sets the on flag if it should. The aelse
1638+ sets hadelse, and toggles on. An aend pops a level. We limit to
1639+ 100 levels of nesting, not because we're facists pigs with read
1640+ only minds, but because more than 100 levels of nesting is probably
1641+ a bug in the user's macro structure. */
1642+
1643+#define IFNESTING 100
1644+struct {
1645+ int on; /* Is the level being output. */
1646+ int hadelse; /* Has an aelse been seen. */
1647+} ifstack[IFNESTING];
1648+
1649+int ifi;
1650+
1651+/* The final and intermediate results of expression evaluation are kept in
1652+ exp_t's. Note that a symbol is not an sb, but a pointer into the input
1653+ line. It must be coped somewhere safe before the next line is read in. */
1654+
1655+typedef struct {
1656+ char *name;
1657+ int len;
1658+} symbol;
1659+
1660+typedef struct {
1661+ int value; /* Constant part. */
1662+ symbol add_symbol; /* Name part. */
1663+ symbol sub_symbol; /* Name part. */
1664+} exp_t;
1665+
1666+/* Hashing is done in a pretty standard way. A hash_table has a
1667+ pointer to a vector of pointers to hash_entrys, and the size of the
1668+ vector. A hash_entry contains a union of all the info we like to
1669+ store in hash table. If there is a hash collision, hash_entries
1670+ with the same hash are kept in a chain. */
1671+
1672+/* What the data in a hash_entry means. */
1673+typedef enum {
1674+ hash_integer, /* Name->integer mapping. */
1675+ hash_string, /* Name->string mapping. */
1676+ hash_macro, /* Name is a macro. */
1677+ hash_formal /* Name is a formal argument. */
1678+} hash_type;
1679+
1680+typedef struct hs {
1681+ sb key; /* Symbol name. */
1682+ hash_type type; /* Symbol meaning. */
1683+ union {
1684+ sb s;
1685+ int i;
1686+ struct macro_struct *m;
1687+ struct formal_struct *f;
1688+ } value;
1689+ struct hs *next; /* Next hash_entry with same hash key. */
1690+} hash_entry;
1691+
1692+typedef struct {
1693+ hash_entry **table;
1694+ int size;
1695+} hash_table;
1696+
1697+/* How we nest files and expand macros etc.
1698+
1699+ We keep a stack of of include_stack structs. Each include file
1700+ pushes a new level onto the stack. We keep an sb with a pushback
1701+ too. unget chars are pushed onto the pushback sb, getchars first
1702+ checks the pushback sb before reading from the input stream.
1703+
1704+ Small things are expanded by adding the text of the item onto the
1705+ pushback sb. Larger items are grown by pushing a new level and
1706+ allocating the entire pushback buf for the item. Each time
1707+ something like a macro is expanded, the stack index is changed. We
1708+ can then perform an exitm by popping all entries off the stack with
1709+ the same stack index. If we're being reasonable, we can detect
1710+ recusive expansion by checking the index is reasonably small. */
1711+
1712+typedef enum {
1713+ include_file, include_repeat, include_while, include_macro
1714+} include_type;
1715+
1716+struct include_stack {
1717+ sb pushback; /* Current pushback stream. */
1718+ int pushback_index; /* Next char to read from stream. */
1719+ FILE *handle; /* Open file. */
1720+ sb name; /* Name of file. */
1721+ int linecount; /* Number of lines read so far. */
1722+ include_type type;
1723+ int index; /* Index of this layer. */
1724+} include_stack[MAX_INCLUDES];
1725+
1726+struct include_stack *sp;
1727+#define isp (sp - include_stack)
1728+
1729+/* Include file list. */
1730+
1731+typedef struct include_path {
1732+ struct include_path *next;
1733+ sb path;
1734+} include_path;
1735+
1736+include_path *paths_head;
1737+include_path *paths_tail;
1738+
1739+static void quit PARAMS ((void));
1740+static void hash_new_table PARAMS ((int, hash_table *));
1741+static int hash PARAMS ((sb *));
1742+static hash_entry *hash_create PARAMS ((hash_table *, sb *));
1743+static void hash_add_to_string_table PARAMS ((hash_table *, sb *, sb *, int));
1744+static void hash_add_to_int_table PARAMS ((hash_table *, sb *, int));
1745+static hash_entry *hash_lookup PARAMS ((hash_table *, sb *));
1746+static void checkconst PARAMS ((int, exp_t *));
1747+static int is_flonum PARAMS ((int, sb *));
1748+static int chew_flonum PARAMS ((int, sb *, sb *));
1749+static int sb_strtol PARAMS ((int, sb *, int, int *));
1750+static int level_0 PARAMS ((int, sb *, exp_t *));
1751+static int level_1 PARAMS ((int, sb *, exp_t *));
1752+static int level_2 PARAMS ((int, sb *, exp_t *));
1753+static int level_3 PARAMS ((int, sb *, exp_t *));
1754+static int level_4 PARAMS ((int, sb *, exp_t *));
1755+static int level_5 PARAMS ((int, sb *, exp_t *));
1756+static int exp_parse PARAMS ((int, sb *, exp_t *));
1757+static void exp_string PARAMS ((exp_t *, sb *));
1758+static int exp_get_abs PARAMS ((const char *, int, sb *, int *));
1759+#if 0
1760+static void strip_comments PARAMS ((sb *));
1761+#endif
1762+static void unget PARAMS ((int));
1763+static void include_buf PARAMS ((sb *, sb *, include_type, int));
1764+static void include_print_where_line PARAMS ((FILE *));
1765+static void include_print_line PARAMS ((FILE *));
1766+static int get_line PARAMS ((sb *));
1767+static int grab_label PARAMS ((sb *, sb *));
1768+static void change_base PARAMS ((int, sb *, sb *));
1769+static void do_end PARAMS ((sb *));
1770+static void do_assign PARAMS ((int, int, sb *));
1771+static void do_radix PARAMS ((sb *));
1772+static int get_opsize PARAMS ((int, sb *, int *));
1773+static int eol PARAMS ((int, sb *));
1774+static void do_data PARAMS ((int, sb *, int));
1775+static void do_datab PARAMS ((int, sb *));
1776+static void do_align PARAMS ((int, sb *));
1777+static void do_res PARAMS ((int, sb *, int));
1778+static void do_export PARAMS ((sb *));
1779+static void do_print PARAMS ((int, sb *));
1780+static void do_heading PARAMS ((int, sb *));
1781+static void do_page PARAMS ((void));
1782+static void do_form PARAMS ((int, sb *));
1783+static int get_any_string PARAMS ((int, sb *, sb *, int, int));
1784+static int skip_openp PARAMS ((int, sb *));
1785+static int skip_closep PARAMS ((int, sb *));
1786+static int dolen PARAMS ((int, sb *, sb *));
1787+static int doinstr PARAMS ((int, sb *, sb *));
1788+static int dosubstr PARAMS ((int, sb *, sb *));
1789+static void process_assigns PARAMS ((int, sb *, sb *));
1790+static int get_and_process PARAMS ((int, sb *, sb *));
1791+static void process_file PARAMS ((void));
1792+static void free_old_entry PARAMS ((hash_entry *));
1793+static void do_assigna PARAMS ((int, sb *));
1794+static void do_assignc PARAMS ((int, sb *));
1795+static void do_reg PARAMS ((int, sb *));
1796+static int condass_lookup_name PARAMS ((sb *, int, sb *, int));
1797+static int whatcond PARAMS ((int, sb *, int *));
1798+static int istrue PARAMS ((int, sb *));
1799+static void do_aif PARAMS ((int, sb *));
1800+static void do_aelse PARAMS ((void));
1801+static void do_aendi PARAMS ((void));
1802+static int condass_on PARAMS ((void));
1803+static void do_if PARAMS ((int, sb *, int));
1804+static int get_mri_string PARAMS ((int, sb *, sb *, int));
1805+static void do_ifc PARAMS ((int, sb *, int));
1806+static void do_aendr PARAMS ((void));
1807+static void do_awhile PARAMS ((int, sb *));
1808+static void do_aendw PARAMS ((void));
1809+static void do_exitm PARAMS ((void));
1810+static void do_arepeat PARAMS ((int, sb *));
1811+static void do_endm PARAMS ((void));
1812+static void do_irp PARAMS ((int, sb *, int));
1813+static void do_local PARAMS ((int, sb *));
1814+static void do_macro PARAMS ((int, sb *));
1815+static int macro_op PARAMS ((int, sb *));
1816+static int getstring PARAMS ((int, sb *, sb *));
1817+static void do_sdata PARAMS ((int, sb *, int));
1818+static void do_sdatab PARAMS ((int, sb *));
1819+static int new_file PARAMS ((const char *));
1820+static void do_include PARAMS ((int, sb *));
1821+static void include_pop PARAMS ((void));
1822+static int get PARAMS ((void));
1823+static int linecount PARAMS ((void));
1824+static int include_next_index PARAMS ((void));
1825+static void chartype_init PARAMS ((void));
1826+static int process_pseudo_op PARAMS ((int, sb *, sb *));
1827+static void add_keyword PARAMS ((const char *, int));
1828+static void process_init PARAMS ((void));
1829+static void do_define PARAMS ((const char *));
1830+static void show_usage PARAMS ((FILE *, int));
1831+static void show_help PARAMS ((void));
1832+
486f726b
JB
1833+/* --- functions recently removed from sb.c --- */
1834+
1835+/* put a null at the end of the sb at in and return the start of the
1836+ * string, so that it can be used as an arg to printf %s. */
1837+
1838+static char *
1839+sb_name (sb *in)
1840+{
1841+ /* stick a null on the end of the string */
1842+ sb_add_char (in, 0);
1843+ return in->ptr;
1844+}
1845+
1846+/* print the sb at ptr to the output file */
1847+
1848+static void
1849+sb_print (FILE *outfile, sb *ptr)
1850+{
1851+ int i;
1852+ int nc = 0;
1853+
1854+ for (i = 0; i < ptr->len; i++)
1855+ {
1856+ if (nc)
1857+ {
1858+ fprintf (outfile, ",");
1859+ }
1860+ fprintf (outfile, "%d", ptr->ptr[i]);
1861+ nc = 1;
1862+ }
1863+}
1864+
1865+/* print the sb at ptr to the output file */
1866+
1867+static void
1868+sb_print_at (FILE *outfile, int idx, sb *ptr)
1869+{
1870+ int i;
1871+ for (i = idx; i < ptr->len; i++)
1872+ putc (ptr->ptr[i], outfile);
1873+}
1874+
0087dcf3
JB
1875+#define FATAL(x) \
1876+ do \
1877+ { \
1878+ include_print_where_line (stderr); \
1879+ fprintf x; \
1880+ fatals++; \
1881+ quit (); \
1882+ } \
1883+ while (0)
1884+
1885+#define ERROR(x) \
1886+ do \
1887+ { \
1888+ include_print_where_line (stderr); \
1889+ fprintf x; \
1890+ errors++; \
1891+ } \
1892+ while (0)
1893+
1894+#define WARNING(x) \
1895+ do \
1896+ { \
1897+ include_print_where_line (stderr); \
1898+ fprintf x; \
1899+ warnings++; \
1900+ } \
1901+ while (0)
1902+
1903+/* Exit the program and return the right ERROR code. */
1904+
1905+static void
1906+quit ()
1907+{
1908+ int exitcode;
1909+ if (fatals + errors)
1910+ exitcode = 1;
1911+ else
1912+ exitcode = 0;
1913+
0087dcf3
JB
1914+ exit (exitcode);
1915+}
1916+
1917+/* Hash table maintenance. */
1918+
1919+/* Build a new hash table with size buckets
1920+ and fill in the info at ptr. */
1921+
1922+static void
1923+hash_new_table (size, ptr)
1924+ int size;
1925+ hash_table *ptr;
1926+{
1927+ int i;
1928+ ptr->size = size;
1929+ ptr->table = (hash_entry **) xmalloc (size * (sizeof (hash_entry *)));
1930+ /* Fill with null-pointer, not zero-bit-pattern. */
1931+ for (i = 0; i < size; i++)
1932+ ptr->table[i] = 0;
1933+}
1934+
1935+/* Calculate and return the hash value of the sb at key. */
1936+
1937+static int
1938+hash (key)
1939+ sb *key;
1940+{
1941+ int k = 0x1234;
1942+ int i;
1943+ char *p = key->ptr;
1944+ for (i = 0; i < key->len; i++)
1945+ {
1946+ k ^= (k << 2) ^ *p;
1947+ p++;
1948+ }
1949+ return k & 0xf0fff;
1950+}
1951+
1952+/* Look up key in hash_table tab. If present, then return it,
1953+ otherwise build a new one and fill it with hash_integer. */
1954+
1955+static hash_entry *
1956+hash_create (tab, key)
1957+ hash_table *tab;
1958+ sb *key;
1959+{
1960+ int k = hash (key) % tab->size;
1961+ hash_entry *p;
1962+ hash_entry **table = tab->table;
1963+
1964+ p = table[k];
1965+
1966+ while (1)
1967+ {
1968+ if (!p)
1969+ {
1970+ hash_entry *n = (hash_entry *) xmalloc (sizeof (hash_entry));
1971+ n->next = table[k];
1972+ sb_new (&n->key);
1973+ sb_add_sb (&n->key, key);
1974+ table[k] = n;
1975+ n->type = hash_integer;
1976+ return n;
1977+ }
1978+ if (strncmp (table[k]->key.ptr, key->ptr, key->len) == 0)
1979+ {
1980+ return p;
1981+ }
1982+ p = p->next;
1983+ }
1984+}
1985+
1986+/* Add sb name with key into hash_table tab.
1987+ If replacing old value and again, then ERROR. */
1988+
1989+static void
1990+hash_add_to_string_table (tab, key, name, again)
1991+ hash_table *tab;
1992+ sb *key;
1993+ sb *name;
1994+ int again;
1995+{
1996+ hash_entry *ptr = hash_create (tab, key);
1997+ if (ptr->type == hash_integer)
1998+ {
1999+ sb_new (&ptr->value.s);
2000+ }
2001+ if (ptr->value.s.len)
2002+ {
2003+ if (!again)
2004+ ERROR ((stderr, _("redefinition not allowed\n")));
2005+ }
2006+
2007+ ptr->type = hash_string;
2008+ sb_reset (&ptr->value.s);
2009+
2010+ sb_add_sb (&ptr->value.s, name);
2011+}
2012+
2013+/* Add integer name to hash_table tab with sb key. */
2014+
2015+static void
2016+hash_add_to_int_table (tab, key, name)
2017+ hash_table *tab;
2018+ sb *key;
2019+ int name;
2020+{
2021+ hash_entry *ptr = hash_create (tab, key);
2022+ ptr->value.i = name;
2023+}
2024+
2025+/* Look up sb key in hash_table tab.
2026+ If found, return hash_entry result, else 0. */
2027+
2028+static hash_entry *
2029+hash_lookup (tab, key)
2030+ hash_table *tab;
2031+ sb *key;
2032+{
2033+ int k = hash (key) % tab->size;
2034+ hash_entry **table = tab->table;
2035+ hash_entry *p = table[k];
2036+ while (p)
2037+ {
2038+ if (p->key.len == key->len
2039+ && strncmp (p->key.ptr, key->ptr, key->len) == 0)
2040+ return p;
2041+ p = p->next;
2042+ }
2043+ return 0;
2044+}
2045+
2046+/* expressions
2047+
2048+ are handled in a really simple recursive decent way. each bit of
2049+ the machine takes an index into an sb and a pointer to an exp_t,
2050+ modifies the *exp_t and returns the index of the first character
2051+ past the part of the expression parsed.
2052+
2053+ expression precedence:
2054+ ( )
2055+ unary + - ~
2056+ * /
2057+ + -
2058+ &
2059+ | ~
2060+*/
2061+
2062+/* Make sure that the exp_t at term is constant.
2063+ If not the give the op ERROR. */
2064+
2065+static void
2066+checkconst (op, term)
2067+ int op;
2068+ exp_t *term;
2069+{
2070+ if (term->add_symbol.len
2071+ || term->sub_symbol.len)
2072+ {
2073+ ERROR ((stderr, _("the %c operator cannot take non-absolute arguments.\n"), op));
2074+ }
2075+}
2076+
2077+/* Chew the flonum from the string starting at idx. Adjust idx to
2078+ point to the next character after the flonum. */
2079+
2080+static int
2081+chew_flonum (idx, string, out)
2082+ int idx;
2083+ sb *string;
2084+ sb *out;
2085+{
2086+ sb buf;
2087+ regex_t reg;
2088+ regmatch_t match;
2089+
2090+ /* Duplicate and null terminate `string'. */
2091+ sb_new (&buf);
2092+ sb_add_sb (&buf, string);
2093+ sb_add_char (&buf, '\0');
2094+
2095+ if (regcomp (&reg, "([0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?)", REG_EXTENDED) != 0)
2096+ return idx;
2097+ if (regexec (&reg, &buf.ptr[idx], 1, &match, 0) != 0)
2098+ return idx;
2099+
2100+ /* Copy the match to the output. */
2101+ assert (match.rm_eo >= match.rm_so);
2102+ sb_add_buffer (out, &buf.ptr[idx], match.rm_eo - match.rm_so);
2103+
2104+ sb_kill (&buf);
2105+ regfree (&reg);
2106+ idx += match.rm_eo;
2107+ return idx;
2108+}
2109+
2110+static int
2111+is_flonum (idx, string)
2112+ int idx;
2113+ sb *string;
2114+{
2115+ sb buf;
2116+ regex_t reg;
2117+ int rc;
2118+
2119+ /* Duplicate and null terminate `string'. */
2120+ sb_new (&buf);
2121+ sb_add_sb (&buf, string);
2122+ sb_add_char (&buf, '\0');
2123+
2124+ if (regcomp (&reg, "^[0-9]*\\.[0-9]+([eE][+-]?[0-9]+)?", REG_EXTENDED) != 0)
2125+ return 0;
2126+
2127+ rc = regexec (&reg, &buf.ptr[idx], 0, NULL, 0);
2128+ sb_kill (&buf);
2129+ regfree (&reg);
2130+ return (rc == 0);
2131+}
2132+
2133+/* Turn the number in string at idx into a number of base, fill in
2134+ ptr, and return the index of the first character not in the number. */
2135+
2136+static int
2137+sb_strtol (idx, string, base, ptr)
2138+ int idx;
2139+ sb *string;
2140+ int base;
2141+ int *ptr;
2142+{
2143+ int value = 0;
2144+ idx = sb_skip_white (idx, string);
2145+
2146+ while (idx < string->len)
2147+ {
2148+ int ch = string->ptr[idx];
2149+ int dig = 0;
2150+ if (ISDIGIT (ch))
2151+ dig = ch - '0';
2152+ else if (ch >= 'a' && ch <= 'f')
2153+ dig = ch - 'a' + 10;
2154+ else if (ch >= 'A' && ch <= 'F')
2155+ dig = ch - 'A' + 10;
2156+ else
2157+ break;
2158+
2159+ if (dig >= base)
2160+ break;
2161+
2162+ value = value * base + dig;
2163+ idx++;
2164+ }
2165+ *ptr = value;
2166+ return idx;
2167+}
2168+
2169+static int
2170+level_0 (idx, string, lhs)
2171+ int idx;
2172+ sb *string;
2173+ exp_t *lhs;
2174+{
2175+ lhs->add_symbol.len = 0;
2176+ lhs->add_symbol.name = 0;
2177+
2178+ lhs->sub_symbol.len = 0;
2179+ lhs->sub_symbol.name = 0;
2180+
2181+ idx = sb_skip_white (idx, string);
2182+
2183+ lhs->value = 0;
2184+
2185+ if (ISDIGIT (string->ptr[idx]))
2186+ {
2187+ idx = sb_strtol (idx, string, 10, &lhs->value);
2188+ }
2189+ else if (ISFIRSTCHAR (string->ptr[idx]))
2190+ {
2191+ int len = 0;
2192+ lhs->add_symbol.name = string->ptr + idx;
2193+ while (idx < string->len && ISNEXTCHAR (string->ptr[idx]))
2194+ {
2195+ idx++;
2196+ len++;
2197+ }
2198+ lhs->add_symbol.len = len;
2199+ }
2200+ else if (string->ptr[idx] == '"')
2201+ {
2202+ sb acc;
2203+ sb_new (&acc);
2204+ ERROR ((stderr, _("string where expression expected.\n")));
2205+ idx = getstring (idx, string, &acc);
2206+ sb_kill (&acc);
2207+ }
2208+ else
2209+ {
2210+ ERROR ((stderr, _("can't find primary in expression.\n")));
2211+ idx++;
2212+ }
2213+ return sb_skip_white (idx, string);
2214+}
2215+
2216+static int
2217+level_1 (idx, string, lhs)
2218+ int idx;
2219+ sb *string;
2220+ exp_t *lhs;
2221+{
2222+ idx = sb_skip_white (idx, string);
2223+
2224+ switch (string->ptr[idx])
2225+ {
2226+ case '+':
2227+ idx = level_1 (idx + 1, string, lhs);
2228+ break;
2229+ case '~':
2230+ idx = level_1 (idx + 1, string, lhs);
2231+ checkconst ('~', lhs);
2232+ lhs->value = ~lhs->value;
2233+ break;
2234+ case '-':
2235+ {
2236+ symbol t;
2237+ idx = level_1 (idx + 1, string, lhs);
2238+ lhs->value = -lhs->value;
2239+ t = lhs->add_symbol;
2240+ lhs->add_symbol = lhs->sub_symbol;
2241+ lhs->sub_symbol = t;
2242+ break;
2243+ }
2244+ case '(':
2245+ idx++;
2246+ idx = level_5 (sb_skip_white (idx, string), string, lhs);
2247+ if (string->ptr[idx] != ')')
2248+ ERROR ((stderr, _("misplaced closing parens.\n")));
2249+ else
2250+ idx++;
2251+ break;
2252+ default:
2253+ idx = level_0 (idx, string, lhs);
2254+ break;
2255+ }
2256+ return sb_skip_white (idx, string);
2257+}
2258+
2259+static int
2260+level_2 (idx, string, lhs)
2261+ int idx;
2262+ sb *string;
2263+ exp_t *lhs;
2264+{
2265+ exp_t rhs;
2266+
2267+ idx = level_1 (idx, string, lhs);
2268+
2269+ while (idx < string->len && (string->ptr[idx] == '*'
2270+ || string->ptr[idx] == '/'))
2271+ {
2272+ char op = string->ptr[idx++];
2273+ idx = level_1 (idx, string, &rhs);
2274+ switch (op)
2275+ {
2276+ case '*':
2277+ checkconst ('*', lhs);
2278+ checkconst ('*', &rhs);
2279+ lhs->value *= rhs.value;
2280+ break;
2281+ case '/':
2282+ checkconst ('/', lhs);
2283+ checkconst ('/', &rhs);
2284+ if (rhs.value == 0)
2285+ ERROR ((stderr, _("attempt to divide by zero.\n")));
2286+ else
2287+ lhs->value /= rhs.value;
2288+ break;
2289+ }
2290+ }
2291+ return sb_skip_white (idx, string);
2292+}
2293+
2294+static int
2295+level_3 (idx, string, lhs)
2296+ int idx;
2297+ sb *string;
2298+ exp_t *lhs;
2299+{
2300+ exp_t rhs;
2301+
2302+ idx = level_2 (idx, string, lhs);
2303+
2304+ while (idx < string->len
2305+ && (string->ptr[idx] == '+'
2306+ || string->ptr[idx] == '-'))
2307+ {
2308+ char op = string->ptr[idx++];
2309+ idx = level_2 (idx, string, &rhs);
2310+ switch (op)
2311+ {
2312+ case '+':
2313+ lhs->value += rhs.value;
2314+ if (lhs->add_symbol.name && rhs.add_symbol.name)
2315+ {
2316+ ERROR ((stderr, _("can't add two relocatable expressions\n")));
2317+ }
2318+ /* Change nn+symbol to symbol + nn. */
2319+ if (rhs.add_symbol.name)
2320+ {
2321+ lhs->add_symbol = rhs.add_symbol;
2322+ }
2323+ break;
2324+ case '-':
2325+ lhs->value -= rhs.value;
2326+ lhs->sub_symbol = rhs.add_symbol;
2327+ break;
2328+ }
2329+ }
2330+ return sb_skip_white (idx, string);
2331+}
2332+
2333+static int
2334+level_4 (idx, string, lhs)
2335+ int idx;
2336+ sb *string;
2337+ exp_t *lhs;
2338+{
2339+ exp_t rhs;
2340+
2341+ idx = level_3 (idx, string, lhs);
2342+
2343+ while (idx < string->len &&
2344+ string->ptr[idx] == '&')
2345+ {
2346+ char op = string->ptr[idx++];
2347+ idx = level_3 (idx, string, &rhs);
2348+ switch (op)
2349+ {
2350+ case '&':
2351+ checkconst ('&', lhs);
2352+ checkconst ('&', &rhs);
2353+ lhs->value &= rhs.value;
2354+ break;
2355+ }
2356+ }
2357+ return sb_skip_white (idx, string);
2358+}
2359+
2360+static int
2361+level_5 (idx, string, lhs)
2362+ int idx;
2363+ sb *string;
2364+ exp_t *lhs;
2365+{
2366+ exp_t rhs;
2367+
2368+ idx = level_4 (idx, string, lhs);
2369+
2370+ while (idx < string->len
2371+ && (string->ptr[idx] == '|' || string->ptr[idx] == '~'))
2372+ {
2373+ char op = string->ptr[idx++];
2374+ idx = level_4 (idx, string, &rhs);
2375+ switch (op)
2376+ {
2377+ case '|':
2378+ checkconst ('|', lhs);
2379+ checkconst ('|', &rhs);
2380+ lhs->value |= rhs.value;
2381+ break;
2382+ case '~':
2383+ checkconst ('~', lhs);
2384+ checkconst ('~', &rhs);
2385+ lhs->value ^= rhs.value;
2386+ break;
2387+ }
2388+ }
2389+ return sb_skip_white (idx, string);
2390+}
2391+
2392+/* Parse the expression at offset idx into string, fill up res with
2393+ the result. Return the index of the first char past the
2394+ expression. */
2395+
2396+static int
2397+exp_parse (idx, string, res)
2398+ int idx;
2399+ sb *string;
2400+ exp_t *res;
2401+{
2402+ return level_5 (sb_skip_white (idx, string), string, res);
2403+}
2404+
2405+/* Turn the expression at exp into text and glue it onto the end of
2406+ string. */
2407+
2408+static void
2409+exp_string (exp, string)
2410+ exp_t *exp;
2411+ sb *string;
2412+{
2413+ int np = 0;
2414+ int ad = 0;
2415+ sb_reset (string);
2416+
2417+ if (exp->add_symbol.len)
2418+ {
2419+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
2420+ np = 1;
2421+ ad = 1;
2422+ }
2423+ if (exp->value)
2424+ {
2425+ char buf[20];
2426+ if (np)
2427+ sb_add_char (string, '+');
2428+ sprintf (buf, "%d", exp->value);
2429+ sb_add_string (string, buf);
2430+ np = 1;
2431+ ad = 1;
2432+ }
2433+ if (exp->sub_symbol.len)
2434+ {
2435+ sb_add_char (string, '-');
2436+ sb_add_buffer (string, exp->add_symbol.name, exp->add_symbol.len);
2437+ np = 0;
2438+ ad = 1;
2439+ }
2440+
2441+ if (!ad)
2442+ sb_add_char (string, '0');
2443+}
2444+
2445+/* Parse the expression at offset idx into sb in. Return the value in
2446+ val. If the expression is not constant, give ERROR emsg. Return
2447+ the index of the first character past the end of the expression. */
2448+
2449+static int
2450+exp_get_abs (emsg, idx, in, val)
2451+ const char *emsg;
2452+ int idx;
2453+ sb *in;
2454+ int *val;
2455+{
2456+ exp_t res;
2457+ idx = exp_parse (idx, in, &res);
2458+ if (res.add_symbol.len || res.sub_symbol.len)
2459+ ERROR ((stderr, "%s", emsg));
2460+ *val = res.value;
2461+ return idx;
2462+}
2463+
2464+/* Current label parsed from line. */
2465+sb label;
2466+
2467+/* Hash table for all assigned variables. */
2468+hash_table assign_hash_table;
2469+
2470+/* Hash table for keyword. */
2471+hash_table keyword_hash_table;
2472+
2473+/* Hash table for eq variables. */
2474+hash_table vars;
2475+
2476+#define in_comment ';'
2477+
2478+#if 0
2479+static void
2480+strip_comments (out)
2481+ sb *out;
2482+{
2483+ char *s = out->ptr;
2484+ int i = 0;
2485+ for (i = 0; i < out->len; i++)
2486+ {
2487+ if (ISCOMMENTCHAR (s[i]))
2488+ {
2489+ out->len = i;
2490+ return;
2491+ }
2492+ }
2493+}
2494+#endif
2495+
2496+/* Push back character ch so that it can be read again. */
2497+
2498+static void
2499+unget (ch)
2500+ int ch;
2501+{
2502+ if (ch == '\n')
2503+ {
2504+ sp->linecount--;
2505+ }
2506+ if (sp->pushback_index)
2507+ sp->pushback_index--;
2508+ else
2509+ sb_add_char (&sp->pushback, ch);
2510+}
2511+
2512+/* Push the sb ptr onto the include stack, with the given name, type
2513+ and index. */
2514+
2515+static void
2516+include_buf (name, ptr, type, index)
2517+ sb *name;
2518+ sb *ptr;
2519+ include_type type;
2520+ int index;
2521+{
2522+ sp++;
2523+ if (sp - include_stack >= MAX_INCLUDES)
2524+ FATAL ((stderr, _("unreasonable nesting.\n")));
2525+ sb_new (&sp->name);
2526+ sb_add_sb (&sp->name, name);
2527+ sp->handle = 0;
2528+ sp->linecount = 1;
2529+ sp->pushback_index = 0;
2530+ sp->type = type;
2531+ sp->index = index;
2532+ sb_new (&sp->pushback);
2533+ sb_add_sb (&sp->pushback, ptr);
2534+}
2535+
2536+/* Used in ERROR messages, print info on where the include stack is
2537+ onto file. */
2538+
2539+static void
2540+include_print_where_line (file)
2541+ FILE *file;
2542+{
2543+ struct include_stack *p = include_stack + 1;
2544+
2545+ while (p <= sp)
2546+ {
2547+ fprintf (file, "%s:%d ", sb_name (&p->name), p->linecount - 1);
2548+ p++;
2549+ }
2550+}
2551+
2552+/* Used in listings, print the line number onto file. */
2553+
2554+static void
2555+include_print_line (file)
2556+ FILE *file;
2557+{
2558+ int n;
2559+ struct include_stack *p = include_stack + 1;
2560+
2561+ n = fprintf (file, "%4d", p->linecount);
2562+ p++;
2563+ while (p <= sp)
2564+ {
2565+ n += fprintf (file, ".%d", p->linecount);
2566+ p++;
2567+ }
2568+ while (n < 8 * 3)
2569+ {
2570+ fprintf (file, " ");
2571+ n++;
2572+ }
2573+}
2574+
2575+/* Read a line from the top of the include stack into sb in. */
2576+
2577+static int
2578+get_line (in)
2579+ sb *in;
2580+{
2581+ int online = 0;
96b2e46d 2582+ int more = 1, ch = 0;
0087dcf3
JB
2583+
2584+ if (copysource)
2585+ {
2586+ putc (comment_char, outfile);
2587+ if (print_line_number)
2588+ include_print_line (outfile);
2589+ }
2590+
2591+ while (1)
2592+ {
96b2e46d 2593+ ch = get ();
0087dcf3
JB
2594+
2595+ while (ch == '\r')
2596+ ch = get ();
2597+
2598+ if (ch == EOF)
2599+ {
2600+ if (online)
2601+ {
2602+ WARNING ((stderr, _("End of file not at start of line.\n")));
2603+ if (copysource)
2604+ putc ('\n', outfile);
2605+ ch = '\n';
2606+ }
2607+ else
2608+ more = 0;
2609+ break;
2610+ }
2611+
2612+ if (copysource)
2613+ {
2614+ putc (ch, outfile);
2615+ }
2616+
2617+ if (ch == '\n')
2618+ {
2619+ ch = get ();
2620+ online = 0;
2621+ if (ch == '+')
2622+ {
2623+ /* Continued line. */
2624+ if (copysource)
2625+ {
2626+ putc (comment_char, outfile);
2627+ putc ('+', outfile);
2628+ }
2629+ ch = get ();
2630+ }
2631+ else
2632+ {
2633+ if (ch != EOF)
2634+ unget (ch);
96b2e46d 2635+ ch = '\n'; break;
0087dcf3
JB
2636+ }
2637+ }
2638+ else
2639+ {
2640+ sb_add_char (in, ch);
2641+ }
2642+ online++;
2643+ }
2644+
96b2e46d 2645+ return more ? ch : 0;
0087dcf3
JB
2646+}
2647+
2648+/* Find a label from sb in and put it in out. */
2649+
2650+static int
2651+grab_label (in, out)
2652+ sb *in;
2653+ sb *out;
2654+{
2655+ int i = 0;
2656+ sb_reset (out);
2657+ if (ISFIRSTCHAR (in->ptr[i]) || in->ptr[i] == '\\')
2658+ {
2659+ sb_add_char (out, in->ptr[i]);
2660+ i++;
2661+ while ((ISNEXTCHAR (in->ptr[i])
2662+ || in->ptr[i] == '\\'
2663+ || in->ptr[i] == '&')
2664+ && i < in->len)
2665+ {
2666+ sb_add_char (out, in->ptr[i]);
2667+ i++;
2668+ }
2669+ }
2670+ return i;
2671+}
2672+
2673+/* Find all strange base stuff and turn into decimal. Also
2674+ find all the other numbers and convert them from the default radix. */
2675+
2676+static void
2677+change_base (idx, in, out)
2678+ int idx;
2679+ sb *in;
2680+ sb *out;
2681+{
2682+ char buffer[20];
2683+
2684+ while (idx < in->len)
2685+ {
2686+ if (in->ptr[idx] == '\\'
2687+ && idx + 1 < in->len
2688+ && in->ptr[idx + 1] == '(')
2689+ {
2690+ idx += 2;
2691+ while (idx < in->len
2692+ && in->ptr[idx] != ')')
2693+ {
2694+ sb_add_char (out, in->ptr[idx]);
2695+ idx++;
2696+ }
2697+ if (idx < in->len)
2698+ idx++;
2699+ }
2700+ else if (idx < in->len - 1 && in->ptr[idx + 1] == '\'' && ! mri)
2701+ {
2702+ int base;
2703+ int value;
2704+ switch (in->ptr[idx])
2705+ {
2706+ case 'b':
2707+ case 'B':
2708+ base = 2;
2709+ break;
2710+ case 'q':
2711+ case 'Q':
2712+ base = 8;
2713+ break;
2714+ case 'h':
2715+ case 'H':
2716+ base = 16;
2717+ break;
2718+ case 'd':
2719+ case 'D':
2720+ base = 10;
2721+ break;
2722+ default:
2723+ ERROR ((stderr, _("Illegal base character %c.\n"), in->ptr[idx]));
2724+ base = 10;
2725+ break;
2726+ }
2727+
2728+ idx = sb_strtol (idx + 2, in, base, &value);
2729+ sprintf (buffer, "%d", value);
2730+ sb_add_string (out, buffer);
2731+ }
2732+ else if (ISFIRSTCHAR (in->ptr[idx]))
2733+ {
2734+ /* Copy entire names through quickly. */
2735+ sb_add_char (out, in->ptr[idx]);
2736+ idx++;
2737+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
2738+ {
2739+ sb_add_char (out, in->ptr[idx]);
2740+ idx++;
2741+ }
2742+ }
2743+ else if (is_flonum (idx, in))
2744+ {
2745+ idx = chew_flonum (idx, in, out);
2746+ }
2747+ else if (ISDIGIT (in->ptr[idx]))
2748+ {
2749+ int value;
2750+ /* All numbers must start with a digit, let's chew it and
2751+ spit out decimal. */
2752+ idx = sb_strtol (idx, in, radix, &value);
2753+ sprintf (buffer, "%d", value);
2754+ sb_add_string (out, buffer);
2755+
2756+ /* Skip all undigsested letters. */
2757+ while (idx < in->len && ISNEXTCHAR (in->ptr[idx]))
2758+ {
2759+ sb_add_char (out, in->ptr[idx]);
2760+ idx++;
2761+ }
2762+ }
2763+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
2764+ {
2765+ char tchar = in->ptr[idx];
2766+ /* Copy entire names through quickly. */
2767+ sb_add_char (out, in->ptr[idx]);
2768+ idx++;
2769+ while (idx < in->len && in->ptr[idx] != tchar)
2770+ {
2771+ sb_add_char (out, in->ptr[idx]);
2772+ idx++;
2773+ }
2774+ }
2775+ else
2776+ {
2777+ /* Nothing special, just pass it through. */
2778+ sb_add_char (out, in->ptr[idx]);
2779+ idx++;
2780+ }
2781+ }
2782+
2783+}
2784+
2785+/* .end */
2786+
2787+static void
2788+do_end (in)
2789+ sb *in;
2790+{
2791+ had_end = 1;
2792+ if (mri)
2793+ fprintf (outfile, "%s\n", sb_name (in));
2794+}
2795+
2796+/* .assign */
2797+
2798+static void
2799+do_assign (again, idx, in)
2800+ int again;
2801+ int idx;
2802+ sb *in;
2803+{
2804+ /* Stick label in symbol table with following value. */
2805+ exp_t e;
2806+ sb acc;
2807+
2808+ sb_new (&acc);
2809+ idx = exp_parse (idx, in, &e);
2810+ exp_string (&e, &acc);
2811+ hash_add_to_string_table (&assign_hash_table, &label, &acc, again);
2812+ sb_kill (&acc);
2813+}
2814+
2815+/* .radix [b|q|d|h] */
2816+
2817+static void
2818+do_radix (ptr)
2819+ sb *ptr;
2820+{
2821+ int idx = sb_skip_white (0, ptr);
2822+ switch (ptr->ptr[idx])
2823+ {
2824+ case 'B':
2825+ case 'b':
2826+ radix = 2;
2827+ break;
2828+ case 'q':
2829+ case 'Q':
2830+ radix = 8;
2831+ break;
2832+ case 'd':
2833+ case 'D':
2834+ radix = 10;
2835+ break;
2836+ case 'h':
2837+ case 'H':
2838+ radix = 16;
2839+ break;
2840+ default:
2841+ ERROR ((stderr, _("radix is %c must be one of b, q, d or h"), radix));
2842+ }
2843+}
2844+
2845+/* Parse off a .b, .w or .l. */
2846+
2847+static int
2848+get_opsize (idx, in, size)
2849+ int idx;
2850+ sb *in;
2851+ int *size;
2852+{
2853+ *size = 4;
2854+ if (in->ptr[idx] == '.')
2855+ {
2856+ idx++;
2857+ }
2858+ switch (in->ptr[idx])
2859+ {
2860+ case 'b':
2861+ case 'B':
2862+ *size = 1;
2863+ break;
2864+ case 'w':
2865+ case 'W':
2866+ *size = 2;
2867+ break;
2868+ case 'l':
2869+ case 'L':
2870+ *size = 4;
2871+ break;
2872+ case ' ':
2873+ case '\t':
2874+ break;
2875+ default:
2876+ ERROR ((stderr, _("size must be one of b, w or l, is %c.\n"), in->ptr[idx]));
2877+ break;
2878+ }
2879+ idx++;
2880+
2881+ return idx;
2882+}
2883+
2884+static int
2885+eol (idx, line)
2886+ int idx;
2887+ sb *line;
2888+{
2889+ idx = sb_skip_white (idx, line);
2890+ if (idx < line->len
2891+ && ISCOMMENTCHAR(line->ptr[idx]))
2892+ return 1;
2893+ if (idx >= line->len)
2894+ return 1;
2895+ return 0;
2896+}
2897+
2898+/* .data [.b|.w|.l] <data>*
2899+ or d[bwl] <data>* */
2900+
2901+static void
2902+do_data (idx, in, size)
2903+ int idx;
2904+ sb *in;
2905+ int size;
2906+{
2907+ int opsize = 4;
2908+ char *opname = ".yikes!";
2909+ sb acc;
2910+ sb_new (&acc);
2911+
2912+ if (!size)
2913+ {
2914+ idx = get_opsize (idx, in, &opsize);
2915+ }
2916+ else
2917+ {
2918+ opsize = size;
2919+ }
2920+ switch (opsize)
2921+ {
2922+ case 4:
2923+ opname = ".long";
2924+ break;
2925+ case 2:
2926+ opname = ".short";
2927+ break;
2928+ case 1:
2929+ opname = ".byte";
2930+ break;
2931+ }
2932+
2933+ fprintf (outfile, "%s\t", opname);
2934+
2935+ idx = sb_skip_white (idx, in);
2936+
2937+ if (alternate
2938+ && idx < in->len
2939+ && in->ptr[idx] == '"')
2940+ {
2941+ int i;
2942+ idx = getstring (idx, in, &acc);
2943+ for (i = 0; i < acc.len; i++)
2944+ {
2945+ if (i)
2946+ fprintf (outfile, ",");
2947+ fprintf (outfile, "%d", acc.ptr[i]);
2948+ }
2949+ }
2950+ else
2951+ {
2952+ while (!eol (idx, in))
2953+ {
2954+ exp_t e;
2955+ idx = exp_parse (idx, in, &e);
2956+ exp_string (&e, &acc);
2957+ sb_add_char (&acc, 0);
2958+ fprintf (outfile, "%s", acc.ptr);
2959+ if (idx < in->len && in->ptr[idx] == ',')
2960+ {
2961+ fprintf (outfile, ",");
2962+ idx++;
2963+ }
2964+ }
2965+ }
2966+ sb_kill (&acc);
2967+ sb_print_at (outfile, idx, in);
2968+ fprintf (outfile, "\n");
2969+}
2970+
2971+/* .datab [.b|.w|.l] <repeat>,<fill> */
2972+
2973+static void
2974+do_datab (idx, in)
2975+ int idx;
2976+ sb *in;
2977+{
2978+ int opsize;
2979+ int repeat;
2980+ int fill;
2981+
2982+ idx = get_opsize (idx, in, &opsize);
2983+
2984+ idx = exp_get_abs (_("datab repeat must be constant.\n"), idx, in, &repeat);
2985+ idx = sb_skip_comma (idx, in);
2986+ idx = exp_get_abs (_("datab data must be absolute.\n"), idx, in, &fill);
2987+
2988+ fprintf (outfile, ".fill\t%d,%d,%d\n", repeat, opsize, fill);
2989+}
2990+
2991+/* .align <size> */
2992+
2993+static void
2994+do_align (idx, in)
2995+ int idx;
2996+ sb *in;
2997+{
2998+ int al, have_fill, fill;
2999+
3000+ idx = exp_get_abs (_("align needs absolute expression.\n"), idx, in, &al);
3001+ idx = sb_skip_white (idx, in);
3002+ have_fill = 0;
3003+ fill = 0;
3004+ if (! eol (idx, in))
3005+ {
3006+ idx = sb_skip_comma (idx, in);
3007+ idx = exp_get_abs (_(".align needs absolute fill value.\n"), idx, in,
3008+ &fill);
3009+ have_fill = 1;
3010+ }
3011+
3012+ fprintf (outfile, ".align %d", al);
3013+ if (have_fill)
3014+ fprintf (outfile, ",%d", fill);
3015+ fprintf (outfile, "\n");
3016+}
3017+
3018+/* .res[.b|.w|.l] <size> */
3019+
3020+static void
3021+do_res (idx, in, type)
3022+ int idx;
3023+ sb *in;
3024+ int type;
3025+{
3026+ int size = 4;
3027+ int count = 0;
3028+
3029+ idx = get_opsize (idx, in, &size);
3030+ while (!eol (idx, in))
3031+ {
3032+ idx = sb_skip_white (idx, in);
3033+ if (in->ptr[idx] == ',')
3034+ idx++;
3035+ idx = exp_get_abs (_("res needs absolute expression for fill count.\n"), idx, in, &count);
3036+
3037+ if (type == 'c' || type == 'z')
3038+ count++;
3039+
3040+ fprintf (outfile, ".space %d\n", count * size);
3041+ }
3042+}
3043+
3044+/* .export */
3045+
3046+static void
3047+do_export (in)
3048+ sb *in;
3049+{
3050+ fprintf (outfile, ".global %s\n", sb_name (in));
3051+}
3052+
3053+/* .print [list] [nolist] */
3054+
3055+static void
3056+do_print (idx, in)
3057+ int idx;
3058+ sb *in;
3059+{
3060+ idx = sb_skip_white (idx, in);
3061+ while (idx < in->len)
3062+ {
3063+ if (strncasecmp (in->ptr + idx, "LIST", 4) == 0)
3064+ {
3065+ fprintf (outfile, ".list\n");
3066+ idx += 4;
3067+ }
3068+ else if (strncasecmp (in->ptr + idx, "NOLIST", 6) == 0)
3069+ {
3070+ fprintf (outfile, ".nolist\n");
3071+ idx += 6;
3072+ }
3073+ idx++;
3074+ }
3075+}
3076+
3077+/* .head */
3078+
3079+static void
3080+do_heading (idx, in)
3081+ int idx;
3082+ sb *in;
3083+{
3084+ sb head;
3085+ sb_new (&head);
3086+ idx = getstring (idx, in, &head);
3087+ fprintf (outfile, ".title \"%s\"\n", sb_name (&head));
3088+ sb_kill (&head);
3089+}
3090+
3091+/* .page */
3092+
3093+static void
3094+do_page ()
3095+{
3096+ fprintf (outfile, ".eject\n");
3097+}
3098+
3099+/* .form [lin=<value>] [col=<value>] */
3100+
3101+static void
3102+do_form (idx, in)
3103+ int idx;
3104+ sb *in;
3105+{
3106+ int lines = 60;
3107+ int columns = 132;
3108+ idx = sb_skip_white (idx, in);
3109+
3110+ while (idx < in->len)
3111+ {
3112+
3113+ if (strncasecmp (in->ptr + idx, "LIN=", 4) == 0)
3114+ {
3115+ idx += 4;
3116+ idx = exp_get_abs (_("form LIN= needs absolute expresssion.\n"), idx, in, &lines);
3117+ }
3118+
3119+ if (strncasecmp (in->ptr + idx, _("COL="), 4) == 0)
3120+ {
3121+ idx += 4;
3122+ idx = exp_get_abs (_("form COL= needs absolute expresssion.\n"), idx, in, &columns);
3123+ }
3124+
3125+ idx++;
3126+ }
3127+ fprintf (outfile, ".psize %d,%d\n", lines, columns);
3128+
3129+}
3130+
3131+/* Fetch string from the input stream,
3132+ rules:
3133+ 'Bxyx<whitespace> -> return 'Bxyza
3134+ %<char> -> return string of decimal value of x
3135+ "<string>" -> return string
3136+ xyx<whitespace> -> return xyz
3137+*/
3138+
3139+static int
3140+get_any_string (idx, in, out, expand, pretend_quoted)
3141+ int idx;
3142+ sb *in;
3143+ sb *out;
3144+ int expand;
3145+ int pretend_quoted;
3146+{
3147+ sb_reset (out);
3148+ idx = sb_skip_white (idx, in);
3149+
3150+ if (idx < in->len)
3151+ {
3152+ if (in->len > 2 && in->ptr[idx + 1] == '\'' && ISBASE (in->ptr[idx]))
3153+ {
3154+ while (!ISSEP (in->ptr[idx]))
3155+ sb_add_char (out, in->ptr[idx++]);
3156+ }
3157+ else if (in->ptr[idx] == '%'
3158+ && alternate
3159+ && expand)
3160+ {
3161+ int val;
3162+ char buf[20];
3163+ /* Turns the next expression into a string. */
3164+ /* xgettext: no-c-format */
3165+ idx = exp_get_abs (_("% operator needs absolute expression"),
3166+ idx + 1,
3167+ in,
3168+ &val);
3169+ sprintf (buf, "%d", val);
3170+ sb_add_string (out, buf);
3171+ }
3172+ else if (in->ptr[idx] == '"'
3173+ || in->ptr[idx] == '<'
3174+ || (alternate && in->ptr[idx] == '\''))
3175+ {
3176+ if (alternate && expand)
3177+ {
3178+ /* Keep the quotes. */
3179+ sb_add_char (out, '\"');
3180+
3181+ idx = getstring (idx, in, out);
3182+ sb_add_char (out, '\"');
3183+
3184+ }
3185+ else
3186+ {
3187+ idx = getstring (idx, in, out);
3188+ }
3189+ }
3190+ else
3191+ {
3192+ while (idx < in->len
3193+ && (in->ptr[idx] == '"'
3194+ || in->ptr[idx] == '\''
3195+ || pretend_quoted
3196+ || !ISSEP (in->ptr[idx])))
3197+ {
3198+ if (in->ptr[idx] == '"'
3199+ || in->ptr[idx] == '\'')
3200+ {
3201+ char tchar = in->ptr[idx];
3202+ sb_add_char (out, in->ptr[idx++]);
3203+ while (idx < in->len
3204+ && in->ptr[idx] != tchar)
3205+ sb_add_char (out, in->ptr[idx++]);
3206+ if (idx == in->len)
3207+ return idx;
3208+ }
3209+ sb_add_char (out, in->ptr[idx++]);
3210+ }
3211+ }
3212+ }
3213+
3214+ return idx;
3215+}
3216+
3217+/* Skip along sb in starting at idx, suck off whitespace a ( and more
3218+ whitespace. Return the idx of the next char. */
3219+
3220+static int
3221+skip_openp (idx, in)
3222+ int idx;
3223+ sb *in;
3224+{
3225+ idx = sb_skip_white (idx, in);
3226+ if (in->ptr[idx] != '(')
3227+ ERROR ((stderr, _("misplaced ( .\n")));
3228+ idx = sb_skip_white (idx + 1, in);
3229+ return idx;
3230+}
3231+
3232+/* Skip along sb in starting at idx, suck off whitespace a ) and more
3233+ whitespace. Return the idx of the next char. */
3234+
3235+static int
3236+skip_closep (idx, in)
3237+ int idx;
3238+ sb *in;
3239+{
3240+ idx = sb_skip_white (idx, in);
3241+ if (in->ptr[idx] != ')')
3242+ ERROR ((stderr, _("misplaced ).\n")));
3243+ idx = sb_skip_white (idx + 1, in);
3244+ return idx;
3245+}
3246+
3247+/* .len */
3248+
3249+static int
3250+dolen (idx, in, out)
3251+ int idx;
3252+ sb *in;
3253+ sb *out;
3254+{
3255+
3256+ sb stringout;
3257+ char buffer[10];
3258+
3259+ sb_new (&stringout);
3260+ idx = skip_openp (idx, in);
3261+ idx = get_and_process (idx, in, &stringout);
3262+ idx = skip_closep (idx, in);
3263+ sprintf (buffer, "%d", stringout.len);
3264+ sb_add_string (out, buffer);
3265+
3266+ sb_kill (&stringout);
3267+ return idx;
3268+}
3269+
3270+/* .instr */
3271+
3272+static int
3273+doinstr (idx, in, out)
3274+ int idx;
3275+ sb *in;
3276+ sb *out;
3277+{
3278+ sb string;
3279+ sb search;
3280+ int i;
3281+ int start;
3282+ int res;
3283+ char buffer[10];
3284+
3285+ sb_new (&string);
3286+ sb_new (&search);
3287+ idx = skip_openp (idx, in);
3288+ idx = get_and_process (idx, in, &string);
3289+ idx = sb_skip_comma (idx, in);
3290+ idx = get_and_process (idx, in, &search);
3291+ idx = sb_skip_comma (idx, in);
3292+ if (ISDIGIT (in->ptr[idx]))
3293+ {
3294+ idx = exp_get_abs (_(".instr needs absolute expresson.\n"), idx, in, &start);
3295+ }
3296+ else
3297+ {
3298+ start = 0;
3299+ }
3300+ idx = skip_closep (idx, in);
3301+ res = -1;
3302+ for (i = start; i < string.len; i++)
3303+ {
3304+ if (strncmp (string.ptr + i, search.ptr, search.len) == 0)
3305+ {
3306+ res = i;
3307+ break;
3308+ }
3309+ }
3310+ sprintf (buffer, "%d", res);
3311+ sb_add_string (out, buffer);
3312+ sb_kill (&string);
3313+ sb_kill (&search);
3314+ return idx;
3315+}
3316+
3317+static int
3318+dosubstr (idx, in, out)
3319+ int idx;
3320+ sb *in;
3321+ sb *out;
3322+{
3323+ sb string;
3324+ int pos;
3325+ int len;
3326+ sb_new (&string);
3327+
3328+ idx = skip_openp (idx, in);
3329+ idx = get_and_process (idx, in, &string);
3330+ idx = sb_skip_comma (idx, in);
3331+ idx = exp_get_abs (_("need absolute position.\n"), idx, in, &pos);
3332+ idx = sb_skip_comma (idx, in);
3333+ idx = exp_get_abs (_("need absolute length.\n"), idx, in, &len);
3334+ idx = skip_closep (idx, in);
3335+
3336+ if (len < 0 || pos < 0 ||
3337+ pos > string.len
3338+ || pos + len > string.len)
3339+ {
3340+ sb_add_string (out, " ");
3341+ }
3342+ else
3343+ {
3344+ sb_add_char (out, '"');
3345+ while (len > 0)
3346+ {
3347+ sb_add_char (out, string.ptr[pos++]);
3348+ len--;
3349+ }
3350+ sb_add_char (out, '"');
3351+ }
3352+ sb_kill (&string);
3353+ return idx;
3354+}
3355+
3356+/* Scan line, change tokens in the hash table to their replacements. */
3357+
3358+static void
3359+process_assigns (idx, in, buf)
3360+ int idx;
3361+ sb *in;
3362+ sb *buf;
3363+{
3364+ while (idx < in->len)
3365+ {
3366+ hash_entry *ptr;
3367+ if (in->ptr[idx] == '\\'
3368+ && idx + 1 < in->len
3369+ && in->ptr[idx + 1] == '(')
3370+ {
3371+ do
3372+ {
3373+ sb_add_char (buf, in->ptr[idx]);
3374+ idx++;
3375+ }
3376+ while (idx < in->len && in->ptr[idx - 1] != ')');
3377+ }
3378+ else if (in->ptr[idx] == '\\'
3379+ && idx + 1 < in->len
3380+ && in->ptr[idx + 1] == '&')
3381+ {
3382+ idx = condass_lookup_name (in, idx + 2, buf, 1);
3383+ }
3384+ else if (in->ptr[idx] == '\\'
3385+ && idx + 1 < in->len
3386+ && in->ptr[idx + 1] == '$')
3387+ {
3388+ idx = condass_lookup_name (in, idx + 2, buf, 0);
3389+ }
3390+ else if (idx + 3 < in->len
3391+ && in->ptr[idx] == '.'
3392+ && TOUPPER (in->ptr[idx + 1]) == 'L'
3393+ && TOUPPER (in->ptr[idx + 2]) == 'E'
3394+ && TOUPPER (in->ptr[idx + 3]) == 'N')
3395+ idx = dolen (idx + 4, in, buf);
3396+ else if (idx + 6 < in->len
3397+ && in->ptr[idx] == '.'
3398+ && TOUPPER (in->ptr[idx + 1]) == 'I'
3399+ && TOUPPER (in->ptr[idx + 2]) == 'N'
3400+ && TOUPPER (in->ptr[idx + 3]) == 'S'
3401+ && TOUPPER (in->ptr[idx + 4]) == 'T'
3402+ && TOUPPER (in->ptr[idx + 5]) == 'R')
3403+ idx = doinstr (idx + 6, in, buf);
3404+ else if (idx + 7 < in->len
3405+ && in->ptr[idx] == '.'
3406+ && TOUPPER (in->ptr[idx + 1]) == 'S'
3407+ && TOUPPER (in->ptr[idx + 2]) == 'U'
3408+ && TOUPPER (in->ptr[idx + 3]) == 'B'
3409+ && TOUPPER (in->ptr[idx + 4]) == 'S'
3410+ && TOUPPER (in->ptr[idx + 5]) == 'T'
3411+ && TOUPPER (in->ptr[idx + 6]) == 'R')
3412+ idx = dosubstr (idx + 7, in, buf);
3413+ else if (ISFIRSTCHAR (in->ptr[idx]))
3414+ {
3415+ /* May be a simple name subsitution, see if we have a word. */
3416+ sb acc;
3417+ int cur = idx + 1;
3418+ while (cur < in->len
3419+ && (ISNEXTCHAR (in->ptr[cur])))
3420+ cur++;
3421+
3422+ sb_new (&acc);
3423+ sb_add_buffer (&acc, in->ptr + idx, cur - idx);
3424+ ptr = hash_lookup (&assign_hash_table, &acc);
3425+ if (ptr)
3426+ {
3427+ /* Found a definition for it. */
3428+ sb_add_sb (buf, &ptr->value.s);
3429+ }
3430+ else
3431+ {
3432+ /* No definition, just copy the word. */
3433+ sb_add_sb (buf, &acc);
3434+ }
3435+ sb_kill (&acc);
3436+ idx = cur;
3437+ }
3438+ else
3439+ {
3440+ sb_add_char (buf, in->ptr[idx++]);
3441+ }
3442+ }
3443+}
3444+
3445+static int
3446+get_and_process (idx, in, out)
3447+ int idx;
3448+ sb *in;
3449+ sb *out;
3450+{
3451+ sb t;
3452+ sb_new (&t);
3453+ idx = get_any_string (idx, in, &t, 1, 0);
3454+ process_assigns (0, &t, out);
3455+ sb_kill (&t);
3456+ return idx;
3457+}
3458+
3459+static void
3460+process_file ()
3461+{
3462+ sb line;
3463+ sb t1, t2;
3464+ sb acc;
3465+ sb label_in;
3466+ int more;
3467+
3468+ sb_new (&line);
3469+ sb_new (&t1);
3470+ sb_new (&t2);
3471+ sb_new (&acc);
3472+ sb_new (&label_in);
3473+ sb_reset (&line);
3474+ more = get_line (&line);
3475+ while (more)
3476+ {
3477+ /* Find any label and pseudo op that we're intested in. */
3478+ int l;
3479+ if (line.len == 0)
3480+ {
3481+ if (condass_on ())
3482+ fprintf (outfile, "\n");
3483+ }
3484+ else if (mri
3485+ && (line.ptr[0] == '*'
3486+ || line.ptr[0] == '!'))
3487+ {
3488+ /* MRI line comment. */
3489+ fprintf (outfile, "%s", sb_name (&line));
3490+ }
3491+ else
3492+ {
3493+ l = grab_label (&line, &label_in);
3494+ sb_reset (&label);
3495+
3496+ if (line.ptr[l] == ':')
3497+ l++;
3498+ while (ISWHITE (line.ptr[l]) && l < line.len)
3499+ l++;
3500+
3501+ if (label_in.len)
3502+ {
3503+ int do_assigns;
3504+
3505+ /* Munge the label, unless this is EQU or ASSIGN. */
3506+ do_assigns = 1;
3507+ if (l < line.len
3508+ && (line.ptr[l] == '.' || alternate || mri))
3509+ {
3510+ int lx = l;
3511+
3512+ if (line.ptr[lx] == '.')
3513+ ++lx;
3514+ if (lx + 3 <= line.len
3515+ && strncasecmp ("EQU", line.ptr + lx, 3) == 0
3516+ && (lx + 3 == line.len
3517+ || ! ISFIRSTCHAR (line.ptr[lx + 3])))
3518+ do_assigns = 0;
3519+ else if (lx + 6 <= line.len
3520+ && strncasecmp ("ASSIGN", line.ptr + lx, 6) == 0
3521+ && (lx + 6 == line.len
3522+ || ! ISFIRSTCHAR (line.ptr[lx + 6])))
3523+ do_assigns = 0;
3524+ }
3525+
3526+ if (do_assigns)
3527+ process_assigns (0, &label_in, &label);
3528+ else
3529+ sb_add_sb (&label, &label_in);
3530+ }
3531+
3532+ if (l < line.len)
3533+ {
3534+ if (process_pseudo_op (l, &line, &acc))
3535+ {
3536+
3537+ }
3538+ else if (condass_on ())
3539+ {
3540+ if (macro_op (l, &line))
3541+ {
3542+
3543+ }
3544+ else
3545+ {
3546+ {
3547+ if (label.len)
3548+ {
3549+ fprintf (outfile, "%s:\t", sb_name (&label));
3550+ }
3551+ else
3552+ fprintf (outfile, "\t");
3553+ sb_reset (&t1);
3554+ process_assigns (l, &line, &t1);
3555+ sb_reset (&t2);
3556+ change_base (0, &t1, &t2);
3557+ fprintf (outfile, "%s\n", sb_name (&t2));
3558+ }
3559+ }
3560+ }
3561+ }
3562+ else
3563+ {
3564+ /* Only a label on this line. */
3565+ if (label.len && condass_on ())
3566+ {
3567+ fprintf (outfile, "%s:\n", sb_name (&label));
3568+ }
3569+ }
3570+ }
3571+
3572+ if (had_end)
3573+ break;
3574+ sb_reset (&line);
3575+ more = get_line (&line);
3576+ }
3577+
3578+ if (!had_end && !mri)
3579+ WARNING ((stderr, _("END missing from end of file.\n")));
3580+}
3581+
3582+static void
3583+free_old_entry (ptr)
3584+ hash_entry *ptr;
3585+{
3586+ if (ptr)
3587+ {
3588+ if (ptr->type == hash_string)
3589+ sb_kill (&ptr->value.s);
3590+ }
3591+}
3592+
3593+/* name: .ASSIGNA <value> */
3594+
3595+static void
3596+do_assigna (idx, in)
3597+ int idx;
3598+ sb *in;
3599+{
3600+ sb tmp;
3601+ int val;
3602+ sb_new (&tmp);
3603+
3604+ process_assigns (idx, in, &tmp);
3605+ idx = exp_get_abs (_(".ASSIGNA needs constant expression argument.\n"), 0, &tmp, &val);
3606+
3607+ if (!label.len)
3608+ {
3609+ ERROR ((stderr, _(".ASSIGNA without label.\n")));
3610+ }
3611+ else
3612+ {
3613+ hash_entry *ptr = hash_create (&vars, &label);
3614+ free_old_entry (ptr);
3615+ ptr->type = hash_integer;
3616+ ptr->value.i = val;
3617+ }
3618+ sb_kill (&tmp);
3619+}
3620+
3621+/* name: .ASSIGNC <string> */
3622+
3623+static void
3624+do_assignc (idx, in)
3625+ int idx;
3626+ sb *in;
3627+{
3628+ sb acc;
3629+ sb_new (&acc);
3630+ idx = getstring (idx, in, &acc);
3631+
3632+ if (!label.len)
3633+ {
3634+ ERROR ((stderr, _(".ASSIGNS without label.\n")));
3635+ }
3636+ else
3637+ {
3638+ hash_entry *ptr = hash_create (&vars, &label);
3639+ free_old_entry (ptr);
3640+ ptr->type = hash_string;
3641+ sb_new (&ptr->value.s);
3642+ sb_add_sb (&ptr->value.s, &acc);
3643+ }
3644+ sb_kill (&acc);
3645+}
3646+
3647+/* name: .REG (reg) */
3648+
3649+static void
3650+do_reg (idx, in)
3651+ int idx;
3652+ sb *in;
3653+{
3654+ /* Remove reg stuff from inside parens. */
3655+ sb what;
3656+ if (!mri)
3657+ idx = skip_openp (idx, in);
3658+ else
3659+ idx = sb_skip_white (idx, in);
3660+ sb_new (&what);
3661+ while (idx < in->len
3662+ && (mri
3663+ ? ! eol (idx, in)
3664+ : in->ptr[idx] != ')'))
3665+ {
3666+ sb_add_char (&what, in->ptr[idx]);
3667+ idx++;
3668+ }
3669+ hash_add_to_string_table (&assign_hash_table, &label, &what, 1);
3670+ sb_kill (&what);
3671+}
3672+
3673+static int
3674+condass_lookup_name (inbuf, idx, out, warn)
3675+ sb *inbuf;
3676+ int idx;
3677+ sb *out;
3678+ int warn;
3679+{
3680+ hash_entry *ptr;
3681+ sb condass_acc;
3682+ sb_new (&condass_acc);
3683+
3684+ while (idx < inbuf->len
3685+ && ISNEXTCHAR (inbuf->ptr[idx]))
3686+ {
3687+ sb_add_char (&condass_acc, inbuf->ptr[idx++]);
3688+ }
3689+
3690+ if (inbuf->ptr[idx] == '\'')
3691+ idx++;
3692+ ptr = hash_lookup (&vars, &condass_acc);
3693+
3694+ if (!ptr)
3695+ {
3696+ if (warn)
3697+ {
3698+ WARNING ((stderr, _("Can't find preprocessor variable %s.\n"), sb_name (&condass_acc)));
3699+ }
3700+ else
3701+ {
3702+ sb_add_string (out, "0");
3703+ }
3704+ }
3705+ else
3706+ {
3707+ if (ptr->type == hash_integer)
3708+ {
3709+ char buffer[30];
3710+ sprintf (buffer, "%d", ptr->value.i);
3711+ sb_add_string (out, buffer);
3712+ }
3713+ else
3714+ {
3715+ sb_add_sb (out, &ptr->value.s);
3716+ }
3717+ }
3718+ sb_kill (&condass_acc);
3719+ return idx;
3720+}
3721+
3722+#define EQ 1
3723+#define NE 2
3724+#define GE 3
3725+#define LT 4
3726+#define LE 5
3727+#define GT 6
3728+#define NEVER 7
3729+
3730+static int
3731+whatcond (idx, in, val)
3732+ int idx;
3733+ sb *in;
3734+ int *val;
3735+{
3736+ int cond;
3737+
3738+ idx = sb_skip_white (idx, in);
3739+ cond = NEVER;
3740+ if (idx + 1 < in->len)
3741+ {
3742+ char *p;
3743+ char a, b;
3744+
3745+ p = in->ptr + idx;
3746+ a = TOUPPER (p[0]);
3747+ b = TOUPPER (p[1]);
3748+ if (a == 'E' && b == 'Q')
3749+ cond = EQ;
3750+ else if (a == 'N' && b == 'E')
3751+ cond = NE;
3752+ else if (a == 'L' && b == 'T')
3753+ cond = LT;
3754+ else if (a == 'L' && b == 'E')
3755+ cond = LE;
3756+ else if (a == 'G' && b == 'T')
3757+ cond = GT;
3758+ else if (a == 'G' && b == 'E')
3759+ cond = GE;
3760+ }
3761+ if (cond == NEVER)
3762+ {
3763+ ERROR ((stderr, _("Comparison operator must be one of EQ, NE, LT, LE, GT or GE.\n")));
3764+ cond = NEVER;
3765+ }
3766+ idx = sb_skip_white (idx + 2, in);
3767+ *val = cond;
3768+ return idx;
3769+}
3770+
3771+static int
3772+istrue (idx, in)
3773+ int idx;
3774+ sb *in;
3775+{
3776+ int res;
3777+ sb acc_a;
3778+ sb cond;
3779+ sb acc_b;
3780+ sb_new (&acc_a);
3781+ sb_new (&cond);
3782+ sb_new (&acc_b);
3783+ idx = sb_skip_white (idx, in);
3784+
3785+ if (in->ptr[idx] == '"')
3786+ {
3787+ int cond;
3788+ int same;
3789+ /* This is a string comparision. */
3790+ idx = getstring (idx, in, &acc_a);
3791+ idx = whatcond (idx, in, &cond);
3792+ idx = getstring (idx, in, &acc_b);
3793+ same = acc_a.len == acc_b.len
3794+ && (strncmp (acc_a.ptr, acc_b.ptr, acc_a.len) == 0);
3795+
3796+ if (cond != EQ && cond != NE)
3797+ {
3798+ ERROR ((stderr, _("Comparison operator for strings must be EQ or NE\n")));
3799+ res = 0;
3800+ }
3801+ else
3802+ res = (cond != EQ) ^ same;
3803+ }
3804+ else
3805+ /* This is a numeric expression. */
3806+ {
3807+ int vala;
3808+ int valb;
3809+ int cond;
3810+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &vala);
3811+ idx = whatcond (idx, in, &cond);
3812+ idx = sb_skip_white (idx, in);
3813+ if (in->ptr[idx] == '"')
3814+ {
3815+ WARNING ((stderr, _("String compared against expression.\n")));
3816+ res = 0;
3817+ }
3818+ else
3819+ {
3820+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"), idx, in, &valb);
3821+ switch (cond)
3822+ {
3823+ default:
3824+ res = 42;
3825+ break;
3826+ case EQ:
3827+ res = vala == valb;
3828+ break;
3829+ case NE:
3830+ res = vala != valb;
3831+ break;
3832+ case LT:
3833+ res = vala < valb;
3834+ break;
3835+ case LE:
3836+ res = vala <= valb;
3837+ break;
3838+ case GT:
3839+ res = vala > valb;
3840+ break;
3841+ case GE:
3842+ res = vala >= valb;
3843+ break;
3844+ case NEVER:
3845+ res = 0;
3846+ break;
3847+ }
3848+ }
3849+ }
3850+
3851+ sb_kill (&acc_a);
3852+ sb_kill (&cond);
3853+ sb_kill (&acc_b);
3854+ return res;
3855+}
3856+
3857+/* .AIF */
3858+
3859+static void
3860+do_aif (idx, in)
3861+ int idx;
3862+ sb *in;
3863+{
3864+ if (ifi >= IFNESTING)
3865+ {
3866+ FATAL ((stderr, _("AIF nesting unreasonable.\n")));
3867+ }
3868+ ifi++;
3869+ ifstack[ifi].on = ifstack[ifi - 1].on ? istrue (idx, in) : 0;
3870+ ifstack[ifi].hadelse = 0;
3871+}
3872+
3873+/* .AELSE */
3874+
3875+static void
3876+do_aelse ()
3877+{
3878+ ifstack[ifi].on = ifstack[ifi - 1].on ? !ifstack[ifi].on : 0;
3879+ if (ifstack[ifi].hadelse)
3880+ {
3881+ ERROR ((stderr, _("Multiple AELSEs in AIF.\n")));
3882+ }
3883+ ifstack[ifi].hadelse = 1;
3884+}
3885+
3886+/* .AENDI */
3887+
3888+static void
3889+do_aendi ()
3890+{
3891+ if (ifi != 0)
3892+ {
3893+ ifi--;
3894+ }
3895+ else
3896+ {
3897+ ERROR ((stderr, _("AENDI without AIF.\n")));
3898+ }
3899+}
3900+
3901+static int
3902+condass_on ()
3903+{
3904+ return ifstack[ifi].on;
3905+}
3906+
3907+/* MRI IFEQ, IFNE, IFLT, IFLE, IFGE, IFGT. */
3908+
3909+static void
3910+do_if (idx, in, cond)
3911+ int idx;
3912+ sb *in;
3913+ int cond;
3914+{
3915+ int val;
3916+ int res;
3917+
3918+ if (ifi >= IFNESTING)
3919+ {
3920+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
3921+ }
3922+
3923+ idx = exp_get_abs (_("Conditional operator must have absolute operands.\n"),
3924+ idx, in, &val);
3925+ switch (cond)
3926+ {
3927+ default:
3928+ case EQ: res = val == 0; break;
3929+ case NE: res = val != 0; break;
3930+ case LT: res = val < 0; break;
3931+ case LE: res = val <= 0; break;
3932+ case GE: res = val >= 0; break;
3933+ case GT: res = val > 0; break;
3934+ }
3935+
3936+ ifi++;
3937+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
3938+ ifstack[ifi].hadelse = 0;
3939+}
3940+
3941+/* Get a string for the MRI IFC or IFNC pseudo-ops. */
3942+
3943+static int
3944+get_mri_string (idx, in, val, terminator)
3945+ int idx;
3946+ sb *in;
3947+ sb *val;
3948+ int terminator;
3949+{
3950+ idx = sb_skip_white (idx, in);
3951+
3952+ if (idx < in->len
3953+ && in->ptr[idx] == '\'')
3954+ {
3955+ sb_add_char (val, '\'');
3956+ for (++idx; idx < in->len; ++idx)
3957+ {
3958+ sb_add_char (val, in->ptr[idx]);
3959+ if (in->ptr[idx] == '\'')
3960+ {
3961+ ++idx;
3962+ if (idx >= in->len
3963+ || in->ptr[idx] != '\'')
3964+ break;
3965+ }
3966+ }
3967+ idx = sb_skip_white (idx, in);
3968+ }
3969+ else
3970+ {
3971+ int i;
3972+
3973+ while (idx < in->len
3974+ && in->ptr[idx] != terminator)
3975+ {
3976+ sb_add_char (val, in->ptr[idx]);
3977+ ++idx;
3978+ }
3979+ i = val->len - 1;
3980+ while (i >= 0 && ISWHITE (val->ptr[i]))
3981+ --i;
3982+ val->len = i + 1;
3983+ }
3984+
3985+ return idx;
3986+}
3987+
3988+/* MRI IFC, IFNC */
3989+
3990+static void
3991+do_ifc (idx, in, ifnc)
3992+ int idx;
3993+ sb *in;
3994+ int ifnc;
3995+{
3996+ sb first;
3997+ sb second;
3998+ int res;
3999+
4000+ if (ifi >= IFNESTING)
4001+ {
4002+ FATAL ((stderr, _("IF nesting unreasonable.\n")));
4003+ }
4004+
4005+ sb_new (&first);
4006+ sb_new (&second);
4007+
4008+ idx = get_mri_string (idx, in, &first, ',');
4009+
4010+ if (idx >= in->len || in->ptr[idx] != ',')
4011+ {
4012+ ERROR ((stderr, _("Bad format for IF or IFNC.\n")));
4013+ return;
4014+ }
4015+
4016+ idx = get_mri_string (idx + 1, in, &second, ';');
4017+
4018+ res = (first.len == second.len
4019+ && strncmp (first.ptr, second.ptr, first.len) == 0);
4020+ res ^= ifnc;
4021+
4022+ ifi++;
4023+ ifstack[ifi].on = ifstack[ifi - 1].on ? res : 0;
4024+ ifstack[ifi].hadelse = 0;
4025+}
4026+
4027+/* .ENDR */
4028+
4029+static void
4030+do_aendr ()
4031+{
4032+ if (!mri)
4033+ ERROR ((stderr, _("AENDR without a AREPEAT.\n")));
4034+ else
4035+ ERROR ((stderr, _("ENDR without a REPT.\n")));
4036+}
4037+
4038+/* .AWHILE */
4039+
4040+static void
4041+do_awhile (idx, in)
4042+ int idx;
4043+ sb *in;
4044+{
4045+ int line = linecount ();
4046+ sb exp;
4047+ sb sub;
4048+ int doit;
4049+
4050+ sb_new (&sub);
4051+ sb_new (&exp);
4052+
4053+ process_assigns (idx, in, &exp);
4054+ doit = istrue (0, &exp);
4055+
4056+ if (! buffer_and_nest ("AWHILE", "AENDW", &sub, get_line))
4057+ FATAL ((stderr, _("AWHILE without a AENDW at %d.\n"), line - 1));
4058+
4059+ /* Turn
4060+ .AWHILE exp
4061+ foo
4062+ .AENDW
4063+ into
4064+ foo
4065+ .AWHILE exp
4066+ foo
4067+ .ENDW
4068+ */
4069+
4070+ if (doit)
4071+ {
4072+ int index = include_next_index ();
4073+
4074+ sb copy;
4075+ sb_new (&copy);
4076+ sb_add_sb (&copy, &sub);
4077+ sb_add_sb (&copy, in);
4078+ sb_add_string (&copy, "\n");
4079+ sb_add_sb (&copy, &sub);
4080+ sb_add_string (&copy, "\t.AENDW\n");
4081+ /* Push another WHILE. */
4082+ include_buf (&exp, &copy, include_while, index);
4083+ sb_kill (&copy);
4084+ }
4085+ sb_kill (&exp);
4086+ sb_kill (&sub);
4087+}
4088+
4089+/* .AENDW */
4090+
4091+static void
4092+do_aendw ()
4093+{
4094+ ERROR ((stderr, _("AENDW without a AENDW.\n")));
4095+}
4096+
4097+/* .EXITM
4098+
4099+ Pop things off the include stack until the type and index changes. */
4100+
4101+static void
4102+do_exitm ()
4103+{
4104+ include_type type = sp->type;
4105+ if (type == include_repeat
4106+ || type == include_while
4107+ || type == include_macro)
4108+ {
4109+ int index = sp->index;
4110+ include_pop ();
4111+ while (sp->index == index
4112+ && sp->type == type)
4113+ {
4114+ include_pop ();
4115+ }
4116+ }
4117+}
4118+
4119+/* .AREPEAT */
4120+
4121+static void
4122+do_arepeat (idx, in)
4123+ int idx;
4124+ sb *in;
4125+{
4126+ int line = linecount ();
4127+ sb exp; /* Buffer with expression in it. */
4128+ sb copy; /* Expanded repeat block. */
4129+ sb sub; /* Contents of AREPEAT. */
4130+ int rc;
4131+ int ret;
4132+ char buffer[30];
4133+
4134+ sb_new (&exp);
4135+ sb_new (&copy);
4136+ sb_new (&sub);
4137+ process_assigns (idx, in, &exp);
4138+ idx = exp_get_abs (_("AREPEAT must have absolute operand.\n"), 0, &exp, &rc);
4139+ if (!mri)
4140+ ret = buffer_and_nest ("AREPEAT", "AENDR", &sub, get_line);
4141+ else
4142+ ret = buffer_and_nest ("REPT", "ENDR", &sub, get_line);
4143+ if (! ret)
4144+ FATAL ((stderr, _("AREPEAT without a AENDR at %d.\n"), line - 1));
4145+ if (rc > 0)
4146+ {
4147+ /* Push back the text following the repeat, and another repeat block
4148+ so
4149+ .AREPEAT 20
4150+ foo
4151+ .AENDR
4152+ gets turned into
4153+ foo
4154+ .AREPEAT 19
4155+ foo
4156+ .AENDR
4157+ */
4158+ int index = include_next_index ();
4159+ sb_add_sb (&copy, &sub);
4160+ if (rc > 1)
4161+ {
4162+ if (!mri)
4163+ sprintf (buffer, "\t.AREPEAT %d\n", rc - 1);
4164+ else
4165+ sprintf (buffer, "\tREPT %d\n", rc - 1);
4166+ sb_add_string (&copy, buffer);
4167+ sb_add_sb (&copy, &sub);
4168+ if (!mri)
4169+ sb_add_string (&copy, " .AENDR\n");
4170+ else
4171+ sb_add_string (&copy, " ENDR\n");
4172+ }
4173+
4174+ include_buf (&exp, &copy, include_repeat, index);
4175+ }
4176+ sb_kill (&exp);
4177+ sb_kill (&sub);
4178+ sb_kill (&copy);
4179+}
4180+
4181+/* .ENDM */
4182+
4183+static void
4184+do_endm ()
4185+{
4186+ ERROR ((stderr, _(".ENDM without a matching .MACRO.\n")));
4187+}
4188+
4189+/* MRI IRP pseudo-op. */
4190+
4191+static void
4192+do_irp (idx, in, irpc)
4193+ int idx;
4194+ sb *in;
4195+ int irpc;
4196+{
4197+ const char *err;
4198+ sb out;
4199+
4200+ sb_new (&out);
4201+
4202+ err = expand_irp (irpc, idx, in, &out, get_line, comment_char);
4203+ if (err != NULL)
4204+ ERROR ((stderr, "%s\n", err));
4205+
4206+ fprintf (outfile, "%s", sb_terminate (&out));
4207+
4208+ sb_kill (&out);
4209+}
4210+
4211+/* Macro processing. */
4212+
4213+/* Parse off LOCAL n1, n2,... Invent a label name for it. */
4214+
4215+static void
4216+do_local (idx, line)
4217+ int idx ATTRIBUTE_UNUSED;
4218+ sb *line ATTRIBUTE_UNUSED;
4219+{
4220+ ERROR ((stderr, _("LOCAL outside of MACRO")));
4221+}
4222+
4223+static void
4224+do_macro (idx, in)
4225+ int idx;
4226+ sb *in;
4227+{
4228+ const char *err;
4229+ int line = linecount ();
4230+
486f726b 4231+ err = define_macro (idx, in, &label, get_line, "[gasp]", line, (const char **) NULL);
0087dcf3
JB
4232+ if (err != NULL)
4233+ ERROR ((stderr, _("macro at line %d: %s\n"), line - 1, err));
4234+}
4235+
4236+static int
4237+macro_op (idx, in)
4238+ int idx;
4239+ sb *in;
4240+{
4241+ const char *err;
4242+ sb out;
4243+ sb name;
4244+
4245+ if (! macro_defined)
4246+ return 0;
4247+
4248+ sb_terminate (in);
4249+ if (! check_macro (in->ptr + idx, &out, comment_char, &err, NULL))
4250+ return 0;
4251+
4252+ if (err != NULL)
4253+ ERROR ((stderr, "%s\n", err));
4254+
4255+ sb_new (&name);
4256+ sb_add_string (&name, _("macro expansion"));
4257+
4258+ include_buf (&name, &out, include_macro, include_next_index ());
4259+
4260+ sb_kill (&name);
4261+ sb_kill (&out);
4262+
4263+ return 1;
4264+}
4265+
4266+/* String handling. */
4267+
4268+static int
4269+getstring (idx, in, acc)
4270+ int idx;
4271+ sb *in;
4272+ sb *acc;
4273+{
4274+ idx = sb_skip_white (idx, in);
4275+
4276+ while (idx < in->len
4277+ && (in->ptr[idx] == '"'
4278+ || in->ptr[idx] == '<'
4279+ || (in->ptr[idx] == '\'' && alternate)))
4280+ {
4281+ if (in->ptr[idx] == '<')
4282+ {
4283+ if (alternate || mri)
4284+ {
4285+ int nest = 0;
4286+ idx++;
4287+ while ((in->ptr[idx] != '>' || nest)
4288+ && idx < in->len)
4289+ {
4290+ if (in->ptr[idx] == '!')
4291+ {
4292+ idx++;
4293+ sb_add_char (acc, in->ptr[idx++]);
4294+ }
4295+ else
4296+ {
4297+ if (in->ptr[idx] == '>')
4298+ nest--;
4299+ if (in->ptr[idx] == '<')
4300+ nest++;
4301+ sb_add_char (acc, in->ptr[idx++]);
4302+ }
4303+ }
4304+ idx++;
4305+ }
4306+ else
4307+ {
4308+ int code;
4309+ idx++;
4310+ idx = exp_get_abs (_("Character code in string must be absolute expression.\n"),
4311+ idx, in, &code);
4312+ sb_add_char (acc, code);
4313+
4314+ if (in->ptr[idx] != '>')
4315+ ERROR ((stderr, _("Missing > for character code.\n")));
4316+ idx++;
4317+ }
4318+ }
4319+ else if (in->ptr[idx] == '"' || in->ptr[idx] == '\'')
4320+ {
4321+ char tchar = in->ptr[idx];
4322+ idx++;
4323+ while (idx < in->len)
4324+ {
4325+ if (alternate && in->ptr[idx] == '!')
4326+ {
4327+ idx++;
4328+ sb_add_char (acc, in->ptr[idx++]);
4329+ }
4330+ else
4331+ {
4332+ if (in->ptr[idx] == tchar)
4333+ {
4334+ idx++;
4335+ if (idx >= in->len || in->ptr[idx] != tchar)
4336+ break;
4337+ }
4338+ sb_add_char (acc, in->ptr[idx]);
4339+ idx++;
4340+ }
4341+ }
4342+ }
4343+ }
4344+
4345+ return idx;
4346+}
4347+
4348+/* .SDATA[C|Z] <string> */
4349+
4350+static void
4351+do_sdata (idx, in, type)
4352+ int idx;
4353+ sb *in;
4354+ int type;
4355+{
4356+ int nc = 0;
4357+ int pidx = -1;
4358+ sb acc;
4359+ sb_new (&acc);
4360+ fprintf (outfile, ".byte\t");
4361+
4362+ while (!eol (idx, in))
4363+ {
4364+ int i;
4365+ sb_reset (&acc);
4366+ idx = sb_skip_white (idx, in);
4367+ while (!eol (idx, in))
4368+ {
4369+ pidx = idx = get_any_string (idx, in, &acc, 0, 1);
4370+ if (type == 'c')
4371+ {
4372+ if (acc.len > 255)
4373+ {
4374+ ERROR ((stderr, _("string for SDATAC longer than 255 characters (%d).\n"), acc.len));
4375+ }
4376+ fprintf (outfile, "%d", acc.len);
4377+ nc = 1;
4378+ }
4379+
4380+ for (i = 0; i < acc.len; i++)
4381+ {
4382+ if (nc)
4383+ {
4384+ fprintf (outfile, ",");
4385+ }
4386+ fprintf (outfile, "%d", acc.ptr[i]);
4387+ nc = 1;
4388+ }
4389+
4390+ if (type == 'z')
4391+ {
4392+ if (nc)
4393+ fprintf (outfile, ",");
4394+ fprintf (outfile, "0");
4395+ }
4396+ idx = sb_skip_comma (idx, in);
4397+ if (idx == pidx)
4398+ break;
4399+ }
4400+ if (!alternate && in->ptr[idx] != ',' && idx != in->len)
4401+ {
4402+ fprintf (outfile, "\n");
4403+ ERROR ((stderr, _("illegal character in SDATA line (0x%x).\n"),
4404+ in->ptr[idx]));
4405+ break;
4406+ }
4407+ idx++;
4408+ }
4409+ sb_kill (&acc);
4410+ fprintf (outfile, "\n");
4411+}
4412+
4413+/* .SDATAB <count> <string> */
4414+
4415+static void
4416+do_sdatab (idx, in)
4417+ int idx;
4418+ sb *in;
4419+{
4420+ int repeat;
4421+ int i;
4422+ sb acc;
4423+ sb_new (&acc);
4424+
4425+ idx = exp_get_abs (_("Must have absolute SDATAB repeat count.\n"), idx, in, &repeat);
4426+ if (repeat <= 0)
4427+ {
4428+ ERROR ((stderr, _("Must have positive SDATAB repeat count (%d).\n"), repeat));
4429+ repeat = 1;
4430+ }
4431+
4432+ idx = sb_skip_comma (idx, in);
4433+ idx = getstring (idx, in, &acc);
4434+
4435+ for (i = 0; i < repeat; i++)
4436+ {
4437+ if (i)
4438+ fprintf (outfile, "\t");
4439+ fprintf (outfile, ".byte\t");
4440+ sb_print (outfile, &acc);
4441+ fprintf (outfile, "\n");
4442+ }
4443+ sb_kill (&acc);
4444+
4445+}
4446+
4447+static int
4448+new_file (name)
4449+ const char *name;
4450+{
4451+ FILE *newone = fopen (name, "r");
4452+ if (!newone)
4453+ return 0;
4454+
4455+ if (isp == MAX_INCLUDES)
4456+ FATAL ((stderr, _("Unreasonable include depth (%ld).\n"), (long) isp));
4457+
4458+ sp++;
4459+ sp->handle = newone;
4460+
4461+ sb_new (&sp->name);
4462+ sb_add_string (&sp->name, name);
4463+
4464+ sp->linecount = 1;
4465+ sp->pushback_index = 0;
4466+ sp->type = include_file;
4467+ sp->index = 0;
4468+ sb_new (&sp->pushback);
4469+ return 1;
4470+}
4471+
4472+static void
4473+do_include (idx, in)
4474+ int idx;
4475+ sb *in;
4476+{
4477+ sb t;
4478+ sb cat;
4479+ include_path *includes;
4480+
4481+ sb_new (&t);
4482+ sb_new (&cat);
4483+
4484+ if (! mri)
4485+ idx = getstring (idx, in, &t);
4486+ else
4487+ {
4488+ idx = sb_skip_white (idx, in);
4489+ while (idx < in->len && ! ISWHITE (in->ptr[idx]))
4490+ {
4491+ sb_add_char (&t, in->ptr[idx]);
4492+ ++idx;
4493+ }
4494+ }
4495+
4496+ for (includes = paths_head; includes; includes = includes->next)
4497+ {
4498+ sb_reset (&cat);
4499+ sb_add_sb (&cat, &includes->path);
4500+ sb_add_char (&cat, '/');
4501+ sb_add_sb (&cat, &t);
4502+ if (new_file (sb_name (&cat)))
4503+ {
4504+ break;
4505+ }
4506+ }
4507+ if (!includes)
4508+ {
4509+ if (! new_file (sb_name (&t)))
4510+ FATAL ((stderr, _("Can't open include file `%s'.\n"), sb_name (&t)));
4511+ }
4512+ sb_kill (&cat);
4513+ sb_kill (&t);
4514+}
4515+
4516+static void
4517+include_pop ()
4518+{
4519+ if (sp != include_stack)
4520+ {
4521+ if (sp->handle)
4522+ fclose (sp->handle);
4523+ sp--;
4524+ }
4525+}
4526+
4527+/* Get the next character from the include stack. If there's anything
4528+ in the pushback buffer, take that first. If we're at eof, pop from
4529+ the stack and try again. Keep the linecount up to date. */
4530+
4531+static int
4532+get ()
4533+{
4534+ int r;
4535+
4536+ if (sp->pushback.len != sp->pushback_index)
4537+ {
4538+ r = (char) (sp->pushback.ptr[sp->pushback_index++]);
4539+ /* When they've all gone, reset the pointer. */
4540+ if (sp->pushback_index == sp->pushback.len)
4541+ {
4542+ sp->pushback.len = 0;
4543+ sp->pushback_index = 0;
4544+ }
4545+ }
4546+ else if (sp->handle)
4547+ {
4548+ r = getc (sp->handle);
4549+ }
4550+ else
4551+ r = EOF;
4552+
4553+ if (r == EOF && isp)
4554+ {
4555+ include_pop ();
4556+ r = get ();
4557+ while (r == EOF && isp)
4558+ {
4559+ include_pop ();
4560+ r = get ();
4561+ }
4562+ return r;
4563+ }
4564+ if (r == '\n')
4565+ {
4566+ sp->linecount++;
4567+ }
4568+
4569+ return r;
4570+}
4571+
4572+static int
4573+linecount ()
4574+{
4575+ return sp->linecount;
4576+}
4577+
4578+static int
4579+include_next_index ()
4580+{
4581+ static int index;
4582+ if (!unreasonable
4583+ && index > MAX_REASONABLE)
4584+ FATAL ((stderr, _("Unreasonable expansion (-u turns off check).\n")));
4585+ return ++index;
4586+}
4587+
4588+/* Initialize the chartype vector. */
4589+
4590+static void
4591+chartype_init ()
4592+{
4593+ int x;
4594+ for (x = 0; x < 256; x++)
4595+ {
4596+ if (ISALPHA (x) || x == '_' || x == '$')
4597+ chartype[x] |= FIRSTBIT;
4598+
4599+ if (mri && x == '.')
4600+ chartype[x] |= FIRSTBIT;
4601+
4602+ if (ISDIGIT (x) || ISALPHA (x) || x == '_' || x == '$')
4603+ chartype[x] |= NEXTBIT;
4604+
4605+ if (x == ' ' || x == '\t' || x == ',' || x == '"' || x == ';'
4606+ || x == '"' || x == '<' || x == '>' || x == ')' || x == '(')
4607+ chartype[x] |= SEPBIT;
4608+
4609+ if (x == 'b' || x == 'B'
4610+ || x == 'q' || x == 'Q'
4611+ || x == 'h' || x == 'H'
4612+ || x == 'd' || x == 'D')
4613+ chartype [x] |= BASEBIT;
4614+
4615+ if (x == ' ' || x == '\t')
4616+ chartype[x] |= WHITEBIT;
4617+
4618+ if (x == comment_char)
4619+ chartype[x] |= COMMENTBIT;
4620+ }
4621+}
4622+
4623+/* What to do with all the keywords. */
4624+#define PROCESS 0x1000 /* Run substitution over the line. */
4625+#define LAB 0x2000 /* Spit out the label. */
4626+
4627+#define K_EQU (PROCESS|1)
4628+#define K_ASSIGN (PROCESS|2)
4629+#define K_REG (PROCESS|3)
4630+#define K_ORG (PROCESS|4)
4631+#define K_RADIX (PROCESS|5)
4632+#define K_DATA (LAB|PROCESS|6)
4633+#define K_DATAB (LAB|PROCESS|7)
4634+#define K_SDATA (LAB|PROCESS|8)
4635+#define K_SDATAB (LAB|PROCESS|9)
4636+#define K_SDATAC (LAB|PROCESS|10)
4637+#define K_SDATAZ (LAB|PROCESS|11)
4638+#define K_RES (LAB|PROCESS|12)
4639+#define K_SRES (LAB|PROCESS|13)
4640+#define K_SRESC (LAB|PROCESS|14)
4641+#define K_SRESZ (LAB|PROCESS|15)
4642+#define K_EXPORT (LAB|PROCESS|16)
4643+#define K_GLOBAL (LAB|PROCESS|17)
4644+#define K_PRINT (LAB|PROCESS|19)
4645+#define K_FORM (LAB|PROCESS|20)
4646+#define K_HEADING (LAB|PROCESS|21)
4647+#define K_PAGE (LAB|PROCESS|22)
4648+#define K_IMPORT (LAB|PROCESS|23)
4649+#define K_PROGRAM (LAB|PROCESS|24)
4650+#define K_END (PROCESS|25)
4651+#define K_INCLUDE (PROCESS|26)
4652+#define K_IGNORED (PROCESS|27)
4653+#define K_ASSIGNA (PROCESS|28)
4654+#define K_ASSIGNC (29)
4655+#define K_AIF (PROCESS|30)
4656+#define K_AELSE (PROCESS|31)
4657+#define K_AENDI (PROCESS|32)
4658+#define K_AREPEAT (PROCESS|33)
4659+#define K_AENDR (PROCESS|34)
4660+#define K_AWHILE (35)
4661+#define K_AENDW (PROCESS|36)
4662+#define K_EXITM (37)
4663+#define K_MACRO (PROCESS|38)
4664+#define K_ENDM (39)
4665+#define K_ALIGN (PROCESS|LAB|40)
4666+#define K_ALTERNATE (41)
4667+#define K_DB (LAB|PROCESS|42)
4668+#define K_DW (LAB|PROCESS|43)
4669+#define K_DL (LAB|PROCESS|44)
4670+#define K_LOCAL (45)
4671+#define K_IFEQ (PROCESS|46)
4672+#define K_IFNE (PROCESS|47)
4673+#define K_IFLT (PROCESS|48)
4674+#define K_IFLE (PROCESS|49)
4675+#define K_IFGE (PROCESS|50)
4676+#define K_IFGT (PROCESS|51)
4677+#define K_IFC (PROCESS|52)
4678+#define K_IFNC (PROCESS|53)
4679+#define K_IRP (PROCESS|54)
4680+#define K_IRPC (PROCESS|55)
4681+
4682+struct keyword {
4683+ char *name;
4684+ int code;
4685+ int extra;
4686+};
4687+
4688+static struct keyword kinfo[] = {
4689+ { "EQU", K_EQU, 0 },
4690+ { "ALTERNATE", K_ALTERNATE, 0 },
4691+ { "ASSIGN", K_ASSIGN, 0 },
4692+ { "REG", K_REG, 0 },
4693+ { "ORG", K_ORG, 0 },
4694+ { "RADIX", K_RADIX, 0 },
4695+ { "DATA", K_DATA, 0 },
4696+ { "DB", K_DB, 0 },
4697+ { "DW", K_DW, 0 },
4698+ { "DL", K_DL, 0 },
4699+ { "DATAB", K_DATAB, 0 },
4700+ { "SDATA", K_SDATA, 0 },
4701+ { "SDATAB", K_SDATAB, 0 },
4702+ { "SDATAZ", K_SDATAZ, 0 },
4703+ { "SDATAC", K_SDATAC, 0 },
4704+ { "RES", K_RES, 0 },
4705+ { "SRES", K_SRES, 0 },
4706+ { "SRESC", K_SRESC, 0 },
4707+ { "SRESZ", K_SRESZ, 0 },
4708+ { "EXPORT", K_EXPORT, 0 },
4709+ { "GLOBAL", K_GLOBAL, 0 },
4710+ { "PRINT", K_PRINT, 0 },
4711+ { "FORM", K_FORM, 0 },
4712+ { "HEADING", K_HEADING, 0 },
4713+ { "PAGE", K_PAGE, 0 },
4714+ { "PROGRAM", K_IGNORED, 0 },
4715+ { "END", K_END, 0 },
4716+ { "INCLUDE", K_INCLUDE, 0 },
4717+ { "ASSIGNA", K_ASSIGNA, 0 },
4718+ { "ASSIGNC", K_ASSIGNC, 0 },
4719+ { "AIF", K_AIF, 0 },
4720+ { "AELSE", K_AELSE, 0 },
4721+ { "AENDI", K_AENDI, 0 },
4722+ { "AREPEAT", K_AREPEAT, 0 },
4723+ { "AENDR", K_AENDR, 0 },
4724+ { "EXITM", K_EXITM, 0 },
4725+ { "MACRO", K_MACRO, 0 },
4726+ { "ENDM", K_ENDM, 0 },
4727+ { "AWHILE", K_AWHILE, 0 },
4728+ { "ALIGN", K_ALIGN, 0 },
4729+ { "AENDW", K_AENDW, 0 },
4730+ { "ALTERNATE", K_ALTERNATE, 0 },
4731+ { "LOCAL", K_LOCAL, 0 },
4732+ { NULL, 0, 0 }
4733+};
4734+
4735+/* Although the conditional operators are handled by gas, we need to
4736+ handle them here as well, in case they are used in a recursive
4737+ macro to end the recursion. */
4738+
4739+static struct keyword mrikinfo[] = {
4740+ { "IFEQ", K_IFEQ, 0 },
4741+ { "IFNE", K_IFNE, 0 },
4742+ { "IFLT", K_IFLT, 0 },
4743+ { "IFLE", K_IFLE, 0 },
4744+ { "IFGE", K_IFGE, 0 },
4745+ { "IFGT", K_IFGT, 0 },
4746+ { "IFC", K_IFC, 0 },
4747+ { "IFNC", K_IFNC, 0 },
4748+ { "ELSEC", K_AELSE, 0 },
4749+ { "ENDC", K_AENDI, 0 },
4750+ { "MEXIT", K_EXITM, 0 },
4751+ { "REPT", K_AREPEAT, 0 },
4752+ { "IRP", K_IRP, 0 },
4753+ { "IRPC", K_IRPC, 0 },
4754+ { "ENDR", K_AENDR, 0 },
4755+ { NULL, 0, 0 }
4756+};
4757+
4758+/* Look for a pseudo op on the line. If one's there then call
4759+ its handler. */
4760+
4761+static int
4762+process_pseudo_op (idx, line, acc)
4763+ int idx;
4764+ sb *line;
4765+ sb *acc;
4766+{
4767+ int oidx = idx;
4768+
4769+ if (line->ptr[idx] == '.' || alternate || mri)
4770+ {
4771+ /* Scan forward and find pseudo name. */
4772+ char *in;
4773+ hash_entry *ptr;
4774+
4775+ char *s;
4776+ char *e;
4777+ if (line->ptr[idx] == '.')
4778+ idx++;
4779+ in = line->ptr + idx;
4780+ s = in;
4781+ e = s;
4782+ sb_reset (acc);
4783+
4784+ while (idx < line->len && *e && ISFIRSTCHAR (*e))
4785+ {
4786+ sb_add_char (acc, *e);
4787+ e++;
4788+ idx++;
4789+ }
4790+
4791+ ptr = hash_lookup (&keyword_hash_table, acc);
4792+
4793+ if (!ptr)
4794+ {
4795+#if 0
4796+ /* This one causes lots of pain when trying to preprocess
4797+ ordinary code. */
4798+ WARNING ((stderr, _("Unrecognised pseudo op `%s'.\n"),
4799+ sb_name (acc)));
4800+#endif
4801+ return 0;
4802+ }
4803+ if (ptr->value.i & LAB)
4804+ {
4805+ /* Output the label. */
4806+ if (label.len)
4807+ {
4808+ fprintf (outfile, "%s:\t", sb_name (&label));
4809+ }
4810+ else
4811+ fprintf (outfile, "\t");
4812+ }
4813+
4814+ if (mri && ptr->value.i == K_END)
4815+ {
4816+ sb t;
4817+
4818+ sb_new (&t);
4819+ sb_add_buffer (&t, line->ptr + oidx, idx - oidx);
4820+ fprintf (outfile, "\t%s", sb_name (&t));
4821+ sb_kill (&t);
4822+ }
4823+
4824+ if (ptr->value.i & PROCESS)
4825+ {
4826+ /* Polish the rest of the line before handling the pseudo op. */
4827+#if 0
4828+ strip_comments (line);
4829+#endif
4830+ sb_reset (acc);
4831+ process_assigns (idx, line, acc);
4832+ sb_reset (line);
4833+ change_base (0, acc, line);
4834+ idx = 0;
4835+ }
4836+ if (!condass_on ())
4837+ {
4838+ switch (ptr->value.i)
4839+ {
4840+ case K_AIF:
4841+ do_aif (idx, line);
4842+ break;
4843+ case K_AELSE:
4844+ do_aelse ();
4845+ break;
4846+ case K_AENDI:
4847+ do_aendi ();
4848+ break;
4849+ }
4850+ return 1;
4851+ }
4852+ else
4853+ {
4854+ switch (ptr->value.i)
4855+ {
4856+ case K_ALTERNATE:
4857+ alternate = 1;
4858+ macro_init (1, mri, 0, exp_get_abs);
4859+ return 1;
4860+ case K_AELSE:
4861+ do_aelse ();
4862+ return 1;
4863+ case K_AENDI:
4864+ do_aendi ();
4865+ return 1;
4866+ case K_ORG:
4867+ ERROR ((stderr, _("ORG command not allowed.\n")));
4868+ break;
4869+ case K_RADIX:
4870+ do_radix (line);
4871+ return 1;
4872+ case K_DB:
4873+ do_data (idx, line, 1);
4874+ return 1;
4875+ case K_DW:
4876+ do_data (idx, line, 2);
4877+ return 1;
4878+ case K_DL:
4879+ do_data (idx, line, 4);
4880+ return 1;
4881+ case K_DATA:
4882+ do_data (idx, line, 0);
4883+ return 1;
4884+ case K_DATAB:
4885+ do_datab (idx, line);
4886+ return 1;
4887+ case K_SDATA:
4888+ do_sdata (idx, line, 0);
4889+ return 1;
4890+ case K_SDATAB:
4891+ do_sdatab (idx, line);
4892+ return 1;
4893+ case K_SDATAC:
4894+ do_sdata (idx, line, 'c');
4895+ return 1;
4896+ case K_SDATAZ:
4897+ do_sdata (idx, line, 'z');
4898+ return 1;
4899+ case K_ASSIGN:
4900+ do_assign (0, 0, line);
4901+ return 1;
4902+ case K_AIF:
4903+ do_aif (idx, line);
4904+ return 1;
4905+ case K_AREPEAT:
4906+ do_arepeat (idx, line);
4907+ return 1;
4908+ case K_AENDW:
4909+ do_aendw ();
4910+ return 1;
4911+ case K_AWHILE:
4912+ do_awhile (idx, line);
4913+ return 1;
4914+ case K_AENDR:
4915+ do_aendr ();
4916+ return 1;
4917+ case K_EQU:
4918+ do_assign (1, idx, line);
4919+ return 1;
4920+ case K_ALIGN:
4921+ do_align (idx, line);
4922+ return 1;
4923+ case K_RES:
4924+ do_res (idx, line, 0);
4925+ return 1;
4926+ case K_SRES:
4927+ do_res (idx, line, 's');
4928+ return 1;
4929+ case K_INCLUDE:
4930+ do_include (idx, line);
4931+ return 1;
4932+ case K_LOCAL:
4933+ do_local (idx, line);
4934+ return 1;
4935+ case K_MACRO:
4936+ do_macro (idx, line);
4937+ return 1;
4938+ case K_ENDM:
4939+ do_endm ();
4940+ return 1;
4941+ case K_SRESC:
4942+ do_res (idx, line, 'c');
4943+ return 1;
4944+ case K_PRINT:
4945+ do_print (idx, line);
4946+ return 1;
4947+ case K_FORM:
4948+ do_form (idx, line);
4949+ return 1;
4950+ case K_HEADING:
4951+ do_heading (idx, line);
4952+ return 1;
4953+ case K_PAGE:
4954+ do_page ();
4955+ return 1;
4956+ case K_GLOBAL:
4957+ case K_EXPORT:
4958+ do_export (line);
4959+ return 1;
4960+ case K_IMPORT:
4961+ return 1;
4962+ case K_SRESZ:
4963+ do_res (idx, line, 'z');
4964+ return 1;
4965+ case K_IGNORED:
4966+ return 1;
4967+ case K_END:
4968+ do_end (line);
4969+ return 1;
4970+ case K_ASSIGNA:
4971+ do_assigna (idx, line);
4972+ return 1;
4973+ case K_ASSIGNC:
4974+ do_assignc (idx, line);
4975+ return 1;
4976+ case K_EXITM:
4977+ do_exitm ();
4978+ return 1;
4979+ case K_REG:
4980+ do_reg (idx, line);
4981+ return 1;
4982+ case K_IFEQ:
4983+ do_if (idx, line, EQ);
4984+ return 1;
4985+ case K_IFNE:
4986+ do_if (idx, line, NE);
4987+ return 1;
4988+ case K_IFLT:
4989+ do_if (idx, line, LT);
4990+ return 1;
4991+ case K_IFLE:
4992+ do_if (idx, line, LE);
4993+ return 1;
4994+ case K_IFGE:
4995+ do_if (idx, line, GE);
4996+ return 1;
4997+ case K_IFGT:
4998+ do_if (idx, line, GT);
4999+ return 1;
5000+ case K_IFC:
5001+ do_ifc (idx, line, 0);
5002+ return 1;
5003+ case K_IFNC:
5004+ do_ifc (idx, line, 1);
5005+ return 1;
5006+ case K_IRP:
5007+ do_irp (idx, line, 0);
5008+ return 1;
5009+ case K_IRPC:
5010+ do_irp (idx, line, 1);
5011+ return 1;
5012+ }
5013+ }
5014+ }
5015+ return 0;
5016+}
5017+
5018+/* Add a keyword to the hash table. */
5019+
5020+static void
5021+add_keyword (name, code)
5022+ const char *name;
5023+ int code;
5024+{
5025+ sb label;
5026+ int j;
5027+
5028+ sb_new (&label);
5029+ sb_add_string (&label, name);
5030+
5031+ hash_add_to_int_table (&keyword_hash_table, &label, code);
5032+
5033+ sb_reset (&label);
5034+ for (j = 0; name[j]; j++)
5035+ sb_add_char (&label, name[j] - 'A' + 'a');
5036+ hash_add_to_int_table (&keyword_hash_table, &label, code);
5037+
5038+ sb_kill (&label);
5039+}
5040+
5041+/* Build the keyword hash table - put each keyword in the table twice,
5042+ once upper and once lower case. */
5043+
5044+static void
5045+process_init ()
5046+{
5047+ int i;
5048+
5049+ for (i = 0; kinfo[i].name; i++)
5050+ add_keyword (kinfo[i].name, kinfo[i].code);
5051+
5052+ if (mri)
5053+ {
5054+ for (i = 0; mrikinfo[i].name; i++)
5055+ add_keyword (mrikinfo[i].name, mrikinfo[i].code);
5056+ }
5057+}
5058+
5059+static void
5060+do_define (string)
5061+ const char *string;
5062+{
5063+ sb label;
5064+ int res = 1;
5065+ hash_entry *ptr;
5066+ sb_new (&label);
5067+
5068+ while (*string)
5069+ {
5070+ if (*string == '=')
5071+ {
5072+ sb value;
5073+ sb_new (&value);
5074+ string++;
5075+ while (*string)
5076+ {
5077+ sb_add_char (&value, *string);
5078+ string++;
5079+ }
5080+ exp_get_abs (_("Invalid expression on command line.\n"),
5081+ 0, &value, &res);
5082+ sb_kill (&value);
5083+ break;
5084+ }
5085+ sb_add_char (&label, *string);
5086+
5087+ string++;
5088+ }
5089+
5090+ ptr = hash_create (&vars, &label);
5091+ free_old_entry (ptr);
5092+ ptr->type = hash_integer;
5093+ ptr->value.i = res;
5094+ sb_kill (&label);
5095+}
5096+
5097+char *program_name;
5098+
5099+/* The list of long options. */
5100+static struct option long_options[] =
5101+{
5102+ { "alternate", no_argument, 0, 'a' },
5103+ { "include", required_argument, 0, 'I' },
5104+ { "commentchar", required_argument, 0, 'c' },
5105+ { "copysource", no_argument, 0, 's' },
5106+ { "debug", no_argument, 0, 'd' },
5107+ { "help", no_argument, 0, 'h' },
5108+ { "mri", no_argument, 0, 'M' },
5109+ { "output", required_argument, 0, 'o' },
5110+ { "print", no_argument, 0, 'p' },
5111+ { "unreasonable", no_argument, 0, 'u' },
5112+ { "version", no_argument, 0, 'v' },
5113+ { "define", required_argument, 0, 'd' },
5114+ { NULL, no_argument, 0, 0 }
5115+};
5116+
5117+/* Show a usage message and exit. */
5118+static void
5119+show_usage (file, status)
5120+ FILE *file;
5121+ int status;
5122+{
5123+ fprintf (file, _("\
5124+Usage: %s \n\
5125+ [-a] [--alternate] enter alternate macro mode\n\
5126+ [-c char] [--commentchar char] change the comment character from !\n\
5127+ [-d] [--debug] print some debugging info\n\
5128+ [-h] [--help] print this message\n\
5129+ [-M] [--mri] enter MRI compatibility mode\n\
5130+ [-o out] [--output out] set the output file\n\
5131+ [-p] [--print] print line numbers\n"), program_name);
5132+ fprintf (file, _("\
5133+ [-s] [--copysource] copy source through as comments \n\
5134+ [-u] [--unreasonable] allow unreasonable nesting\n\
5135+ [-v] [--version] print the program version\n\
5136+ [-Dname=value] create preprocessor variable called name, with value\n\
5137+ [-Ipath] add to include path list\n\
5138+ [in-file]\n"));
5139+ if (status == 0)
5140+ printf (_("Report bugs to %s\n"), REPORT_BUGS_TO);
5141+ exit (status);
5142+}
5143+
5144+/* Display a help message and exit. */
5145+
5146+static void
5147+show_help ()
5148+{
5149+ printf (_("%s: Gnu Assembler Macro Preprocessor\n"), program_name);
5150+ show_usage (stdout, 0);
5151+}
5152+
5153+int main PARAMS ((int, char **));
5154+
5155+int
5156+main (argc, argv)
5157+ int argc;
5158+ char **argv;
5159+{
5160+ int opt;
5161+ char *out_name = 0;
5162+ sp = include_stack;
5163+
5164+ ifstack[0].on = 1;
5165+ ifi = 0;
5166+
5167+#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
5168+ setlocale (LC_MESSAGES, "");
5169+#endif
5170+#if defined (HAVE_SETLOCALE)
5171+ setlocale (LC_CTYPE, "");
5172+#endif
5173+ bindtextdomain (PACKAGE, LOCALEDIR);
5174+ textdomain (PACKAGE);
5175+
5176+ program_name = argv[0];
5177+ xmalloc_set_program_name (program_name);
5178+
5179+ hash_new_table (101, &keyword_hash_table);
5180+ hash_new_table (101, &assign_hash_table);
5181+ hash_new_table (101, &vars);
5182+
5183+ sb_new (&label);
5184+
5185+ while ((opt = getopt_long (argc, argv, "I:sdhavc:upo:D:M", long_options,
5186+ (int *) NULL))
5187+ != EOF)
5188+ {
5189+ switch (opt)
5190+ {
5191+ case 'o':
5192+ out_name = optarg;
5193+ break;
5194+ case 'u':
5195+ unreasonable = 1;
5196+ break;
5197+ case 'I':
5198+ {
5199+ include_path *p = (include_path *) xmalloc (sizeof (include_path));
5200+ p->next = NULL;
5201+ sb_new (&p->path);
5202+ sb_add_string (&p->path, optarg);
5203+ if (paths_tail)
5204+ paths_tail->next = p;
5205+ else
5206+ paths_head = p;
5207+ paths_tail = p;
5208+ }
5209+ break;
5210+ case 'p':
5211+ print_line_number = 1;
5212+ break;
5213+ case 'c':
5214+ comment_char = optarg[0];
5215+ break;
5216+ case 'a':
5217+ alternate = 1;
5218+ break;
5219+ case 's':
5220+ copysource = 1;
5221+ break;
5222+ case 'd':
5223+ stats = 1;
5224+ break;
5225+ case 'D':
5226+ do_define (optarg);
5227+ break;
5228+ case 'M':
5229+ mri = 1;
5230+ comment_char = ';';
5231+ break;
5232+ case 'h':
5233+ show_help ();
5234+ /* NOTREACHED */
5235+ case 'v':
5236+ /* This output is intended to follow the GNU standards document. */
5237+ printf (_("GNU assembler pre-processor %s\n"), program_version);
5238+ printf (_("Copyright 1996 Free Software Foundation, Inc.\n"));
5239+ printf (_("\
5240+This program is free software; you may redistribute it under the terms of\n\
5241+the GNU General Public License. This program has absolutely no warranty.\n"));
5242+ exit (0);
5243+ /* NOTREACHED */
5244+ case 0:
5245+ break;
5246+ default:
5247+ show_usage (stderr, 1);
5248+ /* NOTREACHED */
5249+ }
5250+ }
5251+
5252+ process_init ();
5253+
5254+ macro_init (alternate, mri, 0, exp_get_abs);
5255+
5256+ if (out_name)
5257+ {
5258+ outfile = fopen (out_name, "w");
5259+ if (!outfile)
5260+ {
5261+ fprintf (stderr, _("%s: Can't open output file `%s'.\n"),
5262+ program_name, out_name);
5263+ exit (1);
5264+ }
5265+ }
5266+ else
5267+ {
5268+ outfile = stdout;
5269+ }
5270+
5271+ chartype_init ();
5272+ if (!outfile)
5273+ outfile = stdout;
5274+
5275+ /* Process all the input files. */
5276+
5277+ while (optind < argc)
5278+ {
5279+ if (new_file (argv[optind]))
5280+ {
5281+ process_file ();
5282+ }
5283+ else
5284+ {
5285+ fprintf (stderr, _("%s: Can't open input file `%s'.\n"),
5286+ program_name, argv[optind]);
5287+ exit (1);
5288+ }
5289+ optind++;
5290+ }
5291+
5292+ quit ();
5293+ return 0;
5294+}
5295+
5296+/* This function is used because an abort in some of the other files
5297+ may be compiled into as_abort because they include as.h. */
5298+
5299+void
5300+as_abort (file, line, fn)
5301+ const char *file, *fn;
5302+ int line;
5303+{
5304+ fprintf (stderr, _("Internal error, aborting at %s line %d"), file, line);
5305+ if (fn)
5306+ fprintf (stderr, " in %s", fn);
5307+ fprintf (stderr, _("\nPlease report this bug.\n"));
5308+ exit (1);
5309+}
486f726b
JB
5310+
5311+/* duplicated from as internals */
5312+
5313+static void
5314+identify (char *file)
5315+{
5316+ static int identified;
5317+
5318+ if (identified)
5319+ return;
5320+ identified++;
5321+
5322+ if (file)
5323+ fprintf (stderr, "%s: ", file);
5324+ fprintf (stderr, _("Assembler messages:\n"));
5325+}
5326+
5327+/* The number of warnings issued. */
5328+static int warning_count;
5329+
5330+/* The common portion of as_warn and as_warn_where. */
5331+
5332+static void
5333+as_warn_internal (char *file, unsigned int line, char *buffer)
5334+{
5335+ ++warning_count;
5336+
5337+ identify (file);
5338+ if (file)
5339+ fprintf (stderr, "%s:%u: ", file, line);
5340+ fprintf (stderr, _("Warning: "));
5341+ fputs (buffer, stderr);
5342+ (void) putc ('\n', stderr);
5343+}
5344+
5345+/* Send to stderr a string as a warning, and locate warning
5346+ in input file(s).
5347+ Please only use this for when we have some recovery action.
5348+ Please explain in string (which may have '\n's) what recovery was
5349+ done. */
5350+
5351+void
5352+as_warn (const char *format, ...)
5353+{
5354+ va_list args;
5355+ char buffer[2000];
5356+
5357+ if (1 /*!flag_no_warnings*/)
5358+ {
5359+ va_start (args, format);
5360+ vsprintf (buffer, format, args);
5361+ va_end (args);
5362+ as_warn_internal ((char *) NULL, 0, buffer);
5363+ }
5364+}
5365+
039c34b6
JB
5366+/* Like as_bad but the file name and line number are passed in.
5367+ Unfortunately, we have to repeat the function in order to handle
5368+ the varargs correctly and portably. */
5369+
5370+void
5371+as_warn_where (char *file, unsigned int line, const char *format, ...)
5372+{
5373+ va_list args;
5374+ char buffer[2000];
5375+
5376+ if (1 /*!flag_no_warnings*/)
5377+ {
5378+ va_start (args, format);
5379+ vsprintf (buffer, format, args);
5380+ va_end (args);
5381+ as_warn_internal (file, line, buffer);
5382+ }
5383+}
5384+
486f726b
JB
5385+/* Nonzero if we've hit a 'bad error', and should not write an obj file,
5386+ and exit with a nonzero error code. */
5387+
5388+static int error_count;
5389+
5390+/* The common portion of as_bad and as_bad_where. */
5391+
5392+static void
5393+as_bad_internal (char *file, unsigned int line, char *buffer)
5394+{
5395+ ++error_count;
5396+
5397+ identify (file);
5398+ if (file)
5399+ fprintf (stderr, "%s:%u: ", file, line);
5400+ fprintf (stderr, _("Error: "));
5401+ fputs (buffer, stderr);
5402+ (void) putc ('\n', stderr);
5403+}
5404+
039c34b6
JB
5405+/* Send to stderr a string as a warning, and locate warning in input
5406+ file(s). Please us when there is no recovery, but we want to
5407+ continue processing but not produce an object file.
5408+ Please explain in string (which may have '\n's) what recovery was
5409+ done. */
5410+
5411+void
5412+as_bad (const char *format, ...)
5413+{
5414+ va_list args;
5415+ char buffer[2000];
5416+
5417+ va_start (args, format);
5418+ vsprintf (buffer, format, args);
5419+ va_end (args);
5420+
5421+ as_bad_internal ((char *) NULL, 0, buffer);
5422+}
5423+
5424+/* Like as_bad but the file name and line number are passed in.
5425+ Unfortunately, we have to repeat the function in order to handle
5426+ the varargs correctly and portably. */
5427+
486f726b
JB
5428+void
5429+as_bad_where (char *file, unsigned int line, const char *format, ...)
5430+{
5431+ va_list args;
5432+ char buffer[2000];
5433+
5434+ va_start (args, format);
5435+ vsprintf (buffer, format, args);
5436+ va_end (args);
5437+
5438+ as_bad_internal (file, line, buffer);
5439+}
5440+
da530c8a
JB
5441+/* Indicate assertion failure.
5442+ Arguments: Filename, line number, optional function name. */
5443+
5444+void
5445+as_assert (const char *file, int line, const char *fn)
5446+{
5447+ fprintf (stderr, _("Internal error!\n"));
5448+ if (fn)
5449+ fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
5450+ fn, file, line);
5451+ else
5452+ fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
5453+ fprintf (stderr, _("Please report this bug.\n"));
5454+ xexit (EXIT_FAILURE);
5455+}
5456+
486f726b
JB
5457+#ifndef LEX_AT
5458+/* The m88k unfortunately uses @ as a label beginner. */
5459+#define LEX_AT 0
5460+#endif
5461+
5462+#ifndef LEX_BR
5463+/* The RS/6000 assembler uses {,},[,] as parts of symbol names. */
5464+#define LEX_BR 0
5465+#endif
5466+
5467+#ifndef LEX_PCT
5468+/* The Delta 68k assembler permits % inside label names. */
5469+#define LEX_PCT 0
5470+#endif
5471+
5472+#ifndef LEX_QM
5473+/* The PowerPC Windows NT assemblers permits ? inside label names. */
5474+#define LEX_QM 0
5475+#endif
5476+
5477+#ifndef LEX_HASH
5478+/* The IA-64 assembler uses # as a suffix designating a symbol. We include
5479+ it in the symbol and strip it out in tc_canonicalize_symbol_name. */
5480+#define LEX_HASH 0
5481+#endif
5482+
5483+#ifndef LEX_DOLLAR
5484+/* The a29k assembler does not permits labels to start with $. */
5485+#define LEX_DOLLAR 3
5486+#endif
5487+
5488+#ifndef LEX_TILDE
5489+/* The Delta 68k assembler permits ~ at start of label names. */
5490+#define LEX_TILDE 0
5491+#endif
5492+
5493+/* Used by is_... macros. our ctype[]. */
5494+char lex_type[256] = {
5495+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* @ABCDEFGHIJKLMNO */
5496+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* PQRSTUVWXYZ[\]^_ */
5497+ 0, 0, 0, LEX_HASH, LEX_DOLLAR, LEX_PCT, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, /* _!"#$%&'()*+,-./ */
5498+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, LEX_QM, /* 0123456789:;<=>? */
5499+ LEX_AT, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* @ABCDEFGHIJKLMNO */
5500+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, 0, 3, /* PQRSTUVWXYZ[\]^_ */
5501+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, /* `abcdefghijklmno */
5502+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, LEX_BR, 0, LEX_BR, LEX_TILDE, 0, /* pqrstuvwxyz{|}~. */
5503+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5504+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5505+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5506+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5507+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5508+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5509+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5510+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
5511+};
c286ff20
JB
5512+
5513+/* just a stub to satisfy unused function in sb.o */
5514+int do_scrub_chars (int (*get) (char*, int), char *tostart, int tolen) {}
a94d65a7
AM
5515--- binutils-2.16.91.0.2.org/gas/macro.c 2005-05-10 22:46:44.000000000 +0000
5516+++ binutils-2.16.91.0.2/gas/macro.c 2005-07-21 18:31:04.000000000 +0000
6f16a75e 5517@@ -754,7 +754,7 @@
0087dcf3
JB
5518
5519 static const char *
f07cf0a7 5520 macro_expand_body (sb *in, sb *out, formal_entry *formals,
486f726b
JB
5521- struct hash_control *formal_hash, const macro_entry *macro)
5522+ struct hash_control *formal_hash, const macro_entry *macro, int comment_char)
0087dcf3
JB
5523 {
5524 sb t;
486f726b 5525 int src = 0, inquote = 0, macro_line = 0;
6f16a75e 5526@@ -786,7 +786,14 @@
0087dcf3
JB
5527 else if (in->ptr[src] == '\\')
5528 {
5529 src++;
486f726b 5530- if (src < in->len && in->ptr[src] == '(')
0087dcf3
JB
5531+ if (in->ptr[src] == comment_char && comment_char != '\0')
5532+ {
5533+ /* This is a comment, just drop the rest of the line. */
5534+ while (src < in->len
5535+ && in->ptr[src] != '\n')
5536+ src++;
5537+ }
486f726b 5538+ else if (src < in->len && in->ptr[src] == '(')
0087dcf3
JB
5539 {
5540 /* Sub in till the next ')' literally. */
5541 src++;
6f16a75e 5542@@ -867,7 +874,7 @@
486f726b
JB
5543 else
5544 {
0087dcf3
JB
5545 src = sb_skip_white (src + 5, in);
5546- while (in->ptr[src] != '\n')
5547+ while (in->ptr[src] != '\n' && in->ptr[src] != comment_char)
5548 {
486f726b 5549 const char *name;
039c34b6 5550 formal_entry *f = new_formal ();
6f16a75e 5551@@ -903,6 +910,17 @@
0087dcf3
JB
5552 }
5553 }
5554 }
5555+ else if (comment_char != '\0'
5556+ && in->ptr[src] == comment_char
5557+ && src + 1 < in->len
5558+ && in->ptr[src + 1] == comment_char
5559+ && !inquote)
5560+ {
5561+ /* Two comment chars in a row cause the rest of the line to
5562+ be dropped. */
5563+ while (src < in->len && in->ptr[src] != '\n')
5564+ src++;
5565+ }
5566 else if (in->ptr[src] == '"'
5567 || (macro_mri && in->ptr[src] == '\''))
5568 {
6f16a75e 5569@@ -984,7 +1002,7 @@
0087dcf3
JB
5570 body. */
5571
5572 static const char *
f07cf0a7
JB
5573-macro_expand (int idx, sb *in, macro_entry *m, sb *out)
5574+macro_expand (int idx, sb *in, macro_entry *m, sb *out, int comment_char)
0087dcf3
JB
5575 {
5576 sb t;
5577 formal_entry *ptr;
6f16a75e 5578@@ -1029,7 +1047,7 @@
0087dcf3
JB
5579
5580 /* Peel off the actuals and store them away in the hash tables' actuals. */
5581 idx = sb_skip_white (idx, in);
5582- while (idx < in->len)
5583+ while (idx < in->len && in->ptr[idx] != comment_char)
5584 {
5585 int scan;
5586
6f16a75e 5587@@ -1156,7 +1174,7 @@
039c34b6
JB
5588 sb_add_string (&ptr->actual, buffer);
5589 }
0087dcf3 5590
039c34b6
JB
5591- err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m);
5592+ err = macro_expand_body (&m->sub, out, m->formals, m->formal_hash, m, comment_char);
5593 }
0087dcf3 5594
486f726b 5595 /* Discard any unnamed formal arguments. */
6f16a75e 5596@@ -1189,7 +1207,7 @@
0087dcf3
JB
5597 *EXPAND. Return 1 if a macro is found, 0 otherwise. */
5598
5599 int
f07cf0a7
JB
5600-check_macro (const char *line, sb *expand,
5601+check_macro (const char *line, sb *expand, int comment_char,
5602 const char **error, macro_entry **info)
0087dcf3 5603 {
f07cf0a7 5604 const char *s;
6f16a75e 5605@@ -1224,7 +1242,7 @@
0087dcf3
JB
5606 sb_add_char (&line_sb, *s++);
5607
5608 sb_new (expand);
5609- *error = macro_expand (0, &line_sb, macro, expand);
5610+ *error = macro_expand (0, &line_sb, macro, expand, comment_char);
5611
5612 sb_kill (&line_sb);
5613
6f16a75e 5614@@ -1285,7 +1303,7 @@
0087dcf3
JB
5615 success, or an error message otherwise. */
5616
5617 const char *
f07cf0a7
JB
5618-expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *))
5619+expand_irp (int irpc, int idx, sb *in, sb *out, int (*get_line) (sb *), int comment_char)
0087dcf3 5620 {
0087dcf3 5621 sb sub;
486f726b 5622 formal_entry f;
6f16a75e 5623@@ -1318,10 +1336,10 @@
0087dcf3
JB
5624 sb_reset (out);
5625
5626 idx = sb_skip_comma (idx, in);
5627- if (idx >= in->len)
5628+ if (idx >= in->len || in->ptr[idx] == comment_char)
5629 {
5630 /* Expand once with a null string. */
5631- err = macro_expand_body (&sub, out, &f, h, 0);
486f726b 5632+ err = macro_expand_body (&sub, out, &f, h, 0, comment_char);
0087dcf3 5633 }
486f726b 5634 else
0087dcf3 5635 {
6f16a75e
PS
5636@@ -1333,7 +1351,7 @@
5637 ++idx;
5638 }
5639
0087dcf3
JB
5640- while (idx < in->len)
5641+ while (idx < in->len && in->ptr[idx] != comment_char)
5642 {
5643 if (!irpc)
039c34b6 5644 idx = get_any_string (idx, in, &f.actual);
6f16a75e
PS
5645@@ -1347,7 +1365,7 @@
5646 in_quotes = ! in_quotes;
5647
0087dcf3
JB
5648 nxt = sb_skip_white (idx + 1, in);
5649- if (nxt >= in->len)
5650+ if (nxt >= in->len || in->ptr[nxt] == comment_char)
5651 {
5652 idx = nxt;
5653 break;
6f16a75e 5654@@ -1358,7 +1376,7 @@
0087dcf3
JB
5655 ++idx;
5656 }
6f16a75e 5657
0087dcf3 5658- err = macro_expand_body (&sub, out, &f, h, 0);
486f726b 5659+ err = macro_expand_body (&sub, out, &f, h, 0, comment_char);
0087dcf3 5660 if (err != NULL)
486f726b 5661 break;
0087dcf3 5662 if (!irpc)
a94d65a7
AM
5663--- binutils-2.16.91.0.2.org/gas/macro.h 2005-05-10 22:46:44.000000000 +0000
5664+++ binutils-2.16.91.0.2/gas/macro.h 2005-07-21 18:31:04.000000000 +0000
5665@@ -90,8 +90,8 @@
f07cf0a7 5666 extern void macro_mri_mode (int);
0087dcf3 5667 extern const char *define_macro
486f726b 5668 (int, sb *, sb *, int (*) (sb *), char *, unsigned int, const char **);
f07cf0a7
JB
5669-extern int check_macro (const char *, sb *, const char **, macro_entry **);
5670+extern int check_macro (const char *, sb *, int, const char **, macro_entry **);
5671 extern void delete_macro (const char *);
5672-extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *));
5673+extern const char *expand_irp (int, int, sb *, sb *, int (*) (sb *), int);
0087dcf3
JB
5674
5675 #endif
a94d65a7
AM
5676--- binutils-2.16.91.0.2.org/gas/read.c 2005-06-22 20:53:34.000000000 +0000
5677+++ binutils-2.16.91.0.2/gas/read.c 2005-07-21 18:31:04.000000000 +0000
5678@@ -555,7 +555,7 @@
486f726b
JB
5679 const char *err;
5680 macro_entry *macro;
0087dcf3 5681
486f726b
JB
5682- if (check_macro (line, &out, &err, &macro))
5683+ if (check_macro (line, &out, '\0', &err, &macro))
5684 {
5685 if (err != NULL)
5686 as_bad ("%s", err);
a94d65a7 5687@@ -1958,7 +1958,7 @@
0087dcf3
JB
5688
5689 sb_new (&out);
5690
f6932307
PS
5691- err = expand_irp (irpc, 0, &s, &out, get_non_macro_line_sb);
5692+ err = expand_irp (irpc, 0, &s, &out, get_non_macro_line_sb, '\0');
0087dcf3
JB
5693 if (err != NULL)
5694 as_bad_where (file, line, "%s", err);
5695
This page took 1.064713 seconds and 4 git commands to generate.