📄 sfltok.c
字号:
if (token_list)
{
token_list--; /* Back-up to get right address */
mem_free (token_list [0]); /* Free buffer */
mem_free (token_list); /* and free token list */
}
}
/* ---------------------------------------------------------------------[<]-
Function: tok_push
Synopsis: Prepends a string to the specified token table. Reallocates
the table as required to make room for the new string. Returns the new
token table -- the supplied token table is automatically freed by a call
to tok_free().
---------------------------------------------------------------------[>]-*/
char **
tok_push (
char **token_list,
const char *string)
{
char
*new_buffer, /* Newly-allocated buffer */
**new_list, /* Returned token list */
*new_bufptr; /* Pointer into new buffer */
int
word_count, /* Number of words in string */
word_nbr;
size_t
buffer_size,
string_size,
new_buffer_size;
buffer_size = tok_text_size (token_list);
word_count = tok_size (token_list);
string_size = strlen (string);
new_buffer_size = buffer_size + string_size + 1;
/* New list has one entry for each in old list, plus header, plus null
* entry at end, plus one for the new string -- makes 3 more.
*/
new_list = mem_alloc (sizeof (char *) * (word_count + 3));
new_buffer = mem_alloc (new_buffer_size);
if (new_list == NULL || new_buffer == NULL)
{
mem_free (new_list);
mem_free (new_buffer);
return (NULL);
}
word_count++; /* We add one word */
strncpy (new_buffer, string, new_buffer_size);
memcpy (new_buffer + string_size + 1, token_list [-1], buffer_size);
new_list [0] = new_buffer; /* Store buffer address */
new_list++; /* and bump starting address */
new_bufptr = new_buffer;
for (word_nbr = 0; word_nbr < word_count; word_nbr++)
{
new_list [word_nbr] = new_bufptr;
new_bufptr += strlen (new_bufptr) + 1;
}
new_list [word_count] = NULL; /* Store final null pointer */
tok_free (token_list); /* Free old list */
return (new_list);
}
/* ---------------------------------------------------------------------[<]-
Function: tok_size
Synopsis: Returns size of specified token list, in entries. Stops at
the empty terminating token. Thus the table "This", "Is", "A", "String"
will return a size of 4.
---------------------------------------------------------------------[>]-*/
int
tok_size (
char **token_list)
{
int
word_nbr;
for (word_nbr = 0; token_list [word_nbr]; word_nbr++);
return (word_nbr);
}
/* ---------------------------------------------------------------------[<]-
Function: tok_text_size
Synopsis: Returns size of specified token list, in characters. Counts
the size of each token, plus one terminator for each token. Thus the
table "This", "Is", "A", "String" will return a size of 17.
---------------------------------------------------------------------[>]-*/
size_t
tok_text_size (
char **token_list)
{
size_t
text_size;
int
word_nbr;
text_size = 0;
for (word_nbr = 0; token_list [word_nbr]; word_nbr++)
text_size += strlen (token_list [word_nbr]) + 1;
return (text_size);
}
/* ---------------------------------------------------------------------[<]-
Function: tok_subst
Synopsis: Performs symbol substitution into the specified string.
Returns a newly-allocated string containing the result, or NULL if there
was not enough memory. The symbol table holds the set of symbols that
may be inserted. Undefined symbols are inserted as an empty value.
Symbols are specified in the string using this syntax: $(name), where
'name' is case-sensitive. This version does not allow embedded symbols.
---------------------------------------------------------------------[>]-*/
char *
tok_subst (const char *string, SYMTAB *symbols)
{
char
*sym_start,
*sym_end,
*sym_name, /* Symbol name to look for */
*copied_to, /* Up to where we copied so far */
*cur_result, /* Current result buffer */
*new_result; /* After adding next symbol */
int
sym_length; /* Length of symbol name */
SYMBOL
*symbol; /* Symbol in symbol table */
ASSERT (string);
ASSERT (symbols);
/* Parse from left to right, looking for $(...) patterns */
cur_result = mem_strdup (""); /* Result buffer is empty */
sym_start = strchr (string, '$');
copied_to = (char *) string;
while (sym_start)
{
sym_end = strchr (++sym_start, ')');
if (*sym_start == '('
&& sym_end
&& *sym_end == ')')
{
/* First, copy string up to sym_start */
size_t cur_len = strlen (cur_result);
ASSERT ((sym_start - copied_to) >= 0);
new_result = mem_alloc (cur_len + (sym_start - copied_to));
if (new_result == NULL)
{
mem_free (cur_result);
return (NULL);
}
strncpy (new_result, cur_result, (cur_len + 1));
strncat (new_result, copied_to, sym_start - 1 - copied_to);
mem_free (cur_result);
cur_result = new_result;
copied_to = sym_end + 1;
/* Now translate and insert symbol */
sym_length = sym_end - sym_start - 1;
sym_name = mem_alloc (sym_length + 1);
if (sym_name == NULL)
{
mem_free (cur_result);
return (NULL);
}
memcpy (sym_name, sym_start + 1, sym_length);
sym_name [sym_length] = 0;
symbol = sym_lookup_symbol (symbols, sym_name);
mem_free (sym_name);
if (symbol)
{
xstrcpy_debug ();
new_result = xstrcpy (NULL, cur_result, symbol-> value, NULL);
mem_free (cur_result);
cur_result = new_result;
}
}
else
sym_end = sym_start + 1;
sym_start = strchr (sym_end, '$');
}
/* Copy anything remaining in the string */
xstrcpy_debug ();
new_result = xstrcpy (NULL, cur_result, copied_to, NULL);
mem_free (cur_result);
return (new_result);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -