OSDN Git Service

should not add signed operand to unsigned
[lha/olha.git] / strlib.c
1 /*
2   Copyright (c) 2000 Koji Arai
3
4   Permission is hereby granted, free of charge, to any person
5   obtaining a copy of this software and associated documentation files
6   (the "Software"), to deal in the Software without restriction,
7   including without limitation the rights to use, copy, modify, merge,
8   publish, distribute, sublicense, and/or sell copies of the Software,
9   and to permit persons to whom the Software is furnished to do so,
10   subject to the following conditions:
11
12   The above copyright notice and this permission notice shall be
13   included in all copies or substantial portions of the Software.
14
15   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18   NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19   BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20   ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21   CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22   SOFTWARE.
23 */
24
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29 int
30 string_equal(char *str1, char *str2)
31 {
32     return strcmp(str1, str2) == 0;
33 }
34
35 /* This function is similar to strncpy() but `dst' is always terminated '\0'.
36    Return the copied string length. */
37 int
38 string_copy(char *dst, char *src, int dstsz)
39 {
40     int i;
41
42     if (dstsz < 1) return 0;
43
44     for (i = 0; i < dstsz; i++) {
45         if ((dst[i] = src[i]) == '\0')
46             return i;
47     }
48
49     /* here is i == dstsz */
50     dst[--i] = '\0';    /* if eliminate this line and return dst,
51                            this function is same as strncpy(). */
52
53     return i;
54 }
55
56 /* This function is identical to stpncpy()
57    in GNU gcc (and in MS-DOG compiler?) */
58 char *
59 string_pcopy(char *dst, char *src, int dstsz)
60 {
61     int i;
62
63     for (i = 0; i < dstsz; i++) {
64         if ((dst[i] = src[i]) == '\0')
65             break;
66     }
67
68     /* if here is `return dst', this function is same as strncpy() */
69     return &dst[i];
70 }
71
72 /* string concatenation.
73    1st arg. `dst' is always terminated '\0'.
74    Return the string length */
75 int
76 string_cat(char *dst, int dstsz, ...)
77 {
78     va_list ap;
79     char *dp, *src, *tail;
80     int i;
81     int leftsz = dstsz;
82
83     if (dstsz < 1) return 0;
84
85     va_start(ap, dstsz);
86
87     dp = dst;
88     while ((src = va_arg(ap, char *)) != NULL) {
89         tail = string_pcopy(dp, src, leftsz);
90         if (tail == dst + dstsz) {
91             *--tail = '\0';
92             break;
93         }
94         leftsz -= tail - dp;
95         dp = tail;
96     }
97
98     va_end(ap);
99
100     return tail - dst;
101 }
102
103 /* Return a point of tail letter.
104    If it point '\0', `str' is null string from the beginning. */
105 char *
106 string_tail(char *str)
107 {
108     if (*str == '\0') {
109         return str;
110     }
111
112     while (str != '\0') {
113         str++;
114     }
115
116     return str - 1;
117 }
118
119 /* Eliminate a newline.
120    Return the string length. */
121 int
122 chomp(char *s)
123 {
124     int len;
125
126     len = strlen(s);
127     if (len == 0) return 0;
128
129     if (len > 0 && s[len-1] == '\n') {
130         s[len-1] = '\0';
131         len--;
132     }
133     if (len > 0 && s[len-1] == '\r') {
134         s[len-1] = '\0';
135         len--;
136     }
137     return len;
138 }
139
140 /* Return the address points non-space letter */
141 /* the `space' means bellow. */
142 #define IS_SPACE(c)     ((c) == ' ' || (c) == '\t' || (c) == '\n')
143 char *
144 skip_space(char *s)
145 {
146     while (IS_SPACE(*s))
147         s++;
148
149     return s;
150 }
151
152 /* Return the address points space letter */
153 char *
154 skip_to_space(char *s)
155 {
156     while (!IS_SPACE(*s))
157         s++;
158
159     return s;
160 }
161
162 char *
163 next_field(char *s)
164 {
165     return skip_space(skip_to_space(s));
166 }
167
168 /* Strip spaces on both sides. */
169 char *
170 strip_space(char *s)
171 {
172     char *first, *last;
173
174     while (IS_SPACE(*s))
175         s++;
176
177     if (*s == '\0')
178         return s;
179
180     first = last = s;
181
182     while (*s != '\0') {
183         if (! IS_SPACE(*s))
184             last = s;
185         s++;
186     }
187     *(last + 1) = '\0';
188
189     return first;
190 }
191
192 #if DEBUG
193 #include <stdio.h>
194
195 main()
196 {
197     puts("--- test string_copy()");
198     {
199         int i;
200         char src[80] = "abcdefg", dst[5];
201
202         strncpy(dst, src, sizeof dst); dst[sizeof dst - 1] = '\0';
203         i = strlen(dst);
204         printf("%d:%s\n", i, dst);
205
206         /* same as above */
207         i = string_copy(dst, src, sizeof dst);
208         printf("%d:%s\n", i, dst);
209     }
210
211     puts("--- test string_pcopy()");
212     {
213         char buf[10] = "", *p1, *p2;
214         int size, len, length = 0;
215
216         size = 5;
217
218         p1 = string_pcopy(buf, "abc", size);
219         len = p1 - buf;
220         size -= len;
221         length += len;
222
223         p2 = string_pcopy(p1, "def", size);
224         len = p2 - p1;
225         size -= len;
226         length += len;
227
228         printf("%d:%s\n", length, buf);
229     }
230
231     puts("--- test string_cat()");
232     {
233         char buf[10] = "";
234         int len;
235
236         len = string_cat(buf, 9, "012", "345", "678", "9ab", 0);
237         printf("%d:%s\n", len, buf);
238     }
239
240     puts("--- test for strip_space()");
241     {
242         char buf[100], *ptr;
243
244         puts("test 1");
245         strcpy(buf, "   a b c   ");
246         ptr = strip_space(buf);
247         if (ptr != NULL) puts(ptr);
248
249         puts("test 2");
250         strcpy(buf, "a b c");
251         printf("\x22%s\x22\n", strip_space(buf));
252
253         puts("test 3");
254         strcpy(buf, "   ");
255         printf("\x22%s\x22\n", strip_space(buf));
256
257         puts("test 4");
258         strcpy(buf, "");
259         printf("\x22%s\x22\n", strip_space(buf));
260     }
261     return 0;
262 }
263 #endif /* DEBUG */