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