]>
git.saurik.com Git - apple/boot.git/blob - i386/nasm/nasm.c
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
24 /* The Netwide Assembler main program module
26 * The Netwide Assembler is copyright (C) 1996 Simon Tatham and
27 * Julian Hall. All rights reserved. The software is
28 * redistributable under the licence given in the file "Licence"
29 * distributed in the NASM archive.
48 static void report_error (int, char *, ...);
49 static void parse_cmdline (int, char **);
50 static void assemble_file (char *);
51 static int getkw (char *buf
, char **value
);
52 static void register_output_formats(void);
53 static void usage(void);
56 static char inname
[FILENAME_MAX
];
57 static char outname
[FILENAME_MAX
];
58 static char listname
[FILENAME_MAX
];
59 static int lineno
; /* for error reporting */
60 static int lineinc
; /* set by [LINE] or [ONELINE] */
61 static int globallineno
; /* for forward-reference tracking */
63 static struct ofmt
*ofmt
= NULL
;
65 static FILE *ofile
= NULL
;
66 static int sb
= 16; /* by default */
68 static int use_stdout
= FALSE
; /* by default, errors to stderr */
70 static long current_seg
, abs_seg
;
71 static struct RAA
*offsets
;
72 static long abs_offset
;
74 static struct SAA
*forwrefs
; /* keep track of forward references */
77 static Preproc
*preproc
;
78 static int preprocess_only
;
80 /* used by error function to report location */
81 static char currentfile
[FILENAME_MAX
];
84 * Which of the suppressible warnings are suppressed. Entry zero
85 * doesn't do anything. Initial defaults are given here.
87 static char suppressed
[1+ERR_WARN_MAX
] = {
92 * The option names for the suppressible warnings. As before, entry
95 static char *suppressed_names
[1+ERR_WARN_MAX
] = {
96 NULL
, "macro-params", "orphan-labels", "number-overflow"
100 * The explanations for the suppressible warnings. As before, entry
103 static char *suppressed_what
[1+ERR_WARN_MAX
] = {
104 NULL
, "macro calls with wrong no. of params",
105 "labels alone on lines without trailing `:'",
106 "numeric constants greater than 0xFFFFFFFF"
110 * This is a null preprocessor which just copies lines from input
111 * to output. It's used when someone explicitly requests that NASM
112 * not preprocess their source file.
115 static void no_pp_reset (char *, int, efunc
, evalfunc
, ListGen
*);
116 static char *no_pp_getline (void);
117 static void no_pp_cleanup (void);
118 static Preproc no_pp
= {
125 * get/set current offset...
127 #define get_curr_ofs (current_seg==NO_SEG?abs_offset:\
128 raa_read(offsets,current_seg))
129 #define set_curr_ofs(x) (current_seg==NO_SEG?(void)(abs_offset=(x)):\
130 (void)(offsets=raa_write(offsets,current_seg,(x))))
132 static int want_usage
;
133 static int terminate_after_phase
;
135 int main(int argc
, char **argv
) {
136 want_usage
= terminate_after_phase
= FALSE
;
138 nasm_set_malloc_error (report_error
);
139 offsets
= raa_init();
140 forwrefs
= saa_init ((long)sizeof(int));
143 preprocess_only
= FALSE
;
147 register_output_formats();
149 parse_cmdline(argc
, argv
);
151 if (terminate_after_phase
) {
158 pp_extra_stdmac (ofmt
->stdmac
);
159 eval_global_info (ofmt
, lookup_label
);
161 if (preprocess_only
) {
165 ofile
= fopen(outname
, "w");
167 report_error (ERR_FATAL
| ERR_NOFILE
,
168 "unable to open output file `%s'", outname
);
172 eval_info ("%", 0L, 0L); /* disallow labels, $ or $$ in exprs */
174 preproc
->reset (inname
, 2, report_error
, evaluate
, &nasmlist
);
175 strcpy(currentfile
,inname
);
178 while ( (line
= preproc
->getline()) ) {
180 char buf
[FILENAME_MAX
];
184 * We must still check for %line directives, so that we
185 * can report errors accurately.
187 if (!strncmp(line
, "%line", 5) &&
188 sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) == 3) {
191 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
192 currentfile
[FILENAME_MAX
-1] = '\0';
204 if (ofile
&& terminate_after_phase
)
208 * We must call ofmt->filename _anyway_, even if the user
209 * has specified their own output file, because some
210 * formats (eg OBJ and COFF) use ofmt->filename to find out
211 * the name of the input file and then put that inside the
214 ofmt
->filename (inname
, outname
, report_error
);
216 ofile
= fopen(outname
, "wb");
218 report_error (ERR_FATAL
| ERR_NOFILE
,
219 "unable to open output file `%s'", outname
);
222 * We must call init_labels() before ofmt->init() since
223 * some object formats will want to define labels in their
224 * init routines. (eg OS/2 defines the FLAT group)
227 ofmt
->init (ofile
, report_error
, define_label
, evaluate
);
228 assemble_file (inname
);
229 if (!terminate_after_phase
) {
234 * We had an fclose on the output file here, but we
235 * actually do that in all the object file drivers as well,
236 * so we're leaving out the one here.
239 if (terminate_after_phase
) {
251 if (terminate_after_phase
)
257 static int process_arg (char *p
, char *q
) {
270 case 'o': /* these parameters take values */
276 if (p
[2]) /* the parameter's in the option */
279 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
280 "option `-%c' requires an argument",
284 advance
= 1, param
= q
;
285 if (p
[1]=='o') { /* output file */
286 strcpy (outname
, param
);
287 } else if (p
[1]=='f') { /* output format */
288 ofmt
= ofmt_find(param
);
290 report_error (ERR_FATAL
| ERR_NOFILE
| ERR_USAGE
,
291 "unrecognised output format `%s'",
294 } else if (p
[1]=='p') { /* pre-include */
295 pp_pre_include (param
);
296 } else if (p
[1]=='d') { /* pre-define */
297 pp_pre_define (param
);
298 } else if (p
[1]=='i') { /* include search path */
299 pp_include_path (param
);
300 } else if (p
[1]=='l') { /* listing file */
301 strcpy (listname
, param
);
305 fprintf(use_stdout
? stdout
: stderr
,
306 "usage: nasm [-o outfile] [-f format] [-l listfile]"
307 " [options...] filename\n");
308 fprintf(use_stdout
? stdout
: stderr
,
309 " or nasm -r for version info\n\n");
310 fprintf(use_stdout
? stdout
: stderr
,
311 " -e means preprocess only; "
312 "-a means don't preprocess\n");
313 fprintf(use_stdout
? stdout
: stderr
,
314 " -s means send errors to stdout not stderr\n");
315 fprintf(use_stdout
? stdout
: stderr
,
316 " -i<path> adds a pathname to the include file"
317 " path\n -p<file> pre-includes a file;"
318 " -d<macro>[=<value] pre-defines a macro\n");
319 fprintf(use_stdout
? stdout
: stderr
,
320 " -w+foo enables warnings about foo; "
321 "-w-foo disables them\n where foo can be:\n");
322 for (i
=1; i
<=ERR_WARN_MAX
; i
++)
323 fprintf(use_stdout
? stdout
: stderr
,
324 " %-16s%s (default %s)\n",
325 suppressed_names
[i
], suppressed_what
[i
],
326 suppressed
[i
] ? "off" : "on");
327 fprintf(use_stdout
? stdout
: stderr
,
328 "\nvalid output formats for -f are"
329 " (`*' denotes default):\n");
330 ofmt_list(ofmt
, use_stdout
? stdout
: stderr
);
331 exit (0); /* never need usage message here */
334 fprintf(use_stdout
? stdout
: stderr
,
335 "NASM version %s\n", NASM_VER
);
336 exit (0); /* never need usage message here */
338 case 'e': /* preprocess only */
339 preprocess_only
= TRUE
;
341 case 'a': /* assemble only - don't preprocess */
345 if (p
[2] != '+' && p
[2] != '-') {
346 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
347 "invalid option to `-w'");
349 for (i
=1; i
<=ERR_WARN_MAX
; i
++)
350 if (!nasm_stricmp(p
+3, suppressed_names
[i
]))
352 if (i
<= ERR_WARN_MAX
)
353 suppressed
[i
] = (p
[2] == '-');
355 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
356 "invalid option to `-w'");
360 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
361 "unrecognised option `-%c'",
367 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
368 "more than one input file specified");
376 static void parse_cmdline(int argc
, char **argv
) {
377 char *envreal
, *envcopy
, *p
, *q
, *arg
, *prevarg
;
378 char separator
= ' ';
380 *inname
= *outname
= *listname
= '\0';
383 * First, process the NASM environment variable.
385 envreal
= getenv("NASM");
388 envcopy
= nasm_strdup(envreal
);
394 while (*p
&& *p
!= separator
) p
++;
395 while (*p
== separator
) *p
++ = '\0';
398 if (process_arg (prevarg
, arg
))
404 process_arg (arg
, NULL
);
407 * Now process the actual command line.
412 i
= process_arg (argv
[0], argc
> 1 ? argv
[1] : NULL
);
413 argv
+= i
, argc
-= i
;
417 report_error (ERR_NONFATAL
| ERR_NOFILE
| ERR_USAGE
,
418 "no input file specified");
421 static void assemble_file (char *fname
) {
422 char *value
, *p
, *q
, *special
, *line
;
424 int i
, rn_error
, validid
;
426 struct tokenval tokval
;
431 current_seg
= ofmt
->section(NULL
, pass
, &sb
);
432 preproc
->reset(fname
, 1, report_error
, evaluate
, &nasmlist
);
433 strcpy(currentfile
,fname
);
438 eval_info (NULL
, current_seg
, offs
); /* set $ */
439 while ( (line
= preproc
->getline()) ) {
443 if (line
[0] == '%') {
445 char buf
[FILENAME_MAX
];
448 * This will be a line number directive. They come
449 * straight from the preprocessor, so we'll subject
450 * them to only minimal error checking.
452 if (strncmp(line
, "%line", 5)) {
453 if (preproc
== &no_pp
)
454 report_error (ERR_WARNING
, "unknown `%%' directive in "
455 " preprocessed source");
456 } else if (sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) != 3) {
457 report_error (ERR_WARNING
, "bogus line number directive in"
458 " preprocessed source");
462 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
463 currentfile
[FILENAME_MAX
-1] = '\0';
468 /* here we parse our directives; this is not handled by the 'real'
470 if ( (i
= getkw (line
, &value
)) ) {
472 case 1: /* [SEGMENT n] */
473 seg
= ofmt
->section (value
, pass
, &sb
);
475 report_error (ERR_NONFATAL
,
476 "segment name `%s' not recognised",
482 case 2: /* [EXTERN label:special] */
484 value
++; /* skip initial $ if present */
489 while (*q
&& *q
!= ':') {
495 report_error (ERR_NONFATAL
,
496 "identifier expected after EXTERN");
504 if (!is_extern(value
)) { /* allow re-EXTERN to be ignored */
505 declare_as_global (value
, special
, report_error
);
506 define_label (value
, seg_alloc(), 0L, NULL
, FALSE
, TRUE
,
510 case 3: /* [BITS bits] */
511 switch (atoi(value
)) {
517 report_error(ERR_NONFATAL
,
518 "`%s' is not a valid argument to [BITS]",
523 case 4: /* [GLOBAL symbol:special] */
525 value
++; /* skip initial $ if present */
530 while (*q
&& *q
!= ':') {
536 report_error (ERR_NONFATAL
,
537 "identifier expected after GLOBAL");
545 declare_as_global (value
, special
, report_error
);
547 case 5: /* [COMMON symbol size:special] */
552 while (*p
&& !isspace(*p
)) {
558 report_error (ERR_NONFATAL
,
559 "identifier expected after COMMON");
565 while (*p
&& isspace(*p
))
568 while (*q
&& *q
!= ':')
575 size
= readnum (p
, &rn_error
);
577 report_error (ERR_NONFATAL
, "invalid size specified"
578 " in COMMON declaration");
580 define_common (value
, seg_alloc(), size
,
581 special
, ofmt
, report_error
);
583 report_error (ERR_NONFATAL
, "no size specified in"
584 " COMMON declaration");
586 case 6: /* [ABSOLUTE address] */
587 current_seg
= NO_SEG
;
589 stdscan_bufptr
= value
;
590 tokval
.t_type
= TOKEN_INVALID
;
591 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 1, report_error
,
595 report_error (ERR_NONFATAL
, "cannot use non-"
596 "relocatable expression as ABSOLUTE"
599 abs_seg
= reloc_seg(e
);
600 abs_offset
= reloc_value(e
);
603 abs_offset
= 0x100;/* don't go near zero in case of / */
606 if (!ofmt
->directive (line
+1, value
, 1))
607 report_error (ERR_NONFATAL
, "unrecognised directive [%s]",
612 parse_line (1, line
, &output_ins
,
613 report_error
, evaluate
, eval_info
);
614 if (output_ins
.forw_ref
)
615 *(int *)saa_wstruct(forwrefs
) = globallineno
;
618 * Hack to prevent phase error in the code
622 * We rule that the presence of a forward reference
623 * cancels out the UNITY property of the number 1. This
624 * isn't _strictly_ necessary in pass one, since the
625 * problem occurs in pass two, but for the sake of
626 * having the passes as near to identical as we can
627 * manage, we do it like this.
629 if (output_ins
.forw_ref
) {
631 for (i
=0; i
<output_ins
.operands
; i
++)
632 output_ins
.oprs
[i
].type
&= ~ONENESS
;
635 if (output_ins
.opcode
== I_EQU
) {
637 * Special `..' EQUs get processed in pass two,
638 * except `..@' macro-processor EQUs which are done
639 * in the normal place.
641 if (!output_ins
.label
)
642 report_error (ERR_NONFATAL
,
643 "EQU not preceded by label");
644 else if (output_ins
.label
[0] != '.' ||
645 output_ins
.label
[1] != '.' ||
646 output_ins
.label
[2] == '@') {
647 if (output_ins
.operands
== 1 &&
648 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
649 output_ins
.oprs
[0].wrt
== NO_SEG
) {
650 define_label (output_ins
.label
,
651 output_ins
.oprs
[0].segment
,
652 output_ins
.oprs
[0].offset
,
653 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
654 } else if (output_ins
.operands
== 2 &&
655 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
656 (output_ins
.oprs
[0].type
& COLON
) &&
657 output_ins
.oprs
[0].segment
== NO_SEG
&&
658 output_ins
.oprs
[0].wrt
== NO_SEG
&&
659 (output_ins
.oprs
[1].type
& IMMEDIATE
) &&
660 output_ins
.oprs
[1].segment
== NO_SEG
&&
661 output_ins
.oprs
[1].wrt
== NO_SEG
) {
662 define_label (output_ins
.label
,
663 output_ins
.oprs
[0].offset
| SEG_ABS
,
664 output_ins
.oprs
[1].offset
,
665 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
667 report_error(ERR_NONFATAL
, "bad syntax for EQU");
670 if (output_ins
.label
)
671 define_label (output_ins
.label
,
672 current_seg
==NO_SEG
? abs_seg
: current_seg
,
673 offs
, NULL
, TRUE
, FALSE
, ofmt
, report_error
);
674 offs
+= insn_size (current_seg
, offs
, sb
,
675 &output_ins
, report_error
);
678 cleanup_insn (&output_ins
);
682 eval_info (NULL
, current_seg
, offs
); /* set $ */
686 if (terminate_after_phase
) {
696 saa_rewind (forwrefs
);
698 nasmlist
.init(listname
, report_error
);
700 int *p
= saa_rstruct (forwrefs
);
706 current_seg
= ofmt
->section(NULL
, pass
, &sb
);
708 offsets
= raa_init();
709 preproc
->reset(fname
, 2, report_error
, evaluate
, &nasmlist
);
710 strcpy(currentfile
,fname
);
715 eval_info (NULL
, current_seg
, offs
); /* set $ */
716 while ( (line
= preproc
->getline()) ) {
720 if (line
[0] == '%') {
722 char buf
[FILENAME_MAX
];
725 * This will be a line number directive. They come
726 * straight from the preprocessor, so we'll subject
727 * them to only minimal error checking.
729 if (!strncmp(line
, "%line", 5) &&
730 sscanf(line
, "%%line %d+%d %s", &ln
, &li
, buf
) == 3) {
733 strncpy (currentfile
, buf
, FILENAME_MAX
-1);
734 currentfile
[FILENAME_MAX
-1] = '\0';
739 /* here we parse our directives; this is not handled by
740 * the 'real' parser. */
741 if ( (i
= getkw (line
, &value
)) ) {
743 case 1: /* [SEGMENT n] */
744 seg
= ofmt
->section (value
, pass
, &sb
);
746 report_error (ERR_PANIC
,
747 "invalid segment name on pass two");
751 case 2: /* [EXTERN label] */
753 while (*q
&& *q
!= ':')
757 ofmt
->symdef(value
, 0L, 0L, 3, q
);
760 case 3: /* [BITS bits] */
761 switch (atoi(value
)) {
767 report_error(ERR_PANIC
,
768 "invalid [BITS] value on pass two",
773 case 4: /* [GLOBAL symbol] */
775 while (*q
&& *q
!= ':')
779 ofmt
->symdef(value
, 0L, 0L, 3, q
);
782 case 5: /* [COMMON symbol size] */
784 while (*q
&& *q
!= ':') {
791 ofmt
->symdef(value
, 0L, 0L, 3, q
);
794 case 6: /* [ABSOLUTE addr] */
795 current_seg
= NO_SEG
;
797 stdscan_bufptr
= value
;
798 tokval
.t_type
= TOKEN_INVALID
;
799 e
= evaluate(stdscan
, NULL
, &tokval
, NULL
, 2, report_error
,
803 report_error (ERR_PANIC
, "non-reloc ABSOLUTE address"
806 abs_seg
= reloc_seg(e
);
807 abs_offset
= reloc_value(e
);
810 report_error (ERR_PANIC
, "invalid ABSOLUTE address "
814 if (!ofmt
->directive (line
+1, value
, 2))
815 report_error (ERR_PANIC
, "invalid directive on pass two");
819 parse_line (2, line
, &output_ins
,
820 report_error
, evaluate
, eval_info
);
821 if (globallineno
== forwline
) {
822 int *p
= saa_rstruct (forwrefs
);
827 output_ins
.forw_ref
= TRUE
;
829 output_ins
.forw_ref
= FALSE
;
832 * Hack to prevent phase error in the code
836 if (output_ins
.forw_ref
) {
838 for (i
=0; i
<output_ins
.operands
; i
++)
839 output_ins
.oprs
[i
].type
&= ~ONENESS
;
843 if (output_ins
.label
)
844 define_label_stub (output_ins
.label
, report_error
);
845 if (output_ins
.opcode
== I_EQU
) {
847 * Special `..' EQUs get processed here, except
848 * `..@' macro processor EQUs which are done above.
850 if (output_ins
.label
[0] == '.' &&
851 output_ins
.label
[1] == '.' &&
852 output_ins
.label
[2] != '@') {
853 if (output_ins
.operands
== 1 &&
854 (output_ins
.oprs
[0].type
& IMMEDIATE
)) {
855 define_label (output_ins
.label
,
856 output_ins
.oprs
[0].segment
,
857 output_ins
.oprs
[0].offset
,
858 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
859 } else if (output_ins
.operands
== 2 &&
860 (output_ins
.oprs
[0].type
& IMMEDIATE
) &&
861 (output_ins
.oprs
[0].type
& COLON
) &&
862 output_ins
.oprs
[0].segment
== NO_SEG
&&
863 (output_ins
.oprs
[1].type
& IMMEDIATE
) &&
864 output_ins
.oprs
[1].segment
== NO_SEG
) {
865 define_label (output_ins
.label
,
866 output_ins
.oprs
[0].offset
| SEG_ABS
,
867 output_ins
.oprs
[1].offset
,
868 NULL
, FALSE
, FALSE
, ofmt
, report_error
);
870 report_error(ERR_NONFATAL
, "bad syntax for EQU");
873 offs
+= assemble (current_seg
, offs
, sb
,
874 &output_ins
, ofmt
, report_error
, &nasmlist
);
875 cleanup_insn (&output_ins
);
881 eval_info (NULL
, current_seg
, offs
); /* set $ */
887 static int getkw (char *buf
, char **value
) {
893 while (*p
&& *p
!= ']') p
++;
897 while (*p
&& *p
!= ';') {
905 while (*buf
&& *buf
!=' ' && *buf
!=']' && *buf
!='\t')
912 while (isspace(*buf
)) buf
++; /* beppu - skip leading whitespace */
914 while (*buf
!=']') buf
++;
919 if (!strcmp(p
, "segment") || !strcmp(p
, "section"))
921 if (!strcmp(p
, "extern"))
923 if (!strcmp(p
, "bits"))
925 if (!strcmp(p
, "global"))
927 if (!strcmp(p
, "common"))
929 if (!strcmp(p
, "absolute"))
934 static void report_error (int severity
, char *fmt
, ...) {
938 * See if it's a suppressed warning.
940 if ((severity
& ERR_MASK
) == ERR_WARNING
&&
941 (severity
& ERR_WARN_MASK
) != 0 &&
942 suppressed
[ (severity
& ERR_WARN_MASK
) >> ERR_WARN_SHR
])
943 return; /* and bail out if so */
946 * See if it's a pass-one only warning and we're not in pass one.
948 if ((severity
& ERR_PASS1
) && pass
!= 1)
951 if (severity
& ERR_NOFILE
)
952 fputs ("nasm: ", use_stdout
? stdout
: stderr
);
954 fprintf (use_stdout
? stdout
: stderr
, "%s:%d: ", currentfile
,
955 lineno
+ (severity
& ERR_OFFBY1
? lineinc
: 0));
957 if ( (severity
& ERR_MASK
) == ERR_WARNING
)
958 fputs ("warning: ", use_stdout
? stdout
: stderr
);
959 else if ( (severity
& ERR_MASK
) == ERR_PANIC
)
960 fputs ("panic: ", use_stdout
? stdout
: stderr
);
963 vfprintf (use_stdout
? stdout
: stderr
, fmt
, ap
);
964 fputc ('\n', use_stdout
? stdout
: stderr
);
966 if (severity
& ERR_USAGE
)
969 switch (severity
& ERR_MASK
) {
971 /* no further action, by definition */
974 terminate_after_phase
= TRUE
;
983 exit(1); /* instantly die */
984 break; /* placate silly compilers */
986 abort(); /* halt, catch fire, and dump core */
991 static void usage(void) {
992 fputs("type `nasm -h' for help\n", use_stdout
? stdout
: stderr
);
995 static void register_output_formats(void) {
996 /* Flat-form binary format */
998 extern struct ofmt of_bin
;
1000 /* Unix formats: a.out, COFF, ELF */
1002 extern struct ofmt of_aout
;
1005 extern struct ofmt of_aoutb
;
1008 extern struct ofmt of_coff
;
1011 extern struct ofmt of_elf
;
1013 /* Linux strange format: as86 */
1015 extern struct ofmt of_as86
;
1017 /* DOS and DOS-ish formats: OBJ, OS/2, Win32 */
1019 extern struct ofmt of_obj
;
1022 extern struct ofmt of_win32
;
1025 extern struct ofmt of_rdf
;
1027 #ifdef OF_DBG /* debug format must be included specifically */
1028 extern struct ofmt of_dbg
;
1032 ofmt_register (&of_bin
);
1035 ofmt_register (&of_aout
);
1038 ofmt_register (&of_aoutb
);
1041 ofmt_register (&of_coff
);
1044 ofmt_register (&of_elf
);
1047 ofmt_register (&of_as86
);
1050 ofmt_register (&of_obj
);
1053 ofmt_register (&of_win32
);
1056 ofmt_register (&of_rdf
);
1059 ofmt_register (&of_dbg
);
1062 * set the default format
1067 #define BUF_DELTA 512
1069 static FILE *no_pp_fp
;
1070 static efunc no_pp_err
;
1071 static ListGen
*no_pp_list
;
1073 static void no_pp_reset (char *file
, int pass
, efunc error
, evalfunc eval
,
1076 no_pp_fp
= fopen(file
, "r");
1078 no_pp_err (ERR_FATAL
| ERR_NOFILE
,
1079 "unable to open input file `%s'", file
);
1080 no_pp_list
= listgen
;
1081 (void) pass
; /* placate compilers */
1082 (void) eval
; /* placate compilers */
1085 static char *no_pp_getline (void) {
1086 char *buffer
, *p
, *q
;
1089 bufsize
= BUF_DELTA
;
1090 buffer
= nasm_malloc(BUF_DELTA
);
1093 q
= fgets(p
, bufsize
-(p
-buffer
), no_pp_fp
);
1097 if (p
> buffer
&& p
[-1] == '\n')
1099 if (p
-buffer
> bufsize
-10) {
1100 bufsize
+= BUF_DELTA
;
1101 buffer
= nasm_realloc(buffer
, bufsize
);
1105 if (!q
&& p
== buffer
) {
1111 * Play safe: remove CRs as well as LFs, if any of either are
1112 * present at the end of the line.
1114 while (p
> buffer
&& (p
[-1] == '\n' || p
[-1] == '\r'))
1118 * Handle spurious ^Z, which may be inserted into source files
1119 * by some file transfer utilities.
1121 buffer
[strcspn(buffer
, "\032")] = '\0';
1123 no_pp_list
->line (LIST_READ
, buffer
);
1128 static void no_pp_cleanup (void) {