📄 sflstr.c
字号:
const char *string,
const char *prefix)
{
ASSERT (string);
ASSERT (prefix);
if (*string == *prefix /* Check that first letters match */
&& strlen (string) >= strlen (prefix)
&& memcmp (string, prefix, strlen (prefix)) == 0)
return (TRUE);
else
return (FALSE);
}
/* ---------------------------------------------------------------------[<]-
Function: strprefix
Synopsis: Looks for one of the delimiter characters in the string; if
found, returns a string that contains the text up to that delimiter.
If not found, returns NULL. The returned string can be zero or more
characters long followed by a null byte. It is allocated using the
mem_alloc() function; you should free it using mem_free() when finished.
---------------------------------------------------------------------[>]-*/
char *
strprefix (
const char *string,
const char *delims)
{
const char
*nextch;
char
*token;
int
token_size;
ASSERT (string);
ASSERT (delims);
for (nextch = string; *nextch; nextch++)
{
if (strchr (delims, *string)) /* Is next character a delimiter */
{
token_size = (int) (nextch - string);
token = mem_alloc (token_size + 1);
if (token == NULL)
return (NULL); /* Not enough memory - fail */
memcpy (token, string, token_size);
token [token_size] = 0;
return (token);
}
}
return (NULL);
}
/* ---------------------------------------------------------------------[<]-
Function: strdefix
Synopsis: If string starts with specified prefix, returns pointer to
character after prefix. Null character is not considered part of the
prefix. If string does not start with specified prefix, returns NULL.
---------------------------------------------------------------------[>]-*/
char *
strdefix (
const char *string,
const char *prefix)
{
ASSERT (string);
ASSERT (prefix);
if (strlen (string) >= strlen (prefix)
&& memcmp (string, prefix, strlen (prefix)) == 0)
return ((char *) string + strlen (prefix));
else
return (NULL);
}
/* ---------------------------------------------------------------------[<]-
Function: strhash
Synopsis:
Calculates a 32-bit hash value for the string. The string must end in
a null. To use the result as a hash key, take the modulo over the hash
table size. The algorithm was designed by Peter Weinberger. This
version was adapted from Dr Dobb's Journal April 1996 page 26.
Examples:
int index;
index = (int) strhash (name) % TABLE_SIZE;
---------------------------------------------------------------------[>]-*/
qbyte
strhash (
const char *string)
{
qbyte
high_bits,
hash_value = 0;
ASSERT (string);
while (*string)
{
hash_value = (hash_value << 4) + *string++;
if ((high_bits = hash_value & 0xF0000000L) != 0)
hash_value ^= high_bits >> 24;
hash_value &= ~high_bits;
}
return (hash_value);
}
/* ---------------------------------------------------------------------[<]-
Function: strconvch
Synopsis: Converts all instances of one character in a string to some
other character. Returns string. Does nothing if the string is NULL.
---------------------------------------------------------------------[>]-*/
char *
strconvch (
char *string,
char from,
char to)
{
char *scan;
if (string)
{
scan = string;
while (*scan)
{
if (*scan == from)
*scan = to;
scan++;
}
}
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: xstrcat
Synopsis: Concatenates multiple strings into a single result. Eg.
xstrcat (buffer, "A", "B", NULL) stores "AB" in buffer. Returns dest.
Append the string to any existing contents of dest.
From DDJ Nov 1992 p. 155, with adaptions.
---------------------------------------------------------------------[>]-*/
char *
xstrcat (
char *dest,
const char *src, ...)
{
char
*feedback = dest;
va_list
va;
ASSERT (dest);
while (*dest) /* Find end of dest string */
dest++;
va_start (va, src);
while (src)
{
while (*src)
*dest++ = *src++;
src = va_arg (va, char *);
}
*dest = '\0'; /* Append a null character */
va_end (va);
return (feedback);
}
/* ---------------------------------------------------------------------[<]-
Function: xstrcpy
Synopsis: Concatenates multiple strings into a single result. Eg.
xstrcpy (buffer, "A", "B", NULL) stores "AB" in buffer. Returns dest.
Any existing contents of dest are cleared. If the dest buffer is NULL,
allocates a new buffer with the required length and returns that. The
buffer is allocated using mem_alloc(), and should eventually be freed
using mem_free() or mem_strfree(). Returns NULL if there was too little
memory to allocate the new string. We can't define macros with variable
argument lists, so we pass the file and line number through two globals,
xstrcpy_file and xstrcpy_line, which are reset to empty values after
each call to xstrcpy.
---------------------------------------------------------------------[>]-*/
char *
xstrcpy (
char *dest,
const char *src, ...)
{
const char
*src_ptr;
va_list
va;
size_t
dest_size; /* Size of concatenated strings */
/* Allocate new buffer if necessary */
if (dest == NULL)
{
va_start (va, src); /* Start variable args processing */
src_ptr = src;
dest_size = 1; /* Allow for trailing null char */
while (src_ptr)
{
dest_size += strlen (src_ptr);
src_ptr = va_arg (va, char *);
}
va_end (va); /* End variable args processing */
/* Allocate by going directly to mem_alloc_ function */
dest = mem_alloc_ (NULL, dest_size, xstrcpy_file, xstrcpy_line);
xstrcpy_file = "";
xstrcpy_line = 0;
if (dest == NULL)
return (NULL); /* Not enough memory */
}
/* Now copy strings into destination buffer */
va_start (va, src); /* Start variable args processing */
src_ptr = src;
dest [0] = '\0';
while (src_ptr)
{
strcat (dest, src_ptr);
src_ptr = va_arg (va, char *);
}
va_end (va); /* End variable args processing */
return (dest);
}
/* ---------------------------------------------------------------------[<]-
Function: lexcmp
Synopsis: Performs an unsigned comparison of two strings without regard
to the case of any letters in the strings. Returns a value that is
<TABLE>
<_0 if string1 is less than string2
==_0 if string1 is equal to string2
>_0 if string1 is greater than string2
</TABLE>
---------------------------------------------------------------------[>]-*/
int
lexcmp (
const char *string1,
const char *string2)
{
int cmp;
ASSERT (string1);
ASSERT (string2);
do
{
cmp = (byte) tolower (*string1) - (byte) tolower (*string2);
}
while (*string1++ && *string2++ && cmp == 0);
return (cmp);
}
/* ---------------------------------------------------------------------[<]-
Function: lexncmp
Synopsis: Performs an unsigned comparison of two strings without regard
to the case of specified number of letters in the strings.
Returns a value that is
<TABLE>
<_0 if string1 is less than string2
==_0 if string1 is equal to string2
>_0 if string1 is greater than string2
</TABLE>
---------------------------------------------------------------------[>]-*/
int
lexncmp (
const char *string1,
const char *string2,
const int count)
{
int
cmp;
char
*end;
ASSERT (string1);
ASSERT (string2);
end = (char *)string1 + count;
do
{
cmp = (byte) tolower (*string1) - (byte) tolower (*string2);
}
while (*string1++ && *string2++ && cmp == 0 && string1 < end);
return (cmp);
}
/* ---------------------------------------------------------------------[<]-
Function: lexwcmp
Synopsis: Compares two strings ignoring case, and allowing wildcards
in the second string (the pattern). Two special characters are
recognised in the pattern: '?' matches any character in the string,
and '*' matches the remainder of the string.
Returns a value that is:
<TABLE>
<_0 if string1 is less than pattern
==_0 if string1 is equal to pattern
>_0 if string1 is greater than pattern
</TABLE>
---------------------------------------------------------------------[>]-*/
int
lexwcmp (
const char *string1,
const char *pattern)
{
int cmp = 0;
ASSERT (string1);
ASSERT (pattern);
do
{
if (*pattern != '?' && *pattern != '*')
cmp = (byte) tolower (*string1) - (byte) tolower (*pattern);
}
while (*string1++ && *pattern++ && cmp == 0 && *pattern != '*');
return (cmp);
}
/* ---------------------------------------------------------------------[<]-
Function: soundex
Synopsis: Calculates the SOUNDEX code for the string. Returns the
address of a static area that holds the code. This area is overwritten
by each call to the soundex function. The SOUNDEX encoding converts
letters to uppercase, and translates each letter according to this
table: A0 B1 C2 D3 E0 F1 G2 H0 I0 J2 K2 L4 M5 N5 O0 P1 Q2 R6 S2 T3
U0 V1 W0 X2 Y0 Z2. Non-letters are ignored, letters that translate
to zero, and multiple occurences of the same value are also ignored.
This function always returns a 4-letter encoding: the first letter of
the string followed by the first three significant digits.
Examples:
printf ("Soundex of %s = %s\n", argv [1], soundex (argv [1]));
---------------------------------------------------------------------[>]-*/
char *
soundex (
const char *string)
{
ASSERT (string);
return (soundexn (string, 4, FALSE));
}
/* ---------------------------------------------------------------------[<]-
Function: soundexn
Synopsis: Calculates the SOUNDEX code for the string. Returns the
address of a static area that holds the code. This area is overwritten
by each call to the soundex function. The SOUNDEX encoding converts
letters to uppercase, and translates each letter according to this
table: A0 B1 C2 D3 E0 F1 G2 H0 I0 J2 K2 L4 M5 N5 O0 P1 Q2 R6 S2 T3
U0 V1 W0 X2 Y0 Z2. Non-letters are ignored, letters that translate
to zero, and multiple occurences of the same value are also ignored.
This function returns a N-letter encoding: the first letter of the
string followed by the first N-1 significant digits. N may not be
greater than SOUNDEX_MAX (100). If the fold argument is true, includes
the first letter in the calculated digits, else starts with the second
letter.
---------------------------------------------------------------------[>]-*/
char *
soundexn (
const char *string, int size, Bool fold)
{
# define SOUNDEX_MAX 100
# define SOUNDEX_TABLE \
"00000000000000000000000000000000" \
"00000000000000000000000000000000" \
"00123012002245501262301020200000" \
"00123012002245501262301020200000" \
"00000000000000000000000000000000" \
"00000000000000000000000000000000" \
"00000000000000000000000000000000" \
"00000000000000000000000000000000"
static char
*soundex_table = SOUNDEX_TABLE, /* ASCII-SOUNDEX conversion */
soundex_code [SOUNDEX_MAX + 1]; /* Letter + 3 digits */
int
index;
char
last_value = 0,
this_value;
ASSERT (string);
ASSERT (size > 0 && size <= SOUNDEX_MAX);
/* Initialise the soundex code to a string of zeroes */
memset (soundex_code, '0', size);
soundex_code [size] = '\0';
soundex_code [0] = toupper (*string);
last_value = fold? 0: soundex_table [(byte) *string];
index = 1; /* Store results at [index] */
while (*string)
{
this_value = soundex_table [(byte) *string++];
if (this_value == last_value /* Ignore doubles */
|| this_value == '0') /* and 'quiet' letters */
{
last_value = this_value;
continue;
}
last_value = this_value;
soundex_code [index++] = this_value;
if (index == size) /* Up to size result characters */
break;
}
return (soundex_code);
}
/* ---------------------------------------------------------------------[<]-
Function: strt2descr
Synopsis: Converts a table of strings into a single block of memory.
The input table consists of an array of null-terminated strings,
terminated in a null pointer. Returns the address of a DESCR block
defined as: "typedef struct {size_t size; byte *data} DESCR;".
Allocates the descriptor block using the mem_alloc() function; you must
free it using mem_free() when you are finished with it. The strings are
packed into the descriptor data field, each terminated by a null byte.
The final string is terminated by two nulls. The total size of the
descriptor is descr-> size + sizeof (DESCR). Note that if you omit the
last null pointer in the input table, you will probably get an addressing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -