1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /**************************************************************************
4 *
5 * Copyright (C) 2000-2016, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *
8 ***************************************************************************
9 * file name: pkgdata.c
10 * encoding: ANSI X3.4 (1968)
11 * tab size: 8 (not used)
12 * indentation:4
13 *
14 * created on: 2000may16
15 * created by: Steven \u24C7 Loomis
16 *
17 * common types for pkgdata
18 */
19
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "unicode/utypes.h"
24 #include "unicode/putil.h"
25 #include "cmemory.h"
26 #include "cstring.h"
27 #include "pkgtypes.h"
28 #include "putilimp.h"
29
pkg_writeCharListWrap(FileStream * s,CharList * l,const char * delim,const char * brk,int32_t quote)30 const char *pkg_writeCharListWrap(FileStream *s, CharList *l, const char *delim, const char *brk, int32_t quote)
31 {
32 int32_t ln = 0;
33 char buffer[1024];
34 while(l != NULL)
35 {
36 if(l->str)
37 {
38 uprv_strncpy(buffer, l->str, 1020);
39 buffer[1019]=0;
40
41 if(quote < 0) { /* remove quotes */
42 if(buffer[uprv_strlen(buffer)-1] == '"') {
43 buffer[uprv_strlen(buffer)-1] = '\0';
44 }
45 if(buffer[0] == '"') {
46 uprv_strcpy(buffer, buffer+1);
47 }
48 } else if(quote > 0) { /* add quotes */
49 if(l->str[0] != '"') {
50 uprv_strcpy(buffer, "\"");
51 uprv_strncat(buffer, l->str,1020);
52 }
53 if(l->str[uprv_strlen(l->str)-1] != '"') {
54 uprv_strcat(buffer, "\"");
55 }
56 }
57 T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));
58
59 ln += (int32_t)uprv_strlen(l->str);
60 }
61
62 if(l->next && delim)
63 {
64 if(ln > 60 && brk) {
65 ln = 0;
66 T_FileStream_write(s, brk, (int32_t)uprv_strlen(brk));
67 }
68 T_FileStream_write(s, delim, (int32_t)uprv_strlen(delim));
69 }
70 l = l->next;
71 }
72 return NULL;
73 }
74
75
pkg_writeCharList(FileStream * s,CharList * l,const char * delim,int32_t quote)76 const char *pkg_writeCharList(FileStream *s, CharList *l, const char *delim, int32_t quote)
77 {
78 char buffer[1024];
79 while(l != NULL)
80 {
81 if(l->str)
82 {
83 uprv_strncpy(buffer, l->str, 1023);
84 buffer[1023]=0;
85 if(uprv_strlen(l->str) >= 1023)
86 {
87 fprintf(stderr, "%s:%d: Internal error, line too long (greater than 1023 chars)\n",
88 __FILE__, __LINE__);
89 exit(0);
90 }
91 if(quote < 0) { /* remove quotes */
92 if(buffer[uprv_strlen(buffer)-1] == '"') {
93 buffer[uprv_strlen(buffer)-1] = '\0';
94 }
95 if(buffer[0] == '"') {
96 uprv_strcpy(buffer, buffer+1);
97 }
98 } else if(quote > 0) { /* add quotes */
99 if(l->str[0] != '"') {
100 uprv_strcpy(buffer, "\"");
101 uprv_strcat(buffer, l->str);
102 }
103 if(l->str[uprv_strlen(l->str)-1] != '"') {
104 uprv_strcat(buffer, "\"");
105 }
106 }
107 T_FileStream_write(s, buffer, (int32_t)uprv_strlen(buffer));
108 }
109
110 if(l->next && delim)
111 {
112 T_FileStream_write(s, delim, (int32_t)uprv_strlen(delim));
113 }
114 l = l->next;
115 }
116 return NULL;
117 }
118
119
120 /*
121 * Count items . 0 if null
122 */
pkg_countCharList(CharList * l)123 uint32_t pkg_countCharList(CharList *l)
124 {
125 uint32_t c = 0;
126 while(l != NULL)
127 {
128 c++;
129 l = l->next;
130 }
131
132 return c;
133 }
134
135 /*
136 * Prepend string to CharList
137 */
pkg_prependToList(CharList * l,const char * str)138 CharList *pkg_prependToList(CharList *l, const char *str)
139 {
140 CharList *newList;
141 newList = uprv_malloc(sizeof(CharList));
142
143 /* test for NULL */
144 if(newList == NULL) {
145 return NULL;
146 }
147
148 newList->str = str;
149 newList->next = l;
150 return newList;
151 }
152
153 /*
154 * append string to CharList. *end or even end can be null if you don't
155 * know it.[slow]
156 * Str is adopted!
157 */
pkg_appendToList(CharList * l,CharList ** end,const char * str)158 CharList *pkg_appendToList(CharList *l, CharList** end, const char *str)
159 {
160 CharList *endptr = NULL, *tmp;
161
162 if(end == NULL)
163 {
164 end = &endptr;
165 }
166
167 /* FIND the end */
168 if((*end == NULL) && (l != NULL))
169 {
170 tmp = l;
171 while(tmp->next)
172 {
173 tmp = tmp->next;
174 }
175
176 *end = tmp;
177 }
178
179 /* Create a new empty list and append it */
180 if(l == NULL)
181 {
182 l = pkg_prependToList(NULL, str);
183 }
184 else
185 {
186 (*end)->next = pkg_prependToList(NULL, str);
187 }
188
189 /* Move the end pointer. */
190 if(*end)
191 {
192 (*end) = (*end)->next;
193 }
194 else
195 {
196 *end = l;
197 }
198
199 return l;
200 }
201
convertToNativePathSeparators(char * path)202 char * convertToNativePathSeparators(char *path) {
203 #if defined(U_MAKE_IS_NMAKE)
204 char *itr;
205 while ((itr = uprv_strchr(path, U_FILE_ALT_SEP_CHAR))) {
206 *itr = U_FILE_SEP_CHAR;
207 }
208 #endif
209 return path;
210 }
211
pkg_appendUniqueDirToList(CharList * l,CharList ** end,const char * strAlias)212 CharList *pkg_appendUniqueDirToList(CharList *l, CharList** end, const char *strAlias) {
213 char aBuf[1024];
214 char *rPtr;
215 rPtr = uprv_strrchr(strAlias, U_FILE_SEP_CHAR);
216 #if (U_FILE_SEP_CHAR != U_FILE_ALT_SEP_CHAR)
217 {
218 char *aPtr = uprv_strrchr(strAlias, U_FILE_ALT_SEP_CHAR);
219 if(!rPtr || /* regular char wasn't found or.. */
220 (aPtr && (aPtr > rPtr)))
221 { /* alt ptr exists and is to the right of r ptr */
222 rPtr = aPtr; /* may copy NULL which is OK */
223 }
224 }
225 #endif
226 if(!rPtr) {
227 return l; /* no dir path */
228 }
229 if((rPtr-strAlias) >= UPRV_LENGTHOF(aBuf)) {
230 fprintf(stderr, "## ERR: Path too long [%d chars]: %s\n", (int)sizeof(aBuf), strAlias);
231 return l;
232 }
233 strncpy(aBuf, strAlias,(rPtr-strAlias));
234 aBuf[rPtr-strAlias]=0; /* no trailing slash */
235 convertToNativePathSeparators(aBuf);
236
237 if(!pkg_listContains(l, aBuf)) {
238 return pkg_appendToList(l, end, uprv_strdup(aBuf));
239 } else {
240 return l; /* already found */
241 }
242 }
243
244 #if 0
245 static CharList *
246 pkg_appendFromStrings(CharList *l, CharList** end, const char *s, int32_t len)
247 {
248 CharList *endptr = NULL;
249 const char *p;
250 char *t;
251 const char *targ;
252 if(end == NULL) {
253 end = &endptr;
254 }
255
256 if(len==-1) {
257 len = uprv_strlen(s);
258 }
259 targ = s+len;
260
261 while(*s && s<targ) {
262 while(s<targ&&isspace(*s)) s++;
263 for(p=s;s<targ&&!isspace(*p);p++);
264 if(p!=s) {
265 t = uprv_malloc(p-s+1);
266 uprv_strncpy(t,s,p-s);
267 t[p-s]=0;
268 l=pkg_appendToList(l,end,t);
269 fprintf(stderr, " P %s\n", t);
270 }
271 s=p;
272 }
273
274 return l;
275 }
276 #endif
277
278
279 /*
280 * Delete list
281 */
pkg_deleteList(CharList * l)282 void pkg_deleteList(CharList *l)
283 {
284 CharList *tmp;
285 while(l != NULL)
286 {
287 uprv_free((void*)l->str);
288 tmp = l;
289 l = l->next;
290 uprv_free(tmp);
291 }
292 }
293
pkg_listContains(CharList * l,const char * str)294 UBool pkg_listContains(CharList *l, const char *str)
295 {
296 for(;l;l=l->next){
297 if(!uprv_strcmp(l->str, str)) {
298 return true;
299 }
300 }
301
302 return false;
303 }
304