📄 sflstr.c
字号:
/* ----------------------------------------------------------------<Prolog>-
Name: sflstr.c
Title: String-handling functions
Package: Standard Function Library (SFL)
Written: 1992/10/28 iMatix SFL project team <sfl@imatix.com>
Revised: 1999/09/02
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 "sfllist.h" /* Linked-list functions */
#include "sflmem.h" /* Memory handling functions */
#include "sflsymb.h" /* Symbol-table functions */
#include "sfltok.h" /* Token-handling functions */
#include "sflstr.h" /* Prototypes for functions */
/* Globals */
char *xstrcpy_file = ""; /* Source file calling xstrcpy */
word xstrcpy_line = 0; /* Source line for call */
/* ---------------------------------------------------------------------[<]-
Function: strdupl
Synopsis:
Makes a duplicate of string, obtaining space with a call to malloc().
The allocated space is strlen (string) + 1 bytes long. The caller is
responsible for freeing the space allocated by strdup when it is no
longer needed. Returns a pointer to the allocated string, which holds
a copy of the parameter string. Returns NULL if there was insufficient
heap storage available to allocate the string, or if the original string
was itself NULL.
Use this function in place of the non-portable strdup() function. You
may also want to use the more robust _mem_strdup () function.
---------------------------------------------------------------------[>]-*/
char *
strdupl (
const char *string)
{
char *copy;
size_t length;
if (string)
{
length = strlen (string) + 1;
copy = malloc (length);
if (copy)
strncpy (copy, string, length);
}
else
copy = NULL;
return (copy);
}
/* ---------------------------------------------------------------------[<]-
Function: strfree
Synopsis:
Releases memory occupied by a string. Call this function only when you
previously allocated the string using malloc or strdupl(). You pass the
address of a char pointer; this function sets the pointer to NULL. This
is a safety measure meant to make it safe to try to free non-allocated
strings. In your code, initialise all such pointers to NULL. Returns
the address of the modified pointer.
---------------------------------------------------------------------[>]-*/
char **
strfree (
char **string)
{
ASSERT (string);
if (string && *string)
{
free (*string);
*string = NULL;
}
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strskp
Synopsis: Skips leading spaces in string, and returns a pointer to the
first non-blank character. If this is a null, the end of the string
was reached.
---------------------------------------------------------------------[>]-*/
char *
strskp (
const char *string)
{
char
*skip = (char *) string;
ASSERT (string);
while (*skip == ' ')
skip++;
return (skip);
}
/* ---------------------------------------------------------------------[<]-
Function: strcset
Synopsis: Sets all characters in string up to but not including the
final null character to ch. Returns string. Use this function instead
of the equivalent but non-portable strset() function.
---------------------------------------------------------------------[>]-*/
char *
strcset (
char *string,
char ch)
{
char *scan;
ASSERT (string);
scan = string;
while (*scan)
*scan++ = ch;
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strpad
Synopsis: Returns string of length characters, padding with ch or
truncating if necessary. String must be at least length + 1 long.
---------------------------------------------------------------------[>]-*/
char *
strpad (
char *string,
char ch,
int length)
{
int cursize;
ASSERT (string);
cursize = strlen (string); /* Get current length of string */
while (cursize < length) /* Pad until at desired length */
string [cursize++] = ch;
string [cursize++] = '\0'; /* Add terminating null */
return (string); /* and return to caller */
}
/* ---------------------------------------------------------------------[<]-
Function: strlwc
Synopsis: Converts all alphabetic characters in string to lowercase,
stopping at the final null character. Returns string. If string is
null, returns null. We do not call this function strlwr because that
is already provided by some systems (but not by ANSI C).
---------------------------------------------------------------------[>]-*/
char *
strlwc (
char *string)
{
char *scan;
if (string)
{
scan = string;
while (*scan)
{
*scan = (char) tolower (*scan);
scan++;
}
}
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strupc
Synopsis: Converts all alphabetic characters in string to uppercase,
stopping at the final null character. Returns string. If string is
null, returns null. We do not call this function strupr because that
is already provided by some systems (but not by ANSI C).
---------------------------------------------------------------------[>]-*/
char *
strupc (
char *string)
{
char *scan;
if (string)
{
scan = string;
while (*scan)
{
*scan = (char) toupper (*scan);
scan++;
}
}
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strcrop
Synopsis: Drops trailing whitespace from string by truncating string
to the last non-whitespace character. Returns string. If string is
null, returns null.
---------------------------------------------------------------------[>]-*/
char *
strcrop (
char *string)
{
char *last;
if (string)
{
last = string + strlen (string);
while (last > string)
{
if (!isspace (*(last - 1)))
break;
last--;
}
*last = 0;
}
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: stropen
Synopsis: Inserts a character at string, and places a blank in the gap.
If align is TRUE, makes room by reducing the size of the next gap of 2
or more spaces. If align is FALSE, extends the size of the string.
Returns string.
---------------------------------------------------------------------[>]-*/
char *
stropen (
char *string,
Bool align)
{
char *gap;
int length;
ASSERT (string);
length = strlen (string) + 1; /* By default, move string + NULL */
if (align) /* If align is TRUE, find gap */
{
gap = strstr (string, " ");
if (gap)
length = (int) (gap - string);
}
memmove (string + 1, string, length);
string [0] = ' '; /* Stick a space into string */
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strclose
Synopsis: Removes the character at string, and shifts the remainder
down by one. If align is TRUE, only shifts up to the next gap of 2 or
more spaces. Returns string.
---------------------------------------------------------------------[>]-*/
char *
strclose (
char *string,
Bool align)
{
char *gap;
int length;
ASSERT (string);
length = strlen (string); /* By default, move string + NULL */
if (align) { /* If align is TRUE, find gap */
gap = strstr (string, " ");
if (gap && gap != string)
length = (int) (gap - string);
}
memmove (string, string + 1, length);
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strunique
Synopsis: Reduces chains of some character to a single instances.
For example: replace multiple spaces by one space. Returns string.
---------------------------------------------------------------------[>]-*/
char *
strunique (
char *string,
char unique)
{
char
*from,
*to;
ASSERT (string);
if (strnull (string))
return (string); /* Get rid of special cases */
from = string + 1;
to = string;
while (*from)
{
if (*from == unique && *to == unique)
from++;
else
*++to = *from++;
}
*++to = '\0';
return (string);
}
/* ---------------------------------------------------------------------[<]-
Function: strmatch
Synopsis: Calculates a similarity index for the two strings. This
is a value from 0 to 32767 with higher values indicating a closer match.
The two strings are compared without regard for case. The algorithm was
designed by Leif Svalgaard <leif@ibm.net>.
---------------------------------------------------------------------[>]-*/
int
strmatch (
const char *string1,
const char *string2)
{
static int
name_weight [30] = {
20, 15, 13, 11, 10, 9, 8, 8, 7, 7, 7, 6, 6, 6, 6,
6, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4
};
int
comp_index,
name_index,
start_of_string,
longest_so_far,
substring_contribution,
substring_length,
compare_length,
longest_length,
length_difference,
name_length,
char_index,
similarity_index,
similarity_weight;
char
cur_name_char;
ASSERT (string1);
ASSERT (string2);
name_length = strlen (string1);
compare_length = strlen (string2);
if (name_length > compare_length)
{
length_difference = name_length - compare_length;
longest_length = name_length;
}
else
{
length_difference = compare_length - name_length;
longest_length = compare_length;
}
if (compare_length)
{
similarity_weight = 0;
substring_contribution = 0;
for (char_index = 0; char_index < name_length; char_index++)
{
start_of_string = char_index;
cur_name_char = (char) tolower (string1 [char_index]);
longest_so_far = 0;
comp_index = 0;
while (comp_index < compare_length)
{
while ((comp_index < compare_length)
&& (tolower (string2 [comp_index]) != cur_name_char))
comp_index++;
substring_length = 0;
name_index = start_of_string;
while ((comp_index < compare_length)
&& (tolower (string2 [comp_index])
== tolower (string1 [name_index])))
{
if (comp_index == name_index)
substring_contribution++;
comp_index++;
if (name_index < name_length)
{
name_index++;
substring_length++;
}
}
substring_contribution += (substring_length + 1) * 3;
if (longest_so_far < substring_length)
longest_so_far = substring_length;
}
similarity_weight += (substring_contribution
+ longest_so_far + 1) * 2;
similarity_weight /= name_length + 1;
}
similarity_index = (name_length < 30? name_weight [name_length]: 3)
* longest_length;
similarity_index /= 10;
similarity_index += 2 * length_difference / longest_length;
similarity_index = 100 * similarity_weight / similarity_index;
}
else
similarity_index = 0;
return (similarity_index);
}
/* ---------------------------------------------------------------------[<]-
Function: strprefixed
Synopsis: If string starts with specified prefix, returns TRUE. If
string does not start with specified prefix, returns FALSE.
---------------------------------------------------------------------[>]-*/
Bool
strprefixed (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -