130660a898545416f0fea2d717f16f75640001e38Ted Kremenek/****************************************************************************** 230660a898545416f0fea2d717f16f75640001e38Ted Kremenek * Copyright (C) 2008-2013, International Business Machines 330660a898545416f0fea2d717f16f75640001e38Ted Kremenek * Corporation and others. All Rights Reserved. 430660a898545416f0fea2d717f16f75640001e38Ted Kremenek ******************************************************************************* 530660a898545416f0fea2d717f16f75640001e38Ted Kremenek */ 630660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "unicode/utypes.h" 730660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "unicode/putil.h" 830660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "cstring.h" 930660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "toolutil.h" 1030660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "uoptions.h" 1155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "uparse.h" 1230660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "package.h" 1330660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include "pkg_icu.h" 1430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 1530660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include <stdio.h> 1630660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include <stdlib.h> 1730660a898545416f0fea2d717f16f75640001e38Ted Kremenek#include <string.h> 1830660a898545416f0fea2d717f16f75640001e38Ted Kremenek 1930660a898545416f0fea2d717f16f75640001e38Ted Kremenek 2030660a898545416f0fea2d717f16f75640001e38Ted Kremenek#define LENGTHOF(array) (int32_t)(sizeof(array)/sizeof((array)[0])) 2130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 2230660a898545416f0fea2d717f16f75640001e38Ted Kremenek// read a file list -------------------------------------------------------- *** 2330660a898545416f0fea2d717f16f75640001e38Ted Kremenek 2430660a898545416f0fea2d717f16f75640001e38Ted KremenekU_NAMESPACE_USE 2530660a898545416f0fea2d717f16f75640001e38Ted Kremenek 2630660a898545416f0fea2d717f16f75640001e38Ted Kremenekstatic const struct { 2730660a898545416f0fea2d717f16f75640001e38Ted Kremenek const char *suffix; 2830660a898545416f0fea2d717f16f75640001e38Ted Kremenek int32_t length; 2930660a898545416f0fea2d717f16f75640001e38Ted Kremenek} listFileSuffixes[]={ 3030660a898545416f0fea2d717f16f75640001e38Ted Kremenek { ".txt", 4 }, 3130660a898545416f0fea2d717f16f75640001e38Ted Kremenek { ".lst", 4 }, 3230660a898545416f0fea2d717f16f75640001e38Ted Kremenek { ".tmp", 4 } 3330660a898545416f0fea2d717f16f75640001e38Ted Kremenek}; 3430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 3530660a898545416f0fea2d717f16f75640001e38Ted Kremenek/* check for multiple text file suffixes to see if this list name is a text file name */ 3630660a898545416f0fea2d717f16f75640001e38Ted Kremenekstatic UBool 3730660a898545416f0fea2d717f16f75640001e38Ted KremenekisListTextFile(const char *listname) { 3830660a898545416f0fea2d717f16f75640001e38Ted Kremenek const char *listNameEnd=strchr(listname, 0); 3930660a898545416f0fea2d717f16f75640001e38Ted Kremenek const char *suffix; 4030660a898545416f0fea2d717f16f75640001e38Ted Kremenek int32_t i, length; 4130660a898545416f0fea2d717f16f75640001e38Ted Kremenek for(i=0; i<LENGTHOF(listFileSuffixes); ++i) { 4230660a898545416f0fea2d717f16f75640001e38Ted Kremenek suffix=listFileSuffixes[i].suffix; 4330660a898545416f0fea2d717f16f75640001e38Ted Kremenek length=listFileSuffixes[i].length; 4430660a898545416f0fea2d717f16f75640001e38Ted Kremenek if((listNameEnd-listname)>length && 0==memcmp(listNameEnd-length, suffix, length)) { 4530660a898545416f0fea2d717f16f75640001e38Ted Kremenek return TRUE; 4630660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 4730660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 4830660a898545416f0fea2d717f16f75640001e38Ted Kremenek return FALSE; 4930660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 5030660a898545416f0fea2d717f16f75640001e38Ted Kremenek 5130660a898545416f0fea2d717f16f75640001e38Ted Kremenek/* 5230660a898545416f0fea2d717f16f75640001e38Ted Kremenek * Read a file list. 5330660a898545416f0fea2d717f16f75640001e38Ted Kremenek * If the listname ends with ".txt", then read the list file 5430660a898545416f0fea2d717f16f75640001e38Ted Kremenek * (in the system/ invariant charset). 5530660a898545416f0fea2d717f16f75640001e38Ted Kremenek * If the listname ends with ".dat", then read the ICU .dat package file. 5630660a898545416f0fea2d717f16f75640001e38Ted Kremenek * Otherwise, read the file itself as a single-item list. 5730660a898545416f0fea2d717f16f75640001e38Ted Kremenek */ 5830660a898545416f0fea2d717f16f75640001e38Ted KremenekU_CAPI Package * U_EXPORT2 5930660a898545416f0fea2d717f16f75640001e38Ted KremenekreadList(const char *filesPath, const char *listname, UBool readContents, Package *listPkgIn) { 6030660a898545416f0fea2d717f16f75640001e38Ted Kremenek Package *listPkg = listPkgIn; 6130660a898545416f0fea2d717f16f75640001e38Ted Kremenek FILE *file; 6230660a898545416f0fea2d717f16f75640001e38Ted Kremenek const char *listNameEnd; 6330660a898545416f0fea2d717f16f75640001e38Ted Kremenek 6430660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(listname==NULL || listname[0]==0) { 6530660a898545416f0fea2d717f16f75640001e38Ted Kremenek fprintf(stderr, "missing list file\n"); 6630660a898545416f0fea2d717f16f75640001e38Ted Kremenek return NULL; 6730660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 6830660a898545416f0fea2d717f16f75640001e38Ted Kremenek 6930660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (listPkg == NULL) { 7030660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg=new Package(); 7130660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(listPkg==NULL) { 7230660a898545416f0fea2d717f16f75640001e38Ted Kremenek fprintf(stderr, "icupkg: not enough memory\n"); 7330660a898545416f0fea2d717f16f75640001e38Ted Kremenek exit(U_MEMORY_ALLOCATION_ERROR); 7430660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 7530660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 7630660a898545416f0fea2d717f16f75640001e38Ted Kremenek 7730660a898545416f0fea2d717f16f75640001e38Ted Kremenek listNameEnd=strchr(listname, 0); 7830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(isListTextFile(listname)) { 7930660a898545416f0fea2d717f16f75640001e38Ted Kremenek // read the list file 8030660a898545416f0fea2d717f16f75640001e38Ted Kremenek char line[1024]; 8130660a898545416f0fea2d717f16f75640001e38Ted Kremenek char *end; 8230660a898545416f0fea2d717f16f75640001e38Ted Kremenek const char *start; 8330660a898545416f0fea2d717f16f75640001e38Ted Kremenek 8430660a898545416f0fea2d717f16f75640001e38Ted Kremenek file=fopen(listname, "r"); 8530660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(file==NULL) { 8630660a898545416f0fea2d717f16f75640001e38Ted Kremenek fprintf(stderr, "icupkg: unable to open list file \"%s\"\n", listname); 8730660a898545416f0fea2d717f16f75640001e38Ted Kremenek delete listPkg; 8830660a898545416f0fea2d717f16f75640001e38Ted Kremenek exit(U_FILE_ACCESS_ERROR); 8930660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 9030660a898545416f0fea2d717f16f75640001e38Ted Kremenek 9130660a898545416f0fea2d717f16f75640001e38Ted Kremenek while(fgets(line, sizeof(line), file)) { 9230660a898545416f0fea2d717f16f75640001e38Ted Kremenek // remove comments 9330660a898545416f0fea2d717f16f75640001e38Ted Kremenek end=strchr(line, '#'); 9430660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(end!=NULL) { 9530660a898545416f0fea2d717f16f75640001e38Ted Kremenek *end=0; 9630660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 9730660a898545416f0fea2d717f16f75640001e38Ted Kremenek // remove trailing CR LF 9830660a898545416f0fea2d717f16f75640001e38Ted Kremenek end=strchr(line, 0); 9930660a898545416f0fea2d717f16f75640001e38Ted Kremenek while(line<end && (*(end-1)=='\r' || *(end-1)=='\n')) { 10030660a898545416f0fea2d717f16f75640001e38Ted Kremenek *--end=0; 10130660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 10230660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 103055b395294d190a432e9d87bb665634636a1418aArgyrios Kyrtzidis 104055b395294d190a432e9d87bb665634636a1418aArgyrios Kyrtzidis // check first non-whitespace character and 105055b395294d190a432e9d87bb665634636a1418aArgyrios Kyrtzidis // skip empty lines and 10630660a898545416f0fea2d717f16f75640001e38Ted Kremenek // skip lines starting with reserved characters 107055b395294d190a432e9d87bb665634636a1418aArgyrios Kyrtzidis start=u_skipWhitespace(line); 10830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(*start==0 || NULL!=strchr(U_PKG_RESERVED_CHARS, *start)) { 10930660a898545416f0fea2d717f16f75640001e38Ted Kremenek continue; 11030660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 11130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 11230660a898545416f0fea2d717f16f75640001e38Ted Kremenek // take whitespace-separated items from the line 11330660a898545416f0fea2d717f16f75640001e38Ted Kremenek for(;;) { 11430660a898545416f0fea2d717f16f75640001e38Ted Kremenek // find whitespace after the item or the end of the line 11530660a898545416f0fea2d717f16f75640001e38Ted Kremenek for(end=(char *)start; *end!=0 && *end!=' ' && *end!='\t'; ++end) {} 11630660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(*end==0) { 11730660a898545416f0fea2d717f16f75640001e38Ted Kremenek // this item is the last one on the line 11830660a898545416f0fea2d717f16f75640001e38Ted Kremenek end=NULL; 11930660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 12030660a898545416f0fea2d717f16f75640001e38Ted Kremenek // the item is terminated by whitespace, terminate it with NUL 12130660a898545416f0fea2d717f16f75640001e38Ted Kremenek *end=0; 12230660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 12330660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(readContents) { 12430660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->addFile(filesPath, start); 12530660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 12630660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->addItem(start); 12730660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 12830660a898545416f0fea2d717f16f75640001e38Ted Kremenek 12930660a898545416f0fea2d717f16f75640001e38Ted Kremenek // find the start of the next item or exit the loop 13030660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(end==NULL || *(start=u_skipWhitespace(end+1))==0) { 13130660a898545416f0fea2d717f16f75640001e38Ted Kremenek break; 13230660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 13330660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 13430660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 13530660a898545416f0fea2d717f16f75640001e38Ted Kremenek fclose(file); 13630660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else if((listNameEnd-listname)>4 && 0==memcmp(listNameEnd-4, ".dat", 4)) { 13730660a898545416f0fea2d717f16f75640001e38Ted Kremenek // read the ICU .dat package 13830660a898545416f0fea2d717f16f75640001e38Ted Kremenek // Accept a .dat file whose name differs from the ToC prefixes. 13930660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->setAutoPrefix(); 14030660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->readPackage(listname); 14130660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 14230660a898545416f0fea2d717f16f75640001e38Ted Kremenek // list the single file itself 14330660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(readContents) { 14430660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->addFile(filesPath, listname); 14530660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 14630660a898545416f0fea2d717f16f75640001e38Ted Kremenek listPkg->addItem(listname); 14730660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 14830660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 14930660a898545416f0fea2d717f16f75640001e38Ted Kremenek 15030660a898545416f0fea2d717f16f75640001e38Ted Kremenek return listPkg; 15130660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 15230660a898545416f0fea2d717f16f75640001e38Ted Kremenek 15330660a898545416f0fea2d717f16f75640001e38Ted KremenekU_CAPI int U_EXPORT2 15430660a898545416f0fea2d717f16f75640001e38Ted KremenekwritePackageDatFile(const char *outFilename, const char *outComment, const char *sourcePath, const char *addList, Package *pkg, char outType) { 15530660a898545416f0fea2d717f16f75640001e38Ted Kremenek Package *addListPkg = NULL; 15630660a898545416f0fea2d717f16f75640001e38Ted Kremenek UBool pkgDelete = FALSE; 15730660a898545416f0fea2d717f16f75640001e38Ted Kremenek 15830660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (pkg == NULL) { 15930660a898545416f0fea2d717f16f75640001e38Ted Kremenek pkg = new Package; 16030660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(pkg == NULL) { 16130660a898545416f0fea2d717f16f75640001e38Ted Kremenek fprintf(stderr, "icupkg: not enough memory\n"); 16230660a898545416f0fea2d717f16f75640001e38Ted Kremenek return U_MEMORY_ALLOCATION_ERROR; 16330660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 16430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 16530660a898545416f0fea2d717f16f75640001e38Ted Kremenek addListPkg = readList(sourcePath, addList, TRUE, NULL); 16630660a898545416f0fea2d717f16f75640001e38Ted Kremenek if(addListPkg != NULL) { 16730660a898545416f0fea2d717f16f75640001e38Ted Kremenek pkg->addItems(*addListPkg); 16830660a898545416f0fea2d717f16f75640001e38Ted Kremenek } else { 16930660a898545416f0fea2d717f16f75640001e38Ted Kremenek return U_ILLEGAL_ARGUMENT_ERROR; 17030660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 17130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 17230660a898545416f0fea2d717f16f75640001e38Ted Kremenek pkgDelete = TRUE; 17330660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 17430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 17530660a898545416f0fea2d717f16f75640001e38Ted Kremenek pkg->writePackage(outFilename, outType, outComment); 17630660a898545416f0fea2d717f16f75640001e38Ted Kremenek 17730660a898545416f0fea2d717f16f75640001e38Ted Kremenek if (pkgDelete) { 17830660a898545416f0fea2d717f16f75640001e38Ted Kremenek delete pkg; 17930660a898545416f0fea2d717f16f75640001e38Ted Kremenek delete addListPkg; 18030660a898545416f0fea2d717f16f75640001e38Ted Kremenek } 18130660a898545416f0fea2d717f16f75640001e38Ted Kremenek 18230660a898545416f0fea2d717f16f75640001e38Ted Kremenek return 0; 18330660a898545416f0fea2d717f16f75640001e38Ted Kremenek} 18430660a898545416f0fea2d717f16f75640001e38Ted Kremenek 18530660a898545416f0fea2d717f16f75640001e38Ted Kremenek