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 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 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 */ 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 */ 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 */ 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 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 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 */ 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 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