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

📄 sflsymb.c

📁 短小精悍的C语言标准函数库。提供450个以上的可移植的算法和工具代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
    const char *value)                  /*  New value to assign              */
{
    ASSERT (symbol);

    mem_strfree (&symbol-> value);      /*  Free existing value if any       */
    symbol-> value = mem_strdup (value);
}


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

    Synopsis: Sorts a symbol table using the qsort library function.  To
    access the symbol table, use the next and prev symbol pointers.  If
    the sort_function is NULL, sorts on the symbol name.

    Examples:
    int compare (const void *sym1, const void *sym2)
    {
        return (strcmp (*(SYMBOL **) sym1)-> value,
                        *(SYMBOL **) sym2)-> value));
    }
    SYMTAB
        *table;
    SYMBOL
        *symbol;

    table = sym_create_table ();
    sym_create_symbol (table, "Symbol 1", "A");
    sym_create_symbol (table, "Symbol 2", "D");
    sym_create_symbol (table, "Symbol 4", "B");
    sym_create_symbol (table, "Symbol 3", "C");
    sym_sort_table (table, compare);
    for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
        printf ("Symbol %s = %s\n", symbol-> name, symbol-> value);
    sym_delete_table (table);
    ---------------------------------------------------------------------[>]-*/

void
sym_sort_table (SYMTAB *table, symsort sort_function)
{
    SYMBOL
        *symbol,
        **array;
    int
        index;

    ASSERT (table);

    if (table-> size == 0)
        return;

    array = mem_alloc (table-> size * sizeof (SYMBOL *));
    if (array == NULL)
        return;                         /*  Not enough memory                */

    /*  Build sorting array                                                  */
    for (symbol = table-> symbols, index = 0;
         symbol && index < table-> size;
         symbol = symbol-> next, index++)
        array [index] = symbol;

    if (sort_function == NULL)
        sort_function = sym_sort_by_name;

    qsort ((void *) array, table-> size, sizeof (SYMBOL *), sort_function);

    /*  Re-order symbol table links                                          */
    table-> symbols = array [0];
    for (index = 0; index < table-> size; index++)
      {
        symbol = array [index];
        symbol-> prev = (index > 0)? array [index -1]: NULL;
        symbol-> next = (index < table-> size - 1)? array [index + 1]: NULL;
      }
    mem_free (array);
}


static int
sym_sort_by_name (const void *sym1, const void *sym2)
{
    int
        compare;
    char
        *name1,
        *name2;

    /*  In our sort order, ':' comes before everything else, so that symbols
     *  sort correctly like this:
     *  name
     *  name:one
     *  name:two
     *  name1
     *  name1:one ... etc
     */
    name1 = (*(SYMBOL **) sym1)-> name;
    name2 = (*(SYMBOL **) sym2)-> name;
    
    strconvch (name1, ':', '\001');
    strconvch (name2, ':', '\001');
    compare = strcmp (name1, name2);
    strconvch (name1, '\001', ':');
    strconvch (name2, '\001', ':');
    return (compare);
}


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

    Synopsis: Exports the symbol table as an array of strings of the format
    "name=value".  Returns a pointer to the array.  The array is allocated
    dynamically.  The array ends with a NULL string.  To free the table,
    call strtfree().  If there was not enough memory to allocate the table,
    returns NULL.  See also symb2env().
    Do not call this function directly: pass through the symb2strt macro.
    ---------------------------------------------------------------------[>]-*/

char **
symb2strt_ (
    const SYMTAB *symtab,               /*  Symbol table to export           */
    const char   *filename,             /*  Name of source file making call  */
    size_t        lineno)               /*  Line number in calling source    */
{
    SYMBOL
        *symbol;                        /*  Pointer to symbol                */
    char
        **strings,                      /*  Returned string array            */
        *name_and_value;                /*  Name=value string                */
    int
        string_nbr;                     /*  Index into symbol_array          */

    if (!symtab)
        return (NULL);                  /*  Return NULL if argument is null  */

    /*  Allocate the array of pointers with one slot for the final NULL      */
    strings = mem_alloc_ (NULL, sizeof (char *) * (symtab-> size + 1),
                          filename, lineno);
    if (strings)
      {
        string_nbr = 0;
        for (symbol = symtab-> symbols; symbol; symbol = symbol-> next)
          {
            /*  Allocate space for "name=value" plus final null char         */
	    int n_and_v_len = 0;
	    n_and_v_len = strlen (symbol-> name) + strlen (symbol-> value) + 2;

            name_and_value = mem_alloc_ (NULL, n_and_v_len, filename, lineno);
            if (name_and_value)         /*  Fail-safe if no memory left      */
                snprintf (name_and_value, n_and_v_len, "%s=%s", 
			                  symbol-> name, symbol-> value);
            strings [string_nbr++] = name_and_value;
          }
        strings [string_nbr] = NULL;    /*  Store final null pointer         */
      }
    return (strings);
}


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

    Synopsis: Converts a table of strings into a symbol table.  The input
    table consists of an array of null-terminated strings, terminated in a
    null pointer.  Ignores any strings that don't look like: "name=value".
    If the table contains multiple strings with the same name, the last
    instance is stored in the symbol table.  Note that if you omit the last
    null pointer in the input table, you will probably get an addressing
    error.  Returns NULL if there was insufficient memory to allocate the
    symbol table, or if the input argument was null.
    Do not call this function directly: pass through the strt2symb macro.
    ---------------------------------------------------------------------[>]-*/

SYMTAB *
strt2symb_ (
    char      **table,                  /*  String table to convert          */
    const char *filename,               /*  Name of source file making call  */
    size_t      lineno)                 /*  Line number in calling source    */
{
    SYMTAB
        *symtab;                        /*  Allocated symbol table           */
    char
        *equals;                        /*  Position of '=' in string        */
    int
        string_nbr;                     /*  Index into string table          */

    if (!table)
        return (NULL);                  /*  Return NULL if argument is null  */

    symtab = sym_create_table_ (filename, lineno);
    if (symtab)
      {
        for (string_nbr = 0; table [string_nbr]; string_nbr++)
          {
            equals = strchr (table [string_nbr], '=');
            if (equals)
              {
                *equals = '\0';         /*  Cut into two strings             */
                sym_assume_symbol (symtab, table [string_nbr], equals + 1);
                *equals = '=';          /*  Restore previous state           */
              }
          }
      }
    return (symtab);
}


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

    Synopsis: Exports the symbol table as a table of strings in a DESCR
    block.  Each string has the format "name=value".  The block ends with
    a null string.  Returns a pointer to the descriptor.  The descriptor is
    allocated dynamically; to free it, use mem_free().  If there was not
    enough memory to allocate the descriptor, returns NULL.
    Do not call this function directly: pass through the symb2descr macro.
    ---------------------------------------------------------------------[>]-*/

DESCR *
symb2descr_ (
    const SYMTAB *symtab,               /*  Symbol table to export           */
    const char   *filename,             /*  Name of source file making call  */
    size_t        lineno)               /*  Line number in calling source    */
{
    char
        **strings;                      /*  Formatted string array           */
    DESCR
        *descr;                         /*  Formatted descriptor             */

    if (!symtab)
        return (NULL);                  /*  Return NULL if argument is null  */

    /*  Convert symbol table to strings                                      */
    strings = symb2strt_ (symtab, filename, lineno);
    descr   = strt2descr (strings);     /*  And build into descriptor        */
    strtfree (strings);
    return (descr);
}


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

    Synopsis: Converts a DESCR block into a symbol table.  The descriptor
    consists of a block of null-terminated strings, terminated in a double
    null byte.  Ignores any strings that don't look like: "name=value".
    If the block contains multiple strings with the same name, the last
    instance is stored in the symbol table.  Returns NULL if there was not
    enough memory to allocate the symbol table, or if the input argument was
    null.
    Do not call this function directly: pass through the descr2symb macro.
    ---------------------------------------------------------------------[>]-*/

SYMTAB *
descr2symb_ (
    const DESCR  *descr,                /*  Descriptor to convert            */
    const char   *filename,             /*  Name of source file making call  */
    size_t        lineno)               /*  Line number in calling source    */
{
    SYMTAB
        *symtab;                        /*  Allocated symbol table           */
    char
        **strings;                      /*  Formatted string array           */

    if (!descr)
        return (NULL);                  /*  Return NULL if argument is null  */

    if (!descr-> data)              
        return (sym_create_table ());   /*  Create new symtab if no data     */
        
    strings = descr2strt (descr);       /*  Convert descriptor to strings    */
    symtab  = strt2symb_ (strings, filename, lineno);
    strtfree (strings);
    return (symtab);
}

⌨️ 快捷键说明

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