⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nasm.c

📁 CC386 is a general-purpose 32-bit C compiler. It is not an optimizing compiler but given that the co
💻 C
📖 第 1 页 / 共 4 页
字号:
		if (opt == -99) report_error(ERR_FATAL,
			"command line optimization level must be 'v', 0..3 or <nn>");
	    } else if (p[1]=='P' || p[1]=='p') {    /* pre-include */
		pp_pre_include (param);
	    } else if (p[1]=='D' || p[1]=='d') {    /* pre-define */
		pp_pre_define (param);
	    } else if (p[1]=='U' || p[1]=='u') {    /* un-define */
		pp_pre_undefine (param);
	    } else if (p[1]=='I' || p[1]=='i') {    /* include search path */
		pp_include_path (param);
	    } else if (p[1]=='l') {    /* listing file */
		strcpy (listname, param);
	    } else if (p[1]=='E') {    /* error messages file */
		error_file = fopen(param, "w");
		if ( !error_file ) {
		  error_file = stderr; /* Revert to default! */
		  report_error (ERR_FATAL | ERR_NOFILE | ERR_USAGE,
				"cannot open file `%s' for error messages",
				param);
		}
	    } else if (p[1] == 'F') {  /* specify debug format */
	        ofmt->current_dfmt = dfmt_find(ofmt, param);
	        if (!ofmt->current_dfmt) {
	            report_error (ERR_FATAL | ERR_NOFILE | ERR_USAGE,
	    	    		  "unrecognized debug format `%s' for"
			    	  " output format `%s'",
				  param, ofmt->shortname);
                }
            } else if (p[1] == 'X') { /* specify error reporting format */
		if (nasm_stricmp("vc", param) == 0)
		    report_error = report_error_vc;
		else if (nasm_stricmp("gnu", param) == 0)
		    report_error = report_error_gnu;
		else
		    report_error (ERR_FATAL | ERR_NOFILE | ERR_USAGE,
				  "unrecognized error reporting format `%s'",
				  param);
	    }
	    break;
	  case 'g':
	    using_debug_info = TRUE;
	    break;
	  case 'h':
	    printf("usage: nasm [-@ response file] [-o outfile] [-f format] "
		   "[-l listfile]\n"
		   "            [options...] [--] filename\n"
		   "    or nasm -r   for version info (obsolete)\n"
		   "    or nasm -v   for version info (preferred)\n\n"
		   "    -t          Assemble in SciTech TASM compatible mode\n"
		   "    -g          Generate debug information in selected format.\n");
	    printf("    -e          preprocess only (writes output to stdout by default)\n"
		   "    -a          don't preprocess (assemble only)\n"
		   "    -M          generate Makefile dependencies on stdout\n\n"
		   "    -E<file>    redirect error messages to file\n"
		   "    -s          redirect error messages to stdout\n\n"
		   "    -F format   select a debugging format\n\n"
		   "    -I<path>    adds a pathname to the include file path\n");
	    printf("    -O<digit>   optimize branch offsets (-O0 disables, default)\n"
		   "    -P<file>    pre-includes a file\n"
		   "    -D<macro>[=<value>] pre-defines a macro\n"
		   "    -U<macro>   undefines a macro\n"
		   "    -X<format>  specifies error reporting format (gnu or vc)\n"
		   "    -w+foo      enables warnings about foo; -w-foo disables them\n"
		   "where foo can be:\n");
	    for (i=1; i<=ERR_WARN_MAX; i++)
		printf("    %-23s %s (default %s)\n",
		       suppressed_names[i], suppressed_what[i],
		       suppressed[i] ? "off" : "on");
	    printf ("\nresponse files should contain command line parameters"
		    ", one per line.\n");
	    if (p[2] == 'f') {
		printf("\nvalid output formats for -f are"
		       " (`*' denotes default):\n");
		ofmt_list(ofmt, stdout);
	    }
	    else {
		printf ("\nFor a list of valid output formats, use -hf.\n");
		printf ("For a list of debug formats, use -f <form> -y.\n");
	    }
	    exit (0);		       /* never need usage message here */
	    break;
          case 'y':
	    printf("\nvalid debug formats for '%s' output format are"
		   " ('*' denotes default):\n",
		ofmt->shortname);
	    dfmt_list(ofmt, stdout);
	    exit(0);
	    break;
	  case 't':
	    tasm_compatible_mode = TRUE;
	    break;
	  case 'r':
	  case 'v':
	  {
	      const char *nasm_version_string =
        "NASM version " NASM_VER " compiled on " __DATE__ " (OMF Virtual Extensions/LADSoft)"
#ifdef DEBUG
		  " with -DDEBUG"
#endif
		  ;
	      puts(nasm_version_string);
	      exit (0);		       /* never need usage message here */
	  }
	  break;
	  case 'e':		       /* preprocess only */
	    operating_mode = op_preprocess;
	    break;
	  case 'a':		       /* assemble only - don't preprocess */
	    preproc = &no_pp;
	    break;
	  case 'w':
	    if (p[2] != '+' && p[2] != '-') {
		report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			      "invalid option to `-w'");
	    } else {
                for (i=1; i<=ERR_WARN_MAX; i++)
		    if (!nasm_stricmp(p+3, suppressed_names[i]))
			break;
		if (i <= ERR_WARN_MAX)
		    suppressed[i] = (p[2] == '-');
		else
		    report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
				  "invalid option to `-w'");
	    }
	    break;
          case 'M':
	    operating_mode = op_depend;
	    break;

	  case '-':
	  {
		int s;
		
		if (p[2]==0) {		/* -- => stop processing options */
		    stopoptions = 1;
		    break;
		}
		for(s=0; textopts[s].label; s++)
		{
			if(!nasm_stricmp(p+2, textopts[s].label))
			{
				break;
			}
		}

		switch(s)
		{
		
			case OPT_PREFIX:
			case OPT_POSTFIX:
			{
				if (!q)
				{
					report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			      			"option `--%s' requires an argument",
			      			p+2);
					break;
				}
				else
				{
					advance = 1, param = q;
				}
				
				if(s == OPT_PREFIX)
				{
					strncpy(lprefix,param,PREFIX_MAX-1);
					lprefix[PREFIX_MAX-1]=0;
					break;
				}
				if(s == OPT_POSTFIX)
				{
					strncpy(lpostfix,param,POSTFIX_MAX-1);
					lpostfix[POSTFIX_MAX-1]=0;
					break;
				}
				break;
			}
			default:
			{
				report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			  		"unrecognised option `--%s'",
			  		p+2);
				break;
			}
		}
		break;
	  }

	  default:
	    if (!ofmt->setinfo(GI_SWITCH,&p))
	    	report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			  "unrecognised option `-%c'",
			  p[1]);
	    break;
	}
    }
    else
    {
	if (*inname) {
	    report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			  "more than one input file specified");
	} else
	    strcpy(inname, p);
    }

    return advance;
}

#define ARG_BUF_DELTA 128

static void process_respfile (FILE *rfile)
{
    char *buffer, *p, *q, *prevarg;
    int bufsize, prevargsize;

    bufsize = prevargsize = ARG_BUF_DELTA;
    buffer = nasm_malloc(ARG_BUF_DELTA);
    prevarg = nasm_malloc(ARG_BUF_DELTA);
    prevarg[0] = '\0';

    while (1) {   /* Loop to handle all lines in file */

	p = buffer;
	while (1) {  /* Loop to handle long lines */
	    q = fgets(p, bufsize-(p-buffer), rfile);
	    if (!q)
		break;
	    p += strlen(p);
	    if (p > buffer && p[-1] == '\n')
		break;
	    if (p-buffer > bufsize-10) {
		int offset;
		offset = p - buffer;
		bufsize += ARG_BUF_DELTA;
		buffer = nasm_realloc(buffer, bufsize);
		p = buffer + offset;
	    }
	}

	if (!q && p == buffer) {
	    if (prevarg[0])
		process_arg (prevarg, NULL);
	    nasm_free (buffer);
	    nasm_free (prevarg);
	    return;
	}

	/*
	 * Play safe: remove CRs, LFs and any spurious ^Zs, if any of
	 * them are present at the end of the line.
	 */
	*(p = &buffer[strcspn(buffer, "\r\n\032")]) = '\0';

	while (p > buffer && isspace(p[-1]))
	    *--p = '\0';

	p = buffer;
	while (isspace(*p))
	    p++;

	if (process_arg (prevarg, p))
	    *p = '\0';

	if (strlen(p) > prevargsize-10) {
	    prevargsize += ARG_BUF_DELTA;
	    prevarg = nasm_realloc(prevarg, prevargsize);
	}
	strcpy (prevarg, p);
    }
}

/* Function to process args from a string of args, rather than the
 * argv array. Used by the environment variable and response file
 * processing.
 */
static void process_args (char *args) {
    char *p, *q, *arg, *prevarg;
    char separator = ' ';

    p = args;
    if (*p && *p != '-')
	separator = *p++;
    arg = NULL;
    while (*p) {
	q = p;
	while (*p && *p != separator) p++;
	while (*p == separator) *p++ = '\0';
	prevarg = arg;
	arg = q;
	if (process_arg (prevarg, arg))
	    arg = NULL;
    }
    if (arg)
	process_arg (arg, NULL);
}

static void parse_cmdline(int argc, char **argv)
{
    FILE *rfile;
    char *envreal, *envcopy=NULL, *p, *arg;

    *inname = *outname = *listname = '\0';

    /*
     * First, process the NASMENV environment variable.
     */
    envreal = getenv("NASMENV");
    arg = NULL;
    if (envreal) {
	envcopy = nasm_strdup(envreal);
	process_args(envcopy);
	nasm_free (envcopy);
    }

    /*
     * Now process the actual command line.
     */
    while (--argc)
    {
	int i;
	argv++;
	if (argv[0][0] == '@') {
	    /* We have a response file, so process this as a set of
	     * arguments like the environment variable. This allows us
	     * to have multiple arguments on a single line, which is
	     * different to the -@resp file processing below for regular
	     * NASM.
	     */
	    char *str = malloc(2048);
	    FILE *f = fopen(&argv[0][1],"r");
	    if (!str) {
		printf("out of memory");
		exit(-1);
		}
	    if (f) {
		while (fgets(str,2048,f)) {
		    process_args(str);
		}
		fclose(f);
	    }
	    free(str);
	    argc--;
	    argv++;
	}
	if (!stopoptions && argv[0][0] == '-' && argv[0][1] == '@') {
	    if ((p = get_param (argv[0], argc > 1 ? argv[1] : NULL, &i))) {
		if ((rfile = fopen(p, "r"))) {
		    process_respfile (rfile);
		    fclose(rfile);
		} else
		    report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
			    "unable to open response file `%s'", p);
	    }
	} else
	    i = process_arg (argv[0], argc > 1 ? argv[1] : NULL);
	argv += i, argc -= i;
    }

    if (!*inname)
	report_error (ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
		      "no input file specified");
}


static void assemble_file (char *fname)
{
    char   * directive, * value, * p, * q, * special, * line, debugid[80];
    insn   output_ins;
    int    i, rn_error, validid;
    long   seg, offs;
    struct tokenval tokval;
    expr   * e;
    int pass, pass_max;
    int pass_cnt = 0;		/* count actual passes */

    if (cmd_sb == 32 && cmd_cpu < IF_386)
      report_error(ERR_FATAL, "command line: "
                    "32-bit segment size requires a higher cpu");

   pass_max = (optimizing>0 ? optimizing : 0) + 2;    /* passes 1, optimizing, then 2 */
   pass0 = !(optimizing>0);		/* start at 1 if not optimizing */
   for (pass = 1; pass <= pass_max  &&  pass0 <= 2; pass++) {
      int pass1, pass2;
      ldfunc def_label;

      pass1 = pass < pass_max ? 1 : 2;  /* seq is 1, 1, 1,..., 1, 2 */
      pass2 = pass > 1 ? 2 : 1;         /* seq is 1, 2, 2,..., 2, 2 */
  /*      pass0                            seq is 0, 0, 0,..., 1, 2 */

      def_label = pass > 1 ? redefine_label : define_label;


      sb = cmd_sb;        /* set 'bits' to command line default */
      cpu = cmd_cpu;
      if (pass0 == 2) {
         if (*listname)
            nasmlist.init(listname, report_error);
      }
      in_abs_seg = FALSE;
      global_offset_changed = FALSE;      /* set by redefine_label */
      location.segment = ofmt->section(NULL, pass2, &sb);
      if (pass > 1) {
         saa_rewind (forwrefs);
         forwref = saa_rstruct (forwrefs);
         raa_free (offsets);
         offsets = raa_init();
      }
      preproc->reset(fname, pass1, report_error, evaluate, &nasmlist);
      globallineno = 0;
      if (pass == 1) location.known = TRUE;
      location.offset = offs = GET_CURR_OFFS;

      while ( (line = preproc->getline()) )
      {
         globallineno++;

         /* here we parse our directives; this is not handled by the 'real'
            * parser. */
         directive = line;
         if ( (i = getkw (&directive, &value)) )
         {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -