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

📄 nasm.c

📁 汇编编译器的最新版本的源码.买了自己动手写操作系统这本书的人一定要下
💻 C
📖 第 1 页 / 共 5 页
字号:
            preproc->cleanup(0);
            if (ofile)
                fclose(ofile);
            if (ofile && terminate_after_phase)
                remove(outname);
        }
        break;

    case op_normal:
        {
            /*
             * We must call ofmt->filename _anyway_, even if the user
             * has specified their own output file, because some
             * formats (eg OBJ and COFF) use ofmt->filename to find out
             * the name of the input file and then put that inside the
             * file.
             */
            ofmt->filename(inname, outname, report_error);

            ofile = fopen(outname, "wb");
            if (!ofile) {
                report_error(ERR_FATAL | ERR_NOFILE,
                             "unable to open output file `%s'", outname);
            }

            /*
             * We must call init_labels() before ofmt->init() since
             * some object formats will want to define labels in their
             * init routines. (eg OS/2 defines the FLAT group)
             */
            init_labels();

            ofmt->init(ofile, report_error, define_label, evaluate);

            assemble_file(inname, depend_ptr);

            if (!terminate_after_phase) {
                ofmt->cleanup(using_debug_info);
                cleanup_labels();
            } else {
                /*
                 * Despite earlier comments, we need this fclose.
                 * The object output drivers only fclose on cleanup,
                 * and we just skipped that.
                 */
                fclose (ofile);

                remove(outname);
                if (listname[0])
                    remove(listname);
            }
        }
        break;
    }

    if (depend_list)
	emit_dependencies(depend_list);

    if (want_usage)
        usage();

    raa_free(offsets);
    saa_free(forwrefs);
    eval_cleanup();
    stdscan_cleanup();

    if (terminate_after_phase)
        return 1;
    else
        return 0;
}

/*
 * Get a parameter for a command line option.
 * First arg must be in the form of e.g. -f...
 */
static char *get_param(char *p, char *q, bool *advance)
{
    *advance = false;
    if (p[2]) {                 /* the parameter's in the option */
        p += 2;
        while (nasm_isspace(*p))
            p++;
        return p;
    }
    if (q && q[0]) {
        *advance = true;
        return q;
    }
    report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
                 "option `-%c' requires an argument", p[1]);
    return NULL;
}

/*
 * Copy a filename
 */
static void copy_filename(char *dst, const char *src)
{
    size_t len = strlen(src);

    if (len >= (size_t)FILENAME_MAX) {
	report_error(ERR_FATAL | ERR_NOFILE, "file name too long");
	return;
    }
    strncpy(dst, src, FILENAME_MAX);
}

/*
 * Convert a string to Make-safe form
 */
static char *quote_for_make(const char *str)
{
    const char *p;
    char *os, *q;

    size_t n = 1;		/* Terminating zero */
    size_t nbs = 0;

    if (!str)
	return NULL;

    for (p = str; *p; p++) {
	switch (*p) {
	case ' ':
	case '\t':
	    /* Convert N backslashes + ws -> 2N+1 backslashes + ws */
	    n += nbs + 2;
	    nbs = 0;
	    break;
	case '$':
	case '#':
	    nbs = 0;
	    n += 2;
	    break;
	case '\\':
	    nbs++;
	    n++;
	    break;
	default:
	    nbs = 0;
	    n++;
	break;
	}
    }

    /* Convert N backslashes at the end of filename to 2N backslashes */
    if (nbs)
	n += nbs;

    os = q = nasm_malloc(n);

    nbs = 0;
    for (p = str; *p; p++) {
	switch (*p) {
	case ' ':
	case '\t':
	    while (nbs--)
		*q++ = '\\';
	    *q++ = '\\';
	    *q++ = *p;
	    break;
	case '$':
	    *q++ = *p;
	    *q++ = *p;
	    nbs = 0;
	    break;
	case '#':
	    *q++ = '\\';
	    *q++ = *p;
	    nbs = 0;
	    break;
	case '\\':
	    *q++ = *p;
	    nbs++;
	    break;
	default:
	    *q++ = *p;
	    nbs = 0;
	break;
	}
    }
    while (nbs--)
	*q++ = '\\';

    *q = '\0';

    return os;
}

struct textargs {
    const char *label;
    int value;
};

#define OPT_PREFIX 0
#define OPT_POSTFIX 1
struct textargs textopts[] = {
    {"prefix", OPT_PREFIX},
    {"postfix", OPT_POSTFIX},
    {NULL, 0}
};

static bool stopoptions = false;
static bool process_arg(char *p, char *q)
{
    char *param;
    int i;
    bool advance = false;
    bool do_warn;

    if (!p || !p[0])
        return false;

    if (p[0] == '-' && !stopoptions) {
	if (strchr("oOfpPdDiIlFXuUZwW", p[1])) {
	    /* These parameters take values */
	    if (!(param = get_param(p, q, &advance)))
		return advance;
	}

        switch (p[1]) {
        case 's':
            error_file = stdout;
            break;

	case 'o':		/* output file */
	    copy_filename(outname, param);
	    break;

	case 'f':		/* output format */
	    ofmt = ofmt_find(param);
	    if (!ofmt) {
		report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
			     "unrecognised output format `%s' - "
			     "use -hf for a list", param);
	    } else {
		ofmt->current_dfmt = ofmt->debug_formats[0];
	    }
	    break;

	case 'O':		/* Optimization level */
	{
	    int opt;

	    if (!*param) {
		/* Naked -O == -Ox */
		optimizing = INT_MAX >> 1; /* Almost unlimited */
	    } else {
		while (*param) {
		    switch (*param) {
		    case '0': case '1': case '2': case '3': case '4':
		    case '5': case '6': case '7': case '8': case '9':
			opt = strtoul(param, &param, 10);

			/* -O0 -> optimizing == -1, 0.98 behaviour */
			/* -O1 -> optimizing == 0, 0.98.09 behaviour */
			if (opt < 2)
			    optimizing = opt - 1;
			else
			    optimizing = opt;
			break;

		    case 'v':
		    case '+':
			param++;
			opt_verbose_info = true;
			break;

		    case 'x':
			param++;
			optimizing = INT_MAX >> 1; /* Almost unlimited */
			break;

		    default:
			report_error(ERR_FATAL,
				     "unknown optimization option -O%c\n",
				     *param);
			break;
		    }
		}
	    }
	    break;
	}

	case 'p':			/* pre-include */
	case 'P':
	    pp_pre_include(param);
	    break;

	case 'd':			/* pre-define */
	case 'D':
	    pp_pre_define(param);
	    break;

	case 'u':			/* un-define */
	case 'U':
	    pp_pre_undefine(param);
	    break;

	case 'i':			/* include search path */
	case 'I':
	    pp_include_path(param);
	    break;

	case 'l':			/* listing file */
	    copy_filename(listname, param);
	    break;

	case 'Z':			/* error messages file */
	    strcpy(errname, param);
	    break;

	case '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);
	    }
	    using_debug_info = true;
	    break;

	case '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 -v   for version info\n\n"
                 "    -t          assemble in SciTech TASM compatible mode\n"
                 "    -g          generate debug information in selected format.\n");
            printf
                ("    -E (or -e)  preprocess only (writes output to stdout by default)\n"
                 "    -a          don't preprocess (assemble only)\n"
                 "    -M          generate Makefile dependencies on stdout\n"
                 "    -MG         d:o, missing files assumed generated\n\n"
                 "    -Z<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 warning foo (equiv. -Wfoo)\n"
		 "    -w-foo      disable warning foo (equiv. -Wno-foo)\n"
                 "Warnings:\n");
            for (i = 0; i <= ERR_WARN_MAX; i++)
                printf("    %-23s %s (default %s)\n",
                       warnings[i].name, warnings[i].help,
                       warnings[i].enabled ? "on" : "off");
            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 'v':
            {
                const char *nasm_version_string =
                    "NASM version " NASM_VER " compiled on " __DATE__

⌨️ 快捷键说明

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