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