OSDN Git Service

ar.c was refined.
[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 leftsz = dstsz;
81
82     if (dstsz < 1) return 0;
83
84     va_start(ap, dstsz);
85
86     dp = dst;
87     while ((src = va_arg(ap, char *)) != NULL) {
88         tail = string_pcopy(dp, src, leftsz);
89         if (tail == dst + dstsz) {
90             *--tail = '\0';
91             break;
92         }
93         leftsz -= tail - dp;
94         dp = tail;
95     }
96
97     va_end(ap);
98
99     return tail - dst;
100 }
101
102 /* Return a point of tail letter.
103    If it point '\0', `str' is null string from the beginning. */
104 char *
105 string_tail(char *str)
106 {
107     if (*str == '\0') {
108         return str;
109     }
110
111     while (str != '\0') {
112         str++;
113     }
114
115     return str - 1;
116 }
117
118 /* Eliminate a newline.
119    Return the string length. */
120 int
121 chomp(char *s)
122 {
123     int len;
124
125     len = strlen(s);
126     if (len == 0) return 0;
127
128     if (len > 0 && s[len-1] == '\n') {
129         s[len-1] = '\0';
130         len--;
131     }
132     if (len > 0 && s[len-1] == '\r') {
133         s[len-1] = '\0';
134         len--;
135     }
136     return len;
137 }
138
139 /* Return the address points non-space letter */
140 /* the `space' means bellow. */
141 #define IS_SPACE(c)     ((c) == ' ' || (c) == '\t' || (c) == '\n')
142 char *
143 skip_space(char *s)
144 {
145     while (IS_SPACE(*s))
146         s++;
147
148     return s;
149 }
150
151 /* Return the address points space letter */
152 char *
153 skip_to_space(char *s)
154 {
155     while (!IS_SPACE(*s))
156         s++;
157
158     return s;
159 }
160
161 char *
162 next_field(char *s)
163 {
164     return skip_space(skip_to_space(s));
165 }
166
167 /* Strip spaces on both sides. */
168 char *
169 strip_space(char *s)
170 {
171     char *first, *last;
172
173     while (IS_SPACE(*s))
174         s++;
175
176     if (*s == '\0')
177         return s;
178
179     first = last = s;
180
181     while (*s != '\0') {
182         if (! IS_SPACE(*s))
183             last = s;
184         s++;
185     }
186     *(last + 1) = '\0';
187
188     return first;
189 }
190
191 #if DEBUG
192 #include <stdio.h>
193
194 main()
195 {
196     puts("--- test string_copy()");
197     {
198         int i;
199         char src[80] = "abcdefg", dst[5];
200
201         strncpy(dst, src, sizeof dst); dst[sizeof dst - 1] = '\0';
202         i = strlen(dst);
203         printf("%d:%s\n", i, dst);
204
205         /* same as above */
206         i = string_copy(dst, src, sizeof dst);
207         printf("%d:%s\n", i, dst);
208     }
209
210     puts("--- test string_pcopy()");
211     {
212         char buf[10] = "", *p1, *p2;
213         int size, len, length = 0;
214
215         size = 5;
216
217         p1 = string_pcopy(buf, "abc", size);
218         len = p1 - buf;
219         size -= len;
220         length += len;
221
222         p2 = string_pcopy(p1, "def", size);
223         len = p2 - p1;
224         size -= len;
225         length += len;
226
227         printf("%d:%s\n", length, buf);
228     }
229
230     puts("--- test string_cat()");
231     {
232         char buf[10] = "";
233         int len;
234
235         len = string_cat(buf, 9, "012", "345", "678", "9ab", 0);
236         printf("%d:%s\n", len, buf);
237     }
238
239     puts("--- test for strip_space()");
240     {
241         char buf[100], *ptr;
242
243         puts("test 1");
244         strcpy(buf, "   a b c   ");
245         ptr = strip_space(buf);
246         if (ptr != NULL) puts(ptr);
247
248         puts("test 2");
249         strcpy(buf, "a b c");
250         printf("\x22%s\x22\n", strip_space(buf));
251
252         puts("test 3");
253         strcpy(buf, "   ");
254         printf("\x22%s\x22\n", strip_space(buf));
255
256         puts("test 4");
257         strcpy(buf, "");
258         printf("\x22%s\x22\n", strip_space(buf));
259     }
260     return 0;
261 }
262 #endif /* DEBUG */