]>
git.saurik.com Git - apple/boot.git/blob - i386/nasm/nasm.c
3360b5417fcef6948ad718d8cf4ac897d74d00ab
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
25 /* The Netwide Assembler main program module
27 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
28 * Julian Hall. All rights reserved. The software is
29 * redistributable under the licence given in the file "Licence"
30 * distributed in the NASM archive.
49 static void report_error (int, char *, ...);
50 static void parse_cmdline (int, char **);
51 static void assemble_file (char *);
52 static int getkw (char *buf
, char **value
);
53 static void register_output_formats(void);
54 static void usage(void);
57 static char inname
[FILENAME_MAX
];
58 static char outname
[FILENAME_MAX
];
59 static char listname
[FILENAME_MAX
];
60 static int lineno
; /* for error reporting */
61 static int lineinc
; /* set by [LINE] or [ONELINE] */
62 static int globallineno
; /* for forward-reference tracking */
64 static struct ofmt
*ofmt
= NULL
;
66 static FILE *ofile
= NULL
;
67 static int sb
= 16; /* by default */
69 static int use_stdout
= FALSE
; /* by default, errors to stderr */
71 static long current_seg
, abs_seg
;
72 static struct RAA
*offsets
;
73 static long abs_offset
;
75 static struct SAA
*forwrefs
; /* keep track of forward references */
78 static Preproc
*preproc
;
79 static int preprocess_only
;
81 /* used by error function to report location */
82 static char currentfile
[FILENAME_MAX
];
85 * Which of the suppressible warnings are suppressed. Entry zero
86 * doesn't do anything. Initial defaults are given here.
88 static char suppressed
[1+ERR_WARN_MAX
] = {
93 * The option names for the suppressible warnings. As before, entry
96 static char *suppressed_names
[1+ERR_WARN_MAX
] = {
97 NULL
, "macro-params", "orphan-labels", "number-overflow"
101 * The explanations for the suppressible warnings. As before, entry
104 static char *suppressed_what
[1+ERR_WARN_MAX
] = {
105 NULL
, "macro calls with wrong no. of params",
106 "labels alone on lines without trailing `:'",
107 "numeric constants greater than 0xFFFFFFFF"
111 * This is a null preprocessor which just copies lines from input
112 * to output. It's used when someone explicitly requests that NASM
113 * not preprocess their source file.
116 static void no_pp_reset (char *, int, efunc
, evalfunc
, ListGen
*);
117 static char *no_pp_getline (void);
118 static void no_pp_cleanup (void);
119 static Preproc no_pp
= {
126 * get/set current offset...
128 #define get_curr_ofs (current_seg==NO_SEG?abs_offset:\
129 raa_read(offsets,current_seg))
130 #define set_curr_ofs(x) (current_seg==NO_SEG?(void)(abs_offset=(x)):\
131 (void)(offsets=raa_write(offsets,current_seg,(x))))
133 static int want_usage
;
134 static int terminate_after_phase
;
136 int main(int argc
, char **argv
) {
137 want_usage
= terminate_after_phase
= FALSE
;
139 nasm_set_malloc_error (report_error
);
140 offsets
= raa_init();
141 forwrefs
= saa_init ((long)sizeof(int));
144 preprocess_only
= FALSE
;
148 register_output_formats();
150 parse_cmdline(argc
, argv
);
152 if (terminate_after_phase
) {
159 pp_extra_stdmac (ofmt
->stdmac
);
160 eval_global_info (ofmt
, lookup_label
);
162 if (preprocess_only
) {
166 ofile
= fopen(outname
, "w");
168 report_error (ERR_FATAL
| ERR_NOFILE
,
169 "unable to open output file `%s'", outname
);
173 eval_info ("%", 0L, 0L); /* disallow labels, $ or $$ in exprs */
175 preproc
->reset (inname
, 2, report_error
, evaluate
, &nasmlist
);
176 strcpy(currentfile
,inname
);
179 while ( (line
= preproc
->getline()) ) {
181 char buf
[FILENAME_MAX
];
185 * We must still check for %line directives, so that we
186 * can report errors accurately.
188 if (!strncmp(line
, "%line", 5) &&
189 sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) == 3) {
192 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
193 currentfile
[FILENAME_MAX
-1] = '\0';
205 if (ofile
&& terminate_after_phase
)
209 * We must call ofmt->filename _anyway_, even if the user
210 * has specified their own output file, because some
211 * formats (eg OBJ and COFF) use ofmt->filename to find out
212 * the name of the input file and then put that inside the
215 ofmt
->filename (inname
, outname
, report_error
);
217 ofile
= fopen(outname
, "wb");
219 report_error (ERR_FATAL
| ERR_NOFILE
,
220 "unable to open output file `%s'", outname
);
223 * We must call init_labels() before ofmt->init() since
224 * some object formats will want to define labels in their
225 * init routines. (eg OS/2 defines the FLAT group)
228 ofmt
->init (ofile
, report_error
, define_label
, evaluate
);
229 assemble_file (inname
);
230 if (!terminate_after_phase
) {
235 * We had an fclose on the output file here, but we
236 * actually do that in all the object file drivers as well,
237 * so we're leaving out the one here.
240 if (terminate_after_phase
) {
252 if (terminate_after_phase
)
258 static int process_arg (char *p
, char *q
) {
271 case 'o': /* these parameters take values */
277 if (p
[2]) /* the parameter's in the option */
280 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
281 "option `-%c' requires an argument",
285 advance
= 1, param
= q
;
286 if (p
[1]=='o') { /* output file */
287 strcpy (outname
, param
);
288 } else if (p
[1]=='f') { /* output format */
289 ofmt
= ofmt_find(param
);
291 report_error (ERR_FATAL
| ERR_NOFILE
| ERR_USAGE
,
292 "unrecognised output format `%s'",
295 } else if (p
[1]=='p') { /* pre-include */
296 pp_pre_include (param
);
297 } else if (p
[1]=='d') { /* pre-define */
298 pp_pre_define (param
);
299 } else if (p
[1]=='i') { /* include search path */
300 pp_include_path (param
);
301 } else if (p
[1]=='l') { /* listing file */
302 strcpy (listname
, param
);
306 fprintf(use_stdout
? stdout
: stderr
,
307 "usage: nasm [-o outfile] [-f format] [-l listfile]"
308 " [options...] filename\n");
309 fprintf(use_stdout
? stdout
: stderr
,
310 " or nasm -r for version info\n\n");
311 fprintf(use_stdout
? stdout
: stderr
,
312 " -e means preprocess only; "
313 "-a means don't preprocess\n");
314 fprintf(use_stdout
? stdout
: stderr
,
315 " -s means send errors to stdout not stderr\n");
316 fprintf(use_stdout
? stdout
: stderr
,
317 " -i<path> adds a pathname to the include file"
318 " path\n -p<file> pre-includes a file;"
319 " -d<macro>[=<value] pre-defines a macro\n");
320 fprintf(use_stdout
? stdout
: stderr
,
321 " -w+foo enables warnings about foo; "
322 "-w-foo disables them\n where foo can be:\n");
323 for (i
=1; i
<=ERR_WARN_MAX
; i
++)
324 fprintf(use_stdout
? stdout
: stderr
,
325 " %-16s%s (default %s)\n",
326 suppressed_names
[i
], suppressed_what
[i
],
327 suppressed
[i
] ? "off" : "on");
328 fprintf(use_stdout
? stdout
: stderr
,
329 "\nvalid output formats for -f are"
330 " (`*' denotes default):\n");
331 ofmt_list(ofmt
, use_stdout
? stdout
: stderr
);
332 exit (0); /* never need usage message here */
335 fprintf(use_stdout
? stdout
: stderr
,
336 "NASM version %s\n", NASM_VER
);
337 exit (0); /* never need usage message here */
339 case 'e': /* preprocess only */
340 preprocess_only
= TRUE
;
342 case 'a': /* assemble only - don't preprocess */
346 if (p
[2] != '+' && p
[2] != '-') {
347 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
348 "invalid option to `-w'");
350 for (i
=1; i
<=ERR_WARN_MAX
; i
++)
351 if (!nasm_stricmp(p
+3, suppressed_names
[i
]))
353 if (i
<= ERR_WARN_MAX
)
354 suppressed
[i
] = (p
[2] == '-');
356 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
357 "invalid option to `-w'");
361 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
362 "unrecognised option `-%c'",
368 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
369 "more than one input file specified");
377 static void parse_cmdline(int argc
, char **argv
) {
378 char *envreal
, *envcopy
, *p
, *q
, *arg
, *prevarg
;
379 char separator
= ' ';
381 *inname
= *outname
= *listname
= '\0';
384 * First, process the NASM environment variable.
386 envreal
= getenv("NASM");
389 envcopy
= nasm_strdup(envreal
);
395 while (*p
&& *p
!= separator
) p
++;
396 while (*p
== separator
) *p
++ = '\0';
399 if (process_arg (prevarg
, arg
))
405 process_arg (arg
, NULL
);
408 * Now process the actual command line.
413 i
= process_arg (argv
[0], argc
> 1 ? argv
[1] : NULL
);
414 argv
+= i
, argc
-= i
;
418 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
419 "no input file specified");
422 static void assemble_file (char *fname
) {
423 char *value
, *p
, *q
, *special
, *line
;
425 int i
, rn_error
, validid
;
427 struct tokenval tokval
;
432 current_seg
= ofmt
->section(NULL
, pass
, &sb
);
433 preproc
->reset(fname
, 1, report_error
, evaluate
, &nasmlist
);
434 strcpy(currentfile
,fname
);
439 eval_info (NULL
, current_seg
, offs
); /* set $ */
440 while ( (line
= preproc
->getline()) ) {
444 if (line
[0] == '%') {
446 char buf
[FILENAME_MAX
];
449 * This will be a line number directive. They come
450 * straight from the preprocessor, so we'll subject
451 * them to only minimal error checking.
453 if (strncmp(line
, "%line", 5)) {
454 if (preproc
== &no_pp
)
455 report_error (ERR_WARNING
, "unknown `%%' directive in "
456 " preprocessed source");
457 } else if (sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) != 3) {
458 report_error (ERR_WARNING
, "bogus line number directive in"
459 " preprocessed source");
463 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
464 currentfile
[FILENAME_MAX
-1] = '\0';
469 /* here we parse our directives; this is not handled by the 'real'
471 if ( (i
= getkw (line
, &value
)) ) {
473 case 1: /* [SEGMENT n] */
474 seg
= ofmt
->section (value
, pass
, &sb
);
476 report_error (ERR_NONFATAL
,
477 "segment name `%s' not recognised",
483 case 2: /* [EXTERN label:special] */
485 value
++; /* skip initial $ if present */
490 while (*q
&& *q
!= ':') {
496 report_error (ERR_NONFATAL
,
497 "identifier expected after EXTERN");
505 if (!is_extern(value
)) { /* allow re-EXTERN to be ignored */
506 declare_as_global (value
, special
, report_error
);
507 define_label (value
, seg_alloc(), 0L, NULL
, FALSE
, TRUE
,
511 case 3: /* [BITS bits] */
512 switch (atoi(value
)) {
518 report_error(ERR_NONFATAL
,
519 "`%s' is not a valid argument to [BITS]",
524 case 4: /* [GLOBAL symbol:special] */
526 value
++; /* skip initial $ if present */
531 while (*q
&& *q
!= ':') {
537 report_error (ERR_NONFATAL
,
538 "identifier expected after GLOBAL");
546 declare_as_global (value
, special
, report_error
);
548 case 5: /* [COMMON symbol size:special] */
553 while (*p
&& !isspace(*p
)) {
559 report_error (ERR_NONFATAL
,
560 "identifier expected after COMMON");
566 while (*p
&& isspace(*p
))
569 while (*q
&& *q
!= ':')
576 size
= readnum (p
, &rn_error
);
578 report_error (ERR_NONFATAL
, "invalid size specified"
579 " in COMMON declaration");
581 define_common (value
, seg_alloc(), size
,
582 special
, ofmt
, report_error
);
584 report_error (ERR_NONFATAL
, "no size specified in"
585 " COMMON declaration");
587 case 6: /* [ABSOLUTE address] */
588 current_seg
= NO_SEG
;
590 stdscan_bufptr
= value
;
591 tokval
.t_type
= TOKEN_INVALID
;
592 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, report_error
,
596 report_error (ERR_NONFATAL
, "cannot use non-"
597 "relocatable expression as ABSOLUTE"
600 abs_seg
= reloc_seg(e
);
601 abs_offset
= reloc_value(e
);
604 abs_offset
= 0x100;/* don't go near zero in case of / */
607 if (!ofmt
->directive (line
+1, value
, 1))
608 report_error (ERR_NONFATAL
, "unrecognised directive [%s]",
613 parse_line (1, line
, &output_ins
,
614 report_error
, evaluate
, eval_info
);
615 if (output_ins
.forw_ref
)
616 *(int *)saa_wstruct(forwrefs
) = globallineno
;
619 * Hack to prevent phase error in the code
623 * We rule that the presence of a forward reference
624 * cancels out the UNITY property of the number 1. This
625 * isn't _strictly_ necessary in pass one, since the
626 * problem occurs in pass two, but for the sake of
627 * having the passes as near to identical as we can
628 * manage, we do it like this.
630 if (output_ins
.forw_ref
) {
632 for (i
=0; i
<output_ins
.operands
; i
++)
633 output_ins
.oprs
[i
].type
&= ~ONENESS
;
636 if (output_ins
.opcode
== I_EQU
) {
638 * Special `..' EQUs get processed in pass two,
639 * except `..@' macro-processor EQUs which are done
640 * in the normal place.
642 if (!output_ins
.label
)
643 report_error (ERR_NONFATAL
,
644 "EQU not preceded by label");
645 else if (output_ins
.label
[0] != '.' ||
646 output_ins
.label
[1] != '.' ||
647 output_ins
.label
[2] == '@') {
648 if (output_ins
.operands
== 1 &&
649 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
650 output_ins
.oprs
[0].wrt
== NO_SEG
) {
651 define_label (output_ins
.label
,
652 output_ins
.oprs
[0].segment
,
653 output_ins
.oprs
[0].offset
,
654 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
655 } else if (output_ins
.operands
== 2 &&
656 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
657 (output_ins
.oprs
[0].type
& COLON
) &&
658 output_ins
.oprs
[0].segment
== NO_SEG
&&
659 output_ins
.oprs
[0].wrt
== NO_SEG
&&
660 (output_ins
.oprs
[1].type
& IMMEDIATE
) &&
661 output_ins
.oprs
[1].segment
== NO_SEG
&&
662 output_ins
.oprs
[1].wrt
== NO_SEG
) {
663 define_label (output_ins
.label
,
664 output_ins
.oprs
[0].offset
| SEG_ABS
,
665 output_ins
.oprs
[1].offset
,
666 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
668 report_error(ERR_NONFATAL
, "bad syntax for EQU");
671 if (output_ins
.label
)
672 define_label (output_ins
.label
,
673 current_seg
==NO_SEG
? abs_seg
: current_seg
,
674 offs
, NULL
, TRUE
, FALSE
, ofmt
, report_error
);
675 offs
+= insn_size (current_seg
, offs
, sb
,
676 &output_ins
, report_error
);
679 cleanup_insn (&output_ins
);
683 eval_info (NULL
, current_seg
, offs
); /* set $ */
687 if (terminate_after_phase
) {
697 saa_rewind (forwrefs
);
699 nasmlist
.init(listname
, report_error
);
701 int *p
= saa_rstruct (forwrefs
);
707 current_seg
= ofmt
->section(NULL
, pass
, &sb
);
709 offsets
= raa_init();
710 preproc
->reset(fname
, 2, report_error
, evaluate
, &nasmlist
);
711 strcpy(currentfile
,fname
);
716 eval_info (NULL
, current_seg
, offs
); /* set $ */
717 while ( (line
= preproc
->getline()) ) {
721 if (line
[0] == '%') {
723 char buf
[FILENAME_MAX
];
726 * This will be a line number directive. They come
727 * straight from the preprocessor, so we'll subject
728 * them to only minimal error checking.
730 if (!strncmp(line
, "%line", 5) &&
731 sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) == 3) {
734 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
735 currentfile
[FILENAME_MAX
-1] = '\0';
740 /* here we parse our directives; this is not handled by
741 * the 'real' parser. */
742 if ( (i
= getkw (line
, &value
)) ) {
744 case 1: /* [SEGMENT n] */
745 seg
= ofmt
->section (value
, pass
, &sb
);
747 report_error (ERR_PANIC
,
748 "invalid segment name on pass two");
752 case 2: /* [EXTERN label] */
754 while (*q
&& *q
!= ':')
758 ofmt
->symdef(value
, 0L, 0L, 3, q
);
761 case 3: /* [BITS bits] */
762 switch (atoi(value
)) {
768 report_error(ERR_PANIC
,
769 "invalid [BITS] value on pass two",
774 case 4: /* [GLOBAL symbol] */
776 while (*q
&& *q
!= ':')
780 ofmt
->symdef(value
, 0L, 0L, 3, q
);
783 case 5: /* [COMMON symbol size] */
785 while (*q
&& *q
!= ':') {
792 ofmt
->symdef(value
, 0L, 0L, 3, q
);
795 case 6: /* [ABSOLUTE addr] */
796 current_seg
= NO_SEG
;
798 stdscan_bufptr
= value
;
799 tokval
.t_type
= TOKEN_INVALID
;
800 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 2, report_error
,
804 report_error (ERR_PANIC
, "non-reloc ABSOLUTE address"
807 abs_seg
= reloc_seg(e
);
808 abs_offset
= reloc_value(e
);
811 report_error (ERR_PANIC
, "invalid ABSOLUTE address "
815 if (!ofmt
->directive (line
+1, value
, 2))
816 report_error (ERR_PANIC
, "invalid directive on pass two");
820 parse_line (2, line
, &output_ins
,
821 report_error
, evaluate
, eval_info
);
822 if (globallineno
== forwline
) {
823 int *p
= saa_rstruct (forwrefs
);
828 output_ins
.forw_ref
= TRUE
;
830 output_ins
.forw_ref
= FALSE
;
833 * Hack to prevent phase error in the code
837 if (output_ins
.forw_ref
) {
839 for (i
=0; i
<output_ins
.operands
; i
++)
840 output_ins
.oprs
[i
].type
&= ~ONENESS
;
844 if (output_ins
.label
)
845 define_label_stub (output_ins
.label
, report_error
);
846 if (output_ins
.opcode
== I_EQU
) {
848 * Special `..' EQUs get processed here, except
849 * `..@' macro processor EQUs which are done above.
851 if (output_ins
.label
[0] == '.' &&
852 output_ins
.label
[1] == '.' &&
853 output_ins
.label
[2] != '@') {
854 if (output_ins
.operands
== 1 &&
855 (output_ins
.oprs
[0].type
& IMMEDIATE
)) {
856 define_label (output_ins
.label
,
857 output_ins
.oprs
[0].segment
,
858 output_ins
.oprs
[0].offset
,
859 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
860 } else if (output_ins
.operands
== 2 &&
861 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
862 (output_ins
.oprs
[0].type
& COLON
) &&
863 output_ins
.oprs
[0].segment
== NO_SEG
&&
864 (output_ins
.oprs
[1].type
& IMMEDIATE
) &&
865 output_ins
.oprs
[1].segment
== NO_SEG
) {
866 define_label (output_ins
.label
,
867 output_ins
.oprs
[0].offset
| SEG_ABS
,
868 output_ins
.oprs
[1].offset
,
869 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
871 report_error(ERR_NONFATAL
, "bad syntax for EQU");
874 offs
+= assemble (current_seg
, offs
, sb
,
875 &output_ins
, ofmt
, report_error
, &nasmlist
);
876 cleanup_insn (&output_ins
);
882 eval_info (NULL
, current_seg
, offs
); /* set $ */
888 static int getkw (char *buf
, char **value
) {
894 while (*p
&& *p
!= ']') p
++;
898 while (*p
&& *p
!= ';') {
906 while (*buf
&& *buf
!=' ' && *buf
!=']' && *buf
!='\t')
913 while (isspace(*buf
)) buf
++; /* beppu - skip leading whitespace */
915 while (*buf
!=']') buf
++;
920 if (!strcmp(p
, "segment") || !strcmp(p
, "section"))
922 if (!strcmp(p
, "extern"))
924 if (!strcmp(p
, "bits"))
926 if (!strcmp(p
, "global"))
928 if (!strcmp(p
, "common"))
930 if (!strcmp(p
, "absolute"))
935 static void report_error (int severity
, char *fmt
, ...) {
939 * See if it's a suppressed warning.
941 if ((severity
& ERR_MASK
) == ERR_WARNING
&&
942 (severity
& ERR_WARN_MASK
) != 0 &&
943 suppressed
[ (severity
& ERR_WARN_MASK
) >> ERR_WARN_SHR
])
944 return; /* and bail out if so */
947 * See if it's a pass-one only warning and we're not in pass one.
949 if ((severity
& ERR_PASS1
) && pass
!= 1)
952 if (severity
& ERR_NOFILE
)
953 fputs ("nasm: ", use_stdout
? stdout
: stderr
);
955 fprintf (use_stdout
? stdout
: stderr
, "%s:%d: ", currentfile
,
956 lineno
+ (severity
& ERR_OFFBY1
? lineinc
: 0));
958 if ( (severity
& ERR_MASK
) == ERR_WARNING
)
959 fputs ("warning: ", use_stdout
? stdout
: stderr
);
960 else if ( (severity
& ERR_MASK
) == ERR_PANIC
)
961 fputs ("panic: ", use_stdout
? stdout
: stderr
);
964 vfprintf (use_stdout
? stdout
: stderr
, fmt
, ap
);
965 fputc ('\n', use_stdout
? stdout
: stderr
);
967 if (severity
& ERR_USAGE
)
970 switch (severity
& ERR_MASK
) {
972 /* no further action, by definition */
975 terminate_after_phase
= TRUE
;
984 exit(1); /* instantly die */
985 break; /* placate silly compilers */
987 abort(); /* halt, catch fire, and dump core */
992 static void usage(void) {
993 fputs("type `nasm -h' for help\n", use_stdout
? stdout
: stderr
);
996 static void register_output_formats(void) {
997 /* Flat-form binary format */
999 extern struct ofmt of_bin
;
1001 /* Unix formats: a.out, COFF, ELF */
1003 extern struct ofmt of_aout
;
1006 extern struct ofmt of_aoutb
;
1009 extern struct ofmt of_coff
;
1012 extern struct ofmt of_elf
;
1014 /* Linux strange format: as86 */
1016 extern struct ofmt of_as86
;
1018 /* DOS and DOS-ish formats: OBJ, OS/2, Win32 */
1020 extern struct ofmt of_obj
;
1023 extern struct ofmt of_win32
;
1026 extern struct ofmt of_rdf
;
1028 #ifdef OF_DBG /* debug format must be included specifically */
1029 extern struct ofmt of_dbg
;
1033 ofmt_register (&of_bin
);
1036 ofmt_register (&of_aout
);
1039 ofmt_register (&of_aoutb
);
1042 ofmt_register (&of_coff
);
1045 ofmt_register (&of_elf
);
1048 ofmt_register (&of_as86
);
1051 ofmt_register (&of_obj
);
1054 ofmt_register (&of_win32
);
1057 ofmt_register (&of_rdf
);
1060 ofmt_register (&of_dbg
);
1063 * set the default format
1068 #define BUF_DELTA 512
1070 static FILE *no_pp_fp
;
1071 static efunc no_pp_err
;
1072 static ListGen
*no_pp_list
;
1074 static void no_pp_reset (char *file
, int pass
, efunc error
, evalfunc eval
,
1077 no_pp_fp
= fopen(file
, "r");
1079 no_pp_err (ERR_FATAL
| ERR_NOFILE
,
1080 "unable to open input file `%s'", file
);
1081 no_pp_list
= listgen
;
1082 (void) pass
; /* placate compilers */
1083 (void) eval
; /* placate compilers */
1086 static char *no_pp_getline (void) {
1087 char *buffer
, *p
, *q
;
1090 bufsize
= BUF_DELTA
;
1091 buffer
= nasm_malloc(BUF_DELTA
);
1094 q
= fgets(p
, bufsize
-(p
-buffer
), no_pp_fp
);
1098 if (p
> buffer
&& p
[-1] == '\n')
1100 if (p
-buffer
> bufsize
-10) {
1101 bufsize
+= BUF_DELTA
;
1102 buffer
= nasm_realloc(buffer
, bufsize
);
1106 if (!q
&& p
== buffer
) {
1112 * Play safe: remove CRs as well as LFs, if any of either are
1113 * present at the end of the line.
1115 while (p
> buffer
&& (p
[-1] == '\n' || p
[-1] == '\r'))
1119 * Handle spurious ^Z, which may be inserted into source files
1120 * by some file transfer utilities.
1122 buffer
[strcspn(buffer
, "\032")] = '\0';
1124 no_pp_list
->line (LIST_READ
, buffer
);
1129 static void no_pp_cleanup (void) {