Add macro %isu_package to generate ISU Package
[platform/upstream/rpm.git] / rpmio / rpmstring.c
1 /**
2  * \file rpmio/rpmstring.c
3  */
4
5 #include "system.h"
6
7 #include <stdarg.h>
8 #include <stdio.h>
9
10 #include <rpm/rpmstring.h>
11 #include "debug.h"
12
13
14 int rstrcasecmp(const char * s1, const char * s2)
15 {
16   const char * p1 = s1;
17   const char * p2 = s2;
18   char c1, c2;
19
20   if (p1 == p2)
21     return 0;
22
23   do
24     {
25       c1 = rtolower (*p1++);
26       c2 = rtolower (*p2++);
27       if (c1 == '\0')
28         break;
29     }
30   while (c1 == c2);
31
32   return (int)(c1 - c2);
33 }
34
35 int rstrncasecmp(const char *s1, const char *s2, size_t n)
36 {
37   const char * p1 = s1;
38   const char * p2 = s2;
39   char c1, c2;
40
41   if (p1 == p2 || n == 0)
42     return 0;
43
44   do
45     {
46       c1 = rtolower (*p1++);
47       c2 = rtolower (*p2++);
48       if (c1 == '\0' || c1 != c2)
49         break;
50     } while (--n > 0);
51
52   return (int)(c1 - c2);
53 }
54
55 /* 
56  * Simple and stupid asprintf() clone.
57  * FIXME: write to work with non-C99 vsnprintf or check for one in configure.
58  */
59 int rasprintf(char **strp, const char *fmt, ...)
60 {
61     int n;
62     va_list ap;
63     char * p = NULL;
64   
65     if (strp == NULL) 
66         return -1;
67
68     va_start(ap, fmt);
69     n = vsnprintf(NULL, 0, fmt, ap);
70     va_end(ap);
71
72     if (n >= -1) {
73         size_t nb = n + 1;
74         p = xmalloc(nb);
75         va_start(ap, fmt);
76         n = vsnprintf(p, nb, fmt, ap);
77         va_end(ap);
78     } 
79     *strp = p;
80     return n;
81 }
82
83 /*
84  * Concatenate two strings with dynamically (re)allocated
85  * memory what prevents static buffer overflows by design.
86  * *dest is reallocated to the size of strings to concatenate.
87  *
88  * Note:
89  * 1) char *buf = rstrcat(NULL,"string"); is the same like rstrcat(&buf,"string");
90  * 2) rstrcat(&buf,NULL) returns buf
91  * 3) rstrcat(NULL,NULL) returns NULL
92  * 4) *dest and src can overlap
93  */
94 char *rstrcat(char **dest, const char *src)
95 {
96     if ( src == NULL ) {
97         return dest != NULL ? *dest : NULL;
98     }
99
100     if ( dest == NULL ) {
101         return xstrdup(src);
102     }
103
104     {
105         size_t dest_size = *dest != NULL ? strlen(*dest) : 0;
106         size_t src_size = strlen(src);
107
108         *dest = xrealloc(*dest, dest_size+src_size+1);          /* include '\0' */
109         memmove(&(*dest)[dest_size], src, src_size+1);
110     }
111
112     return *dest;
113 }
114
115 /*
116  * Concatenate strings with dynamically (re)allocated
117  * memory what prevents static buffer overflows by design.
118  * *dest is reallocated to the size of strings to concatenate.
119  * List of strings has to be NULL terminated.
120  *
121  * Note:
122  * 1) char *buf = rstrscat(NULL,"string",NULL); is the same like rstrscat(&buf,"string",NULL);
123  * 2) rstrscat(&buf,NULL) returns buf
124  * 3) rstrscat(NULL,NULL) returns NULL
125  * 4) *dest and argument strings can overlap
126  */
127 char *rstrscat(char **dest, const char *arg, ...)
128 {
129     va_list ap;
130     size_t arg_size, dst_size;
131     const char *s;
132     char *dst, *p;
133
134     dst = dest ? *dest : NULL;
135
136     if ( arg == NULL ) {
137         return dst;
138     }
139
140     va_start(ap, arg);
141     for (arg_size=0, s=arg; s; s = va_arg(ap, const char *))
142         arg_size += strlen(s);
143     va_end(ap);
144
145     dst_size = dst ? strlen(dst) : 0;
146     dst = xrealloc(dst, dst_size+arg_size+1);    /* include '\0' */
147     p = &dst[dst_size];
148
149     va_start(ap, arg);
150     for (s = arg; s; s = va_arg(ap, const char *)) {
151         size_t size = strlen(s);
152         memmove(p, s, size);
153         p += size;
154     }
155     va_end(ap);
156     *p = '\0';
157
158     if ( dest ) {
159         *dest = dst;
160     }
161
162     return dst;
163 }
164
165 /*
166  * Adapted from OpenBSD, strlcpy() originally developed by
167  * Todd C. Miller <Todd.Miller@courtesan.com>
168  */
169 size_t rstrlcpy(char *dest, const char *src, size_t n)
170 {
171     char *d = dest;
172     const char *s = src;
173     size_t len = n;
174
175     /* Copy as many bytes as will fit */
176     if (len != 0) {
177         while (--len != 0) {
178             if ((*d++ = *s++) == '\0')
179                 break;
180         }
181     }
182
183     /* Not enough room in dst, add NUL and traverse rest of src */
184     if (len == 0) {
185         if (n != 0)
186             *d = '\0'; /* NUL-terminate dst */
187         while (*s++)
188             ;
189     }
190
191     return s - src - 1; /* count does not include NUL */
192 }