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

📄 fileset.cc

📁 c到DHL的转换工具
💻 CC
📖 第 1 页 / 共 2 页
字号:
/*  File Set Implementation *//*  Copyright (c) 1994,95 Stanford University    All rights reserved.    This software is provided under the terms described in    the "suif_copyright.h" include file. */#include <suif_copyright.h>#define _MODULE_ "libsuif.a"#pragma implementation "fileset.h"#define RCS_BASE_FILE fileset_cc#include <machine_dependent.h>#include "suif1.h"#include "suif_internal.h"#include <stdio.h>#include <fcntl.h>RCS_BASE(    "$Id: fileset.cc,v 1.2 1999/08/25 03:29:10 brm Exp $")static void set_default_target();file_set *fileset = NULL;boolean disable_global_symtab_check = FALSE;base_symtab *write_scope = NULL;/* We make explicit copy constructor and assignment operator and * make them private to foil C++'s automatic default versions. */file_set::file_set(const file_set &)  { assert(FALSE); }file_set &file_set::operator=(const file_set &)  { assert(FALSE); return *this; }/* *  File_set constructor.  This is called when the fileset is created in *  the init_suif routine. */file_set::file_set (){    assert_msg(!fileset,	       ("file_set::file_set - only one file_set is allowed"));    files = new file_set_entry_list;    iter = new file_set_entry_list_iter(files);    globs = new global_symtab("global");    set_default_target();    globs->predefine_types();    read_a_file = FALSE;    /* keep track of number of open files */    open_max = SUIF_FOPEN_MAX;    /* check for non-SUIF files that are already open */    for (int f = 0; f < SUIF_FOPEN_MAX; f++) {        if (fcntl(f, F_GETFD) != -1) {            open_max -= 1;        }    }    if (open_max < 6)      {        /* In this case, we were unable to get the OS to guarantee a         * reasonable number of files we can have open.  Usually, this         * is because the OS is being too conservative in what it         * tells us through the channels above.  For example, under         * Solaris on a SPARC, FOPEN_MAX is 20, even though there are         * really 64 positions available, at least under some         * circumstances.  Running a program under gdb within emacs         * and then re-running the program ends up eating up 20 open         * files in all (but no more).  This leaves us with zero         * additional files that the OS guarantees us, even though         * there are 44 that can really be open (as experiments         * verified).         *         * To address this problem, if the OS won't guarantee us         * sufficient files, we just try ourselves to see if we can         * keep a few "dev/null" handles open.         */        FILE *fps[6];        int null_count;        for (null_count = 0; null_count < 6; ++null_count)          {            fps[null_count] = fopen("/dev/null", "r");            if (fps[null_count] == NULL)                break;          }        for (int null_num = 0; null_num < null_count; ++null_num)            fclose(fps[null_num]);        if (null_count > open_max)            open_max = null_count;      }    assert_msg(open_max > 0,	       ("file_set::file_set - cannot open any files"));    open_cnt = 0;}/* *  File_set destructor.  This destroys the file_set_entries, which causes *  them to write out the global symtabs and close the associated i/o streams. */file_set::~file_set (){    /* make sure that the global symtab contains no variable definitions */    assert_msg(globs->var_defs()->is_empty(),	       ("file_set destructor - "		"variables defined in the global symtab"));    /* write out and delete each of the files */    while (!file_list()->is_empty()) {	delete file_list()->pop();    }    delete files;    delete iter;    delete globs;}/* *  Add a file to the set. */file_set_entry *file_set::add_file (char *in, char *out){    file_set_entry *fse = new file_set_entry(this, in, out);    file_list()->append(fse);    return fse;}file_set_entry *file_set::find_by_num (int file_id){    file_set_entry_list_iter fse_iter(files);    while (!fse_iter.is_empty())      {        file_set_entry *this_fse = fse_iter.step();        if (this_fse->file_id() == file_id)            return this_fse;      }    return NULL;}/* *  Set the maximum number of files the file set is allowed to keep *  open at one time.  By default this is set to the OS limit, but if *  a user opens other files outside of those controlled by this file *  set, the user must give the file set a lower limit. * *  The user can set this temporarily to zero to force all files used *  by the file set to be closed, but it must be set back to a higher *  limit before any operations that might need to use an open file *  are performed. */voidfile_set::set_max_open_files(long new_max){    assert_msg(new_max >= 0,	       ("file_set::set_max_open_files - maximum must be "		"non-negative"));    while (open_cnt > new_max)	close_other_file(NULL);    open_max = new_max;}/* *  Open a stream on behalf of a file_set_entry.  If too many files are open, *  search through the file list for an open stream to close.  Besides not *  closing a stream associated with the current file_set_entry, the function *  doesn't do anything fancy--it just closes the first open stream that it *  finds. */voidfile_set::open_stream (base_stream *s, file_set_entry *fse){    /* do nothing if the stream is already open */    if (s->is_open()) return;    assert_msg(open_max > 0,	       ("file_set::open_stream - max open files is zero"));    /* check if there are too many open files */    if (open_cnt == open_max)	close_other_file(fse);    s->open();    open_cnt += 1;}/* *  Close a stream on behalf of a file_set_entry.  The file_set does *  all opening and closing of streams so that it can keep an accurate *  count of the number of open streams at an given time. */voidfile_set::close_stream (base_stream *s){    if (s->is_open()) {	s->close();	assert(open_cnt > 0);	open_cnt -= 1;    }}/* *  Close any one stream that is not associated with fse; if fse is *  NULL, or if the maximum number of open streams allowed is one, *  close any stream at all.  This is called internally to reduce the *  number of currently open files. */voidfile_set::close_other_file(file_set_entry *fse){    /* find a stream to close */    file_set_entry_list_iter file_iter(file_list());    while (!file_iter.is_empty()) {	file_set_entry *other_fse = file_iter.step();	/* don't mess with the current fse */	if ((other_fse == fse) && (open_max > 1)) continue;	/* try to close the input stream */	in_stream *is = other_fse->is;	if (is && is->is_open()) {	    is->close();	    open_cnt -= 1;	    return;	}	/* try to close the output stream */	out_stream *os = other_fse->os;	if (os && os->is_open()) {	    os->close();	    open_cnt -= 1;	    return;	}    }    assert(FALSE);}/* *  Set the default target parameters.  These should usually be overridden *  by the annotations on the file_set_entries. */voidset_default_target (){    target.is_big_endian = FALSE;    target.addressable_size = 8;    target.char_is_signed = TRUE;    target.size[C_char] = 8;    target.size[C_short] = 16;    target.size[C_int] = 32;    target.size[C_long] = 32;    target.size[C_longlong] = 64;    target.size[C_float] = 32;    target.size[C_double] = 64;    target.size[C_longdouble] = 128;    target.size[C_ptr] = 32;    target.align[C_char] = 8;    target.align[C_short] = 16;    target.align[C_int] = 32;    target.align[C_long] = 32;    target.align[C_longlong] = 64;    target.align[C_float] = 32;    target.align[C_double] = 64;    target.align[C_longdouble] = 128;    target.align[C_ptr] = 32;    target.array_align = 32;    target.struct_align = 32;    target.ptr_diff_type = C_int;}/*****************************************************************************//* *  File_set_entry constructor.  If there is an input file, open it and *  read the global symbol tables.  If there is an output file, write the *  low-level file header. */file_set_entry::file_set_entry (file_set *p, char *inn, char *outn){    /* record the parent file_set */    par = p;    /* create the i/o streams */    is = inn ? new in_stream(lexicon->enter(inn)->sp) : NULL;    os = NULL;    table = new file_symtab(inn ? inn : (outn ? outn : (char *)"file"), this);    par->globals()->add_child(table);    if (is) {	par->open_stream(is, this);	/* read in the global and file symtabs */	fill_table();	/* read the annotations for the file_set_entry */	instruction *mrk = instruction::read(is, symtab(), NULL);	mrk_to_annotes(mrk);	delete mrk;	/* read extra info from annotations on the file_set_entry */	get_contents();    }    if (outn != NULL)	add_outfile(outn);    {	immed_list *file_num_immeds = (immed_list *)(get_annote(k_file_num));	if (file_num_immeds == NULL) {	    the_id = 0;	} else {	    assert(file_num_immeds->count() == 1);	    assert(file_num_immeds->head()->contents.is_integer());	    the_id = file_num_immeds->head()->contents.integer();	    delete file_num_immeds;	}    }    /* record the current pass name on a "history" annotation */    annote *an = new annote(k_history);    an->immeds()->append(immed(_suif_command_line));    annotes()->append(an);    an = new annote(k_version_history);    an->immeds()->append(immed(_suif_prog_base_name));    an->immeds()->append(immed(prog_ver_string));    an->immeds()->append(immed("suif distribution"));    an->immeds()->append(immed(libsuif1_suif_string));    library_list_iter library_iter(suif_libraries);    while (!library_iter.is_empty())      {        suif_library *this_library = library_iter.step();        an->immeds()->append(immed(this_library->name));        an->immeds()->append(immed(this_library->version));      }    annotes()->append(an);    global_proc_iter = new sym_node_list_iter;    static_proc_iter = new sym_node_list_iter;    reset_proc_iter();}/* *  Read the global and file symbol tables.  Reading the global symtab is *  a little tricky.  If this is the first input file, the new symtab replaces *  the existing (empty) global symtab.  Otherwise, if the global symtab has *  already been read from another file, we just check to make sure that the *  new table is the same.  If disable_global_symtab_check has been *  set to TRUE, the user is asserting that the check will be *  successful and can be omitted to save time.  If it turns out the *  tables are not the same and the check is disabled, other things *  will probably fail in strange ways. */voidfile_set_entry::fill_table (){    /* read the symtab position from the beginning of the file */    instruction *mrk = instruction::read(is, parent()->globals(), NULL);    annote *an = mrk->annotes()->get_annote(k_file_symtab_ptr);    if ((mrk->opcode() != io_mrk) || !an || (an->immeds()->count() != 1)) {	error_line(1, NULL, "File '%s' does not contain a symtab pointer",		   is->name());    }    immed position_immed = an->immeds()->pop();    if (!position_immed.is_int_const()) {

⌨️ 快捷键说明

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