pkgtypes.c revision c73f511526464f8e56c242df80552e9b0d94ae3d
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
27const 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
73const 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 */
120uint32_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 */
135CharList *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 */
155CharList *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
199char * 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
209CharList *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
242static CharList *
243pkg_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 */
279void 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
291UBool  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