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

📄 sflsymb.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  ----------------------------------------------------------------<Prolog>-
    Name:       sflsymb.c
    Title:      Symbol-table functions
    Package:    Standard Function Library (SFL)

    Written:    1993/12/27  iMatix SFL project team <sfl@imatix.com>
    Revised:    2000/01/19

    Copyright:  Copyright (c) 1996-2000 iMatix Corporation
    License:    This is free software; you can redistribute it and/or modify
                it under the terms of the SFL License Agreement as provided
                in the file LICENSE.TXT.  This software is distributed in
                the hope that it will be useful, but without any warranty.
 ------------------------------------------------------------------</Prolog>-*/

#include "prelude.h"                    /*  Universal header file            */
#include "sflstr.h"                     /*  String functions                 */
#include "sflconv.h"                    /*  Conversion functions             */
#include "sfllist.h"                    /*  Linked-list functions            */
#include "sflmem.h"                     /*  Memory allocation functions      */
#include "sflprint.h"                   /*  snprintf functions               */
#include "sflsymb.h"                    /*  Prototypes for functions         */


static int sym_sort_by_name (const void *sym1, const void *sym2);


/*  ---------------------------------------------------------------------[<]-
    Function: sym_create_table_

    Synopsis: Creates a new symbol table.  Use the sym_create_table macro
    to call this function!  Returns a SYMTAB pointer which you must use in
    all future references to the symbol table.  The symbol table is
    maintained in memory until the program ends or you use sym_delete_table()
    to delete it.  Returns null if there was not enough memory to create the
    symbol table.
    ---------------------------------------------------------------------[>]-*/

SYMTAB *
sym_create_table_ (
    const char *filename,               /*  Name of source file making call  */
    size_t      lineno)                 /*  Line number in calling source    */
{
    SYMTAB
        *table;                         /*  Pointer to created table         */
    int
        hash_index;                     /*  Index into hash bucket           */

    /*  Allocate by going directly to mem_alloc_ function                    */
    table = mem_alloc_ (NULL, sizeof (SYMTAB), filename, lineno);
    if (table)
      {
        table-> symbols = NULL;         /*  No symbols attached yet          */
        table-> size    = 0;
        for (hash_index = 0; hash_index < SYM_HASH_SIZE; hash_index++)
            table-> hash [hash_index] = NULL;
      }
    return (table);
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_delete_table

    Synopsis: Deletes the given symbol table.  First frees any memory space
    used by the table and attached symbols, including the user data block
    if that is not null.  If the table argument is NULL, does nothing.
    ---------------------------------------------------------------------[>]-*/

void
sym_delete_table (
    SYMTAB *table)                      /*  Symbol table to delete           */
{
    SYMBOL
        *symbol,                        /*  Pointer to symbol                */
        *next = NULL;                   /*    and to next symbol in list     */

    if (!table)
        return;                         /*  Do nothing if argument is null   */

    for (symbol = table-> symbols; symbol; symbol = next)
      {
        next = symbol-> next;           /*  Keep track of next in list       */
        mem_free (symbol-> value);      /*  Free value if used               */
        mem_free (symbol);              /*  Finally free symbol and name     */
      }
    mem_free (table);                   /*  Now free the table               */
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_empty_table

    Synopsis: Empties the given symbol table, by deleting all symbols.  You
    can then add new symbols.  If the table argument is NULL, does nothing.
    ---------------------------------------------------------------------[>]-*/

void
sym_empty_table (
    SYMTAB *table)                      /*  Symbol table to empty            */
{
    SYMBOL
        *symbol,                        /*  Pointer to symbol                */
        *next = NULL;                   /*    and to next symbol in list     */
    int
        hash_index;                     /*  Index into hash bucket           */

    if (!table)
        return;                         /*  Do nothing if argument is null   */

    for (symbol = table-> symbols; symbol; symbol = next)
      {
        next = symbol-> next;           /*  Keep track of next in list       */
        mem_free (symbol-> value);      /*  Free value if used               */
        mem_free (symbol);              /*  Finally free symbol and name     */
      }
    table-> symbols = NULL;             /*  No symbols attached yet          */
    table-> size    = 0;
    for (hash_index = 0; hash_index < SYM_HASH_SIZE; hash_index++)
        table-> hash [hash_index] = NULL;
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_merge_tables

    Synopsis: Imports the contents of one symbol table into another.  Will
    overwrite symbols with the same name.  Returns the number of symbols
    imported.  If there is a lack of available memory, will stop importing,
    and return negative the number of symbols imported so far.  
    ---------------------------------------------------------------------[>]-*/

int
sym_merge_tables (
    SYMTAB *table,                      /*  Symbol table to import into      */
    const SYMTAB *import)               /*  Symbol table to import from      */
{
    SYMBOL
        *symbol;                        /*  Next symbol in table             */
    int
        count = 0;

    ASSERT (table);
    ASSERT (import);

    for (symbol = import-> symbols; symbol; symbol = symbol-> next)
      {
        if (sym_assume_symbol (table, symbol-> name, symbol-> value) == NULL)
        {
          return (-(count));            /*  Failed => negative value returned*/
        }

        count++;
      }
      
    return (count);                     /*  Success => postive value returned*/
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_lookup_symbol

    Synopsis: Searches for a symbol, by name, in the specified symbol table.
    Returns a pointer to the symbol if found, or NULL if not found.  If more
    than one symbol with the same name exists, finds the latest entry.
    ---------------------------------------------------------------------[>]-*/

SYMBOL *
sym_lookup_symbol (
    const SYMTAB *table,                /*  Symbol table to search           */
    const char   *name)                 /*  Symbol name to search for        */
{
    SYMBOL
        *symbol;                        /*  Search through hash bucket list  */

    ASSERT (table);

    for (symbol = table-> hash [sym_hash (name)];
         symbol;
         symbol = symbol-> h_next)
      {
        if (streq (symbol-> name, name))
            return (symbol);
      }
    return (NULL);
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_create_symbol_

    Synopsis: Creates a new symbol in the specified table.  Use the
    sym_create_symbol macro to call this function!  Returns a SYMBOL
    pointer to the created symbol, or NULL if there was not enough memory to
    create the symbol.  Initialises the symbol name and value to the values
    supplied.  Sets symbol data to NULL.  You can set this yourself if you
    need to, after calling this function.  Use mem_alloc() or mem_strdup()
    to assign values to the data block, otherwise you may cause problems when
    you delete the symbol or symbol table, since these functions free these
    fields.  You can create several symbols with the same name; the
    last-defined is always placed before older instances and will be found
    first by sym_lookup_symbol().

    Examples:
    SYMTAB
        *symbol_table;
    SYMBOL
        *new_symbol;

    symbol_table = sym_create_table ();
    ASSERT (symbol_table);
    new_symbol = sym_create_symbol (symbol_table, "This name", "This value");
    if (new_symbol)
      {
        new_symbol-> data = mem_alloc (sizeof (my_block));
        memcpy (new_symbol-> data, my_block);
      }
    ---------------------------------------------------------------------[>]-*/

SYMBOL *
sym_create_symbol_ (
    SYMTAB *table,                      /*  Symbol table to insert into      */
    const char *name,                   /*  Name of symbol to create         */
    const char *value,                  /*  Value of symbol to create        */
    const char *filename,               /*  Name of source file making call  */
    size_t      lineno)                 /*  Line number in calling source    */
{
    SYMBOL
        *symbol;                        /*  Allocated symbol                 */
    int
        hash;                           /*  Hash bucket no. for symbol       */

    ASSERT (table);

    symbol = mem_alloc_ (NULL, sizeof (*symbol) + strlen (name) + 1,
                         filename, lineno);
    if (symbol)
      {
        /*  Set the symbol pointers and fields                               */
        hash = sym_hash (name);
        symbol-> next   = table-> symbols;
        symbol-> prev   = NULL;
        symbol-> h_next = table-> hash [hash];
        symbol-> h_prev = NULL;
        symbol-> name   = (char *) symbol + sizeof (*symbol);
        symbol-> value  = mem_strdup (value);
        symbol-> data   = NULL;
        symbol-> hash   = (byte) hash;
        strcpy (symbol-> name, name);

        if (table-> symbols)
            table-> symbols-> prev = symbol;
        table-> symbols = symbol;

        if (table-> hash [hash])
            table-> hash [hash]-> h_prev = symbol;
        table-> hash [hash] = symbol;
        table-> size++;
      }
    return (symbol);
}


/*  ---------------------------------------------------------------------[<]-
    Function: sym_assume_symbol_

    Synopsis: Searches for a symbol, by name, in the specified symbol table.
    If the symbol does not exist, creates the symbol as specified.  Returns
    a SYMBOL pointer to the existing or new symbol, or NULL if a new symbol
    could not be created.  The lookup and creation follow the same rules as
    sym_lookup_symbol() and sym_create_symbol().  The symbol's value is set
    to the supplied value in all cases.
    Do not call this function directly; pass through the sym_assume_symbol
    macro.
    ---------------------------------------------------------------------[>]-*/

SYMBOL *
sym_assume_symbol_ (

⌨️ 快捷键说明

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