3 * Purpose: Low-level string handling and other utilities.
5 * Copyright (c) 1997-2005 Ben Harrison, Robert Ruehlmann.
7 * This work is free software; you can redistribute it and/or modify it
8 * under the terms of either:
10 * a) the GNU General Public License as published by the Free Software
11 * Foundation, version 2, or
13 * b) the "Angband licence":
14 * This software may be copied and distributed for educational, research,
15 * and not for profit purposes provided that this copyright and statement
16 * are included in all such copies. Other copyrights may also apply.
23 * Convenient storage of the program name
29 * Case insensitive comparison between two strings
31 int my_stricmp(const char *s1
, const char *s2
)
39 /* We've reached the end of both strings simultaneously */
40 if ((*s1
== 0) && (*s2
== 0))
42 /* We're still here, so s1 and s2 are equal */
46 ch1
= toupper((unsigned char) *s1
);
47 ch2
= toupper((unsigned char) *s2
);
49 /* If the characters don't match */
52 /* return the difference between them */
53 return ((int)(ch1
- ch2
));
56 /* Step on through both strings */
64 * Case insensitive comparison between the first n characters of two strings
66 int my_strnicmp(cptr a
, cptr b
, int n
)
71 /* Scan the strings */
72 for (s1
= a
, s2
= b
; n
> 0; s1
++, s2
++, n
--)
74 z1
= toupper((unsigned char)*s1
);
75 z2
= toupper((unsigned char)*s2
);
76 if (z1
< z2
) return (-1);
77 if (z1
> z2
) return (1);
86 * The my_strcpy() function copies up to 'bufsize'-1 characters from 'src'
87 * to 'buf' and NUL-terminates the result. The 'buf' and 'src' strings may
90 * my_strcpy() returns strlen(src). This makes checking for truncation
91 * easy. Example: if (my_strcpy(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
93 * This function should be equivalent to the strlcpy() function in BSD.
95 size_t my_strcpy(char *buf
, const char *src
, size_t bufsize
)
97 size_t len
= strlen(src
);
101 if (bufsize
== 0) return ret
;
104 if (len
>= bufsize
) len
= bufsize
- 1;
106 /* Copy the string and terminate it */
107 (void)memcpy(buf
, src
, len
);
110 /* Return strlen(src) */
116 * The my_strcat() tries to append a string to an existing NUL-terminated string.
117 * It never writes more characters into the buffer than indicated by 'bufsize' and
118 * NUL-terminates the buffer. The 'buf' and 'src' strings may not overlap.
120 * my_strcat() returns strlen(buf) + strlen(src). This makes checking for
121 * truncation easy. Example:
122 * if (my_strcat(buf, src, sizeof(buf)) >= sizeof(buf)) ...;
124 * This function should be equivalent to the strlcat() function in BSD.
126 size_t my_strcat(char *buf
, const char *src
, size_t bufsize
)
128 size_t dlen
= strlen(buf
);
130 /* Is there room left in the buffer? */
131 if (dlen
< bufsize
- 1)
133 /* Append as much as possible */
134 return (dlen
+ my_strcpy(buf
+ dlen
, src
, bufsize
- dlen
));
138 /* Return without appending */
139 return (dlen
+ strlen(src
));
145 * Determine if string "a" is equal to string "b"
148 bool streq(cptr a
, cptr b
)
150 return (!strcmp(a
, b
));
155 * Determine if string "t" is a suffix of string "s"
157 bool suffix(cptr s
, cptr t
)
159 size_t tlen
= strlen(t
);
160 size_t slen
= strlen(s
);
162 /* Check for incompatible lengths */
163 if (tlen
> slen
) return (FALSE
);
165 /* Compare "t" to the end of "s" */
166 return (!strcmp(s
+ slen
- tlen
, t
));
171 * Determine if string "t" is a prefix of string "s"
173 bool prefix(cptr s
, cptr t
)
178 /* Compare content and length */
179 if (*t
++ != *s
++) return (FALSE
);
182 /* Matched, we have a prefix */
189 * Redefinable "plog" action
191 void (*plog_aux
)(cptr
) = NULL
;
194 * Print (or log) a "warning" message (ala "perror()")
195 * Note the use of the (optional) "plog_aux" hook.
199 /* Use the "alternative" function if possible */
200 if (plog_aux
) (*plog_aux
)(str
);
202 /* Just do a labeled fprintf to stderr */
203 else (void)(fprintf(stderr
, "%s: %s\n", argv0
? argv0
: "?", str
));
209 * Redefinable "quit" action
211 void (*quit_aux
)(cptr
) = NULL
;
214 * Exit (ala "exit()"). If 'str' is NULL, do "exit(EXIT_SUCCESS)".
215 * Otherwise, plog() 'str' and exit with an error code of -1.
216 * But always use 'quit_aux', if set, before anything else.
220 /* Attempt to use the aux function */
221 if (quit_aux
) (*quit_aux
)(str
);
224 if (!str
) (void)(exit(EXIT_SUCCESS
));
226 /* Send the string to plog() */
230 (void)(exit(EXIT_FAILURE
));