Angband 3.0.9b.
[angband.git] / src / z-util.c
blob160079a61af88bf21765982f130f375eba51c534
1 /*
2 * File: z-util.c
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.
18 #include "z-util.h"
23 * Convenient storage of the program name
25 cptr argv0 = NULL;
29 * Case insensitive comparison between two strings
31 int my_stricmp(const char *s1, const char *s2)
33 char ch1 = 0;
34 char ch2 = 0;
36 /* Just loop */
37 while (TRUE)
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 */
43 return (0);
46 ch1 = toupper((unsigned char) *s1);
47 ch2 = toupper((unsigned char) *s2);
49 /* If the characters don't match */
50 if (ch1 != ch2)
52 /* return the difference between them */
53 return ((int)(ch1 - ch2));
56 /* Step on through both strings */
57 s1++;
58 s2++;
64 * Case insensitive comparison between the first n characters of two strings
66 int my_strnicmp(cptr a, cptr b, int n)
68 cptr s1, s2;
69 char z1, z2;
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);
78 if (!z1) return (0);
81 return 0;
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
88 * not overlap.
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);
98 size_t ret = len;
100 /* Paranoia */
101 if (bufsize == 0) return ret;
103 /* Truncate */
104 if (len >= bufsize) len = bufsize - 1;
106 /* Copy the string and terminate it */
107 (void)memcpy(buf, src, len);
108 buf[len] = '\0';
110 /* Return strlen(src) */
111 return ret;
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));
136 else
138 /* Return without appending */
139 return (dlen + strlen(src));
145 * Determine if string "a" is equal to string "b"
147 #undef streq
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)
175 /* Scan "t" */
176 while (*t)
178 /* Compare content and length */
179 if (*t++ != *s++) return (FALSE);
182 /* Matched, we have a prefix */
183 return (TRUE);
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.
197 void plog(cptr str)
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.
218 void quit(cptr str)
220 /* Attempt to use the aux function */
221 if (quit_aux) (*quit_aux)(str);
223 /* Success */
224 if (!str) (void)(exit(EXIT_SUCCESS));
226 /* Send the string to plog() */
227 plog(str);
229 /* Failure */
230 (void)(exit(EXIT_FAILURE));