Пример #1
0
static ANODE* find_by_sval(
    ARRAY A ,
    STRING *sval ,
    int create_flag ,
    int *redo )
{
    unsigned hval = ahash(sval) ;
    char *str = sval->str ;
    DUAL_LINK *table ;
    unsigned indx ;
    ANODE *p ;  /* walks list */
    ANODE *q = (ANODE*) 0 ; /* trails p */
    if (! (A->type & AY_STR)) add_string_associations(A) ;
    table = (DUAL_LINK*) A->ptr ;
    indx = hval & A->hmask ;
    p = table[indx].slink ;
    *redo = 0 ;
    while(1) {
        if (!p)  {
            if (create_flag) {
                {
                    p = ZMALLOC(ANODE) ;
                    p->sval = sval ;
                    sval->ref_cnt++ ;
                    p->ival = NOT_AN_IVALUE ;
                    p->hval = hval ;
                    p->cell.type = C_NOINIT ;
                    if (++A->size > A->limit) {
                        double_the_hash_table(A) ; /* changes table, may change index */
                        table = (DUAL_LINK*) A->ptr ;
                        indx = hval & A->hmask ;
                        *redo = 1 ;
                    }
                }

                break ;
            }
            return (ANODE*) 0 ;
        }
        else if (p->hval == hval) {
            if (strcmp(p->sval->str,str) == 0 ) {
                /* found */
                if (!q) /* already at the front */
                    return p ;
                else { /* delete for move to the front */
                    q->slink = p->slink ;
                    break ;
                }
            }
        }
        q = p ;
        p = q->slink ;
    }
    p->slink = table[indx].slink ;
    table[indx].slink = p ;
    return p ;
}
Пример #2
0
ConfigSetting* ConfigFile::GetSetting(const char* Block, const char* Setting)
{
    uint32 block_hash = ahash(Block);
    uint32 setting_hash = ahash(Setting);

    /* find it in the big map */
    map<uint32, ConfigBlock>::iterator itr = m_settings.find(block_hash);
    if (itr != m_settings.end())
    {
        ConfigBlock::iterator it2 = itr->second.find(setting_hash);
        if (it2 != itr->second.end())
            return &(it2->second);

        return 0;
    }

    return 0;
}
Пример #3
0
static Dpage*
findpage(XDStore *s, u32int addr)
{
	uint h;
	Dpage *p;

	assert(addr%s->ds.pagesize == 0);
	h = ahash(addr, nelem(s->hash));
	assert(h < nelem(s->hash));
//print("look for %ud on %ud\n", addr, h);
	for(p=s->hash[h]; p; p=p->next){
		if(p->addr == addr){
			p->nref++;
			return p;
		}
	}
	return nil;
}
Пример #4
0
static Dpage*
mkpage(XDStore *s, u32int addr)
{
	uint h;
	Dpage *p;

	p = malloc(sizeof(Dpage)+s->ds.pagesize);
	if(p == nil)
		return nil;
	memset(p, 0, sizeof(Dpage));
	p->a = (uchar*)&p[1];
	p->nref = 1;
	p->addr = addr;
	p->s = s;
	h = ahash(addr, nelem(s->hash));
	p->next = s->hash[h];
	s->hash[h] = p;
//print("mk %ud linked to %d\n", addr, h);
	return p;
}
Пример #5
0
static void add_string_associations(ARRAY A)
{
    if (A->type == AY_NULL) make_empty_table(A, AY_STR) ;
    else {
        DUAL_LINK *table ;
        int i ; /* walks table */
        ANODE *p ; /* walks ilist */
        char buff[256] ;
        if (A->type == AY_SPLIT) convert_split_array_to_table(A) ;
        table = (DUAL_LINK*) A->ptr ;
        for(i=0; (unsigned) i <= A->hmask; i++) {
            p = table[i].ilink ;
            while(p) {
                sprintf(buff, INT_FMT, p->ival) ;
                p->sval = new_STRING(buff) ;
                p->hval = ahash(p->sval) ;
                p->slink = table[A->hmask&p->hval].slink ;
                table[A->hmask&p->hval].slink = p ;
                p = p->ilink ;
            }
        }
        A->type |= AY_STR ;
    }
}
Пример #6
0
bool ConfigFile::SetSource(const char* file, bool /*ignorecase*/)
{
    /* wipe any existing settings. */
    m_settings.clear();

    /* open the file */
    if (file != 0)
    {
        //the right mode in Windows is "rb" since '\n' is saved as 0x0D,0x0A but fopen(file,"r") reads these 2 chars
        //as only 1 char, so ftell(f) returns a higher value than the required by fread() to the file to buf.
#ifdef WIN32
        FILE* f = fopen(file, "rb");
#else
        FILE* f = fopen(file, "r");
#endif
        char* buf;
        int length;
        if (!f)
        {
            sLog.outError("Could not open %s.", file);
            return false;
        }

        /* get the length of the file */
        fseek(f, 0, SEEK_END);
        length = ftell(f);
        buf = new char[length + 1];
        fseek(f, 0, SEEK_SET);

        fread(buf, length, 1, f);
        buf[length] = '\0';
        string buffer = string(buf);
        delete[] buf;

        /* close the file, it is no longer needed */
        fclose(f);

        /* let's parse it. */
        string line;
        string::size_type end;
        string::size_type offset;
        bool in_multiline_comment = false;
        bool in_multiline_quote = false;
        bool in_block = false;
        string current_setting = "";
        string current_variable = "";
        string current_block = "";
        ConfigBlock current_block_map;
        ConfigSetting current_setting_struct;

        /* oh god this is awful */
        try
        {
            for (;;)
            {
                /* grab a line. */
                end = buffer.find(EOL);
                if (end == string::npos)
                {
                    if (buffer.size() == 0)
                        break;
                    line = buffer;
                    buffer.clear();
                    goto parse;
                }

                line = buffer.substr(0, end);
                buffer.erase(0, end + EOL_SIZE);
                goto parse;

            parse:
                if (!line.size())
                    continue;

                /* are we a comment? */
                if (!in_multiline_comment && is_comment(line, &in_multiline_comment))
                {
                    /* our line is a comment. */
                    if (!in_multiline_comment)
                    {
                        /* the entire line is a comment, skip it. */
                        continue;
                    }
                }

                /* handle our cases */
                if (in_multiline_comment)
                {
                    // we need to find a "*/".
                    offset = line.find("*/", 0);

                    /* skip this entire line, eh? */
                    if (offset == string::npos)
                        continue;

                    /* remove up to the end of the comment block. */
                    line.erase(0, offset + 2);
                    in_multiline_comment = false;
                }

                if (in_block)
                {
                    /* handle settings across multiple lines */
                    if (in_multiline_quote)
                    {
                        /* attempt to find the end of the quote block. */
                        offset = line.find("\"");

                        if (offset == string::npos)
                        {
                            /* append the whole line to the quote. */
                            current_setting += line;
                            current_setting += "\n";
                            continue;
                        }

                        /* only append part of the line to the setting. */
                        current_setting.append(line.c_str(), offset + 1);
                        line.erase(0, offset + 1);

                        /* append the setting to the config block. */
                        if (current_block == "" || current_variable == "")
                        {
                            sLog.outError("Quote without variable.");
                            return false;
                        }

                        /* apply the setting */
                        apply_setting(current_setting, current_setting_struct);

                        /* the setting is done, append it to the current block. */
                        current_block_map[ahash(current_variable)] = current_setting_struct;
#ifdef _CONFIG_DEBUG
                        sLog.outDebug("Block: '%s', Setting: '%s', Value: '%s'", current_block.c_str(), current_variable.c_str(), current_setting_struct.AsString.c_str());
#endif
                        /* no longer doing this setting, or in a quote. */
                        current_setting = "";
                        current_variable = "";
                        in_multiline_quote = false;
                    }

                    /* remove any leading spaces */
                    remove_spaces(line);

                    if (!line.size())
                        continue;

                    /* our target is a *setting*. look for an '=' sign, this is our seperator. */
                    offset = line.find("=");
                    if (offset != string::npos)
                    {
                        ASSERT(current_variable == "");
                        current_variable = line.substr(0, offset);

                        /* remove any spaces from the end of the setting */
                        remove_all_spaces(current_variable);

                        /* remove the directive *and* the = from the line */
                        line.erase(0, offset + 1);
                    }

                    /* look for the opening quote. this signifies the start of a setting. */
                    offset = line.find("\"");
                    if (offset != string::npos)
                    {
                        ASSERT(current_setting == "");
                        ASSERT(current_variable != "");

                        /* try and find the ending quote */
                        end = line.find("\"", offset + 1);
                        if (end != string::npos)
                        {
                            /* the closing quote is on the same line, oh goody. */
                            current_setting = line.substr(offset + 1, end - offset - 1);

                            /* erase up to the end */
                            line.erase(0, end + 1);

                            /* apply the setting */
                            apply_setting(current_setting, current_setting_struct);

                            /* the setting is done, append it to the current block. */
                            current_block_map[ahash(current_variable)] = current_setting_struct;

#ifdef _CONFIG_DEBUG
                            sLog.outDebug("Block: '%s', Setting: '%s', Value: '%s'", current_block.c_str(), current_variable.c_str(), current_setting_struct.AsString.c_str());
#endif
                            /* no longer doing this setting, or in a quote. */
                            current_setting = "";
                            current_variable = "";
                            in_multiline_quote = false;

                            /* attempt to grab more settings from the same line. */
                            goto parse;
                        }
                        else
                        {
                            /* the closing quote is not on the same line. means we'll try and find it on
                               the next. */
                            current_setting.append(line.c_str(), offset);

                            /* skip to the next line. (after setting our condition first, of course :P */
                            in_multiline_quote = true;
                            continue;
                        }
                    }

                    /* are we at the end of the block yet? */
                    offset = line.find(">");
                    if (offset != string::npos)
                    {
                        line.erase(0, offset + 1);

                        // freeeee!
                        in_block = false;

                        /* assign this block to the main "big" map. */
                        m_settings[ahash(current_block)] = current_block_map;

                        /* erase all data for this so it doesn't seep through */
                        current_block_map.clear();
                        current_setting = "";
                        current_variable = "";
                        current_block = "";
                    }
                }
                else
                {
                    /* we're not in a block. look for the start of one. */
                    offset = line.find("<");

                    if (offset != string::npos)
                    {
                        in_block = true;

                        /* whee, a block! let's cut the string and re-parse. */
                        line.erase(0, offset + 1);

                        /* find the name of the block first, though. */
                        offset = line.find(" ");
                        if (offset != string::npos)
                        {
                            current_block = line.substr(0, offset);
                            line.erase(0, offset + 1);
                        }
                        else
                        {
                            sLog.outError("Block without name.");
                            return false;
                        }

                        /* skip back */
                        goto parse;
                    }
                }
            }
        }
        catch (...)
        {
            sLog.outError("Exception in config parsing.");
            return false;
        }

        /* handle any errors */
        if (in_block)
        {
            sLog.outError("Unterminated block.");
            return false;
        }

        if (in_multiline_comment)
        {
            sLog.outError("Unterminated comment.");
            return false;
        }

        if (in_multiline_quote)
        {
            sLog.outError("Unterminated quote.");
            return false;
        }

        /* we're all good :) */
        return true;
    }

    return false;
}
Пример #7
0
uint32 ahash(string & str)
{
    return ahash(str.c_str());
}