📄 sflsymb.c
字号:
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 + -