tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

pkg_icu.cpp (5589B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /******************************************************************************
      4 *   Copyright (C) 2008-2015, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *******************************************************************************
      7 */
      8 #include "unicode/utypes.h"
      9 #include "unicode/localpointer.h"
     10 #include "unicode/putil.h"
     11 #include "cstring.h"
     12 #include "toolutil.h"
     13 #include "uoptions.h"
     14 #include "uparse.h"
     15 #include "package.h"
     16 #include "pkg_icu.h"
     17 
     18 #include <stdio.h>
     19 #include <stdlib.h>
     20 #include <string.h>
     21 
     22 // read a file list -------------------------------------------------------- ***
     23 
     24 U_NAMESPACE_USE
     25 
     26 static const struct {
     27    const char *suffix;
     28    int32_t length;
     29 } listFileSuffixes[]={
     30    { ".txt", 4 },
     31    { ".lst", 4 },
     32    { ".tmp", 4 }
     33 };
     34 
     35 /* check for multiple text file suffixes to see if this list name is a text file name */
     36 static UBool
     37 isListTextFile(const char *listname) {
     38    const char *listNameEnd=strchr(listname, 0);
     39    const char *suffix;
     40    int32_t i, length;
     41    for(i=0; i<UPRV_LENGTHOF(listFileSuffixes); ++i) {
     42        suffix=listFileSuffixes[i].suffix;
     43        length=listFileSuffixes[i].length;
     44        if((listNameEnd-listname)>length && 0==memcmp(listNameEnd-length, suffix, length)) {
     45            return true;
     46        }
     47    }
     48    return false;
     49 }
     50 
     51 /*
     52 * Read a file list.
     53 * If the listname ends with ".txt", then read the list file
     54 * (in the system/ invariant charset).
     55 * If the listname ends with ".dat", then read the ICU .dat package file.
     56 * Otherwise, read the file itself as a single-item list.
     57 */
     58 U_CAPI Package * U_EXPORT2
     59 readList(const char *filesPath, const char *listname, UBool readContents, Package *listPkgIn) {
     60    Package *listPkg = listPkgIn;
     61    FILE *file;
     62    const char *listNameEnd;
     63 
     64    if(listname==nullptr || listname[0]==0) {
     65        fprintf(stderr, "missing list file\n");
     66        return nullptr;
     67    }
     68 
     69    if (listPkg == nullptr) {
     70        listPkg=new Package();
     71        if(listPkg==nullptr) {
     72            fprintf(stderr, "icupkg: not enough memory\n");
     73            exit(U_MEMORY_ALLOCATION_ERROR);
     74        }
     75    }
     76 
     77    listNameEnd=strchr(listname, 0);
     78    if(isListTextFile(listname)) {
     79        // read the list file
     80        char line[1024];
     81        char *end;
     82        const char *start;
     83 
     84        file=fopen(listname, "r");
     85        if(file==nullptr) {
     86            fprintf(stderr, "icupkg: unable to open list file \"%s\"\n", listname);
     87            delete listPkg;
     88            exit(U_FILE_ACCESS_ERROR);
     89        }
     90 
     91        while(fgets(line, sizeof(line), file)) {
     92            // remove comments
     93            end=strchr(line, '#');
     94            if(end!=nullptr) {
     95                *end=0;
     96            } else {
     97                // remove trailing CR LF
     98                end=strchr(line, 0);
     99                while(line<end && (*(end-1)=='\r' || *(end-1)=='\n')) {
    100                    *--end=0;
    101                }
    102            }
    103 
    104            // check first non-whitespace character and
    105            // skip empty lines and
    106            // skip lines starting with reserved characters
    107            start=u_skipWhitespace(line);
    108            if(*start==0 || nullptr!=strchr(U_PKG_RESERVED_CHARS, *start)) {
    109                continue;
    110            }
    111 
    112            // take whitespace-separated items from the line
    113            for(;;) {
    114                // find whitespace after the item or the end of the line
    115                for(end=(char *)start; *end!=0 && *end!=' ' && *end!='\t'; ++end) {}
    116                if(*end==0) {
    117                    // this item is the last one on the line
    118                    end=nullptr;
    119                } else {
    120                    // the item is terminated by whitespace, terminate it with NUL
    121                    *end=0;
    122                }
    123                if(readContents) {
    124                    listPkg->addFile(filesPath, start);
    125                } else {
    126                    listPkg->addItem(start);
    127                }
    128 
    129                // find the start of the next item or exit the loop
    130                if(end==nullptr || *(start=u_skipWhitespace(end+1))==0) {
    131                    break;
    132                }
    133            }
    134        }
    135        fclose(file);
    136    } else if((listNameEnd-listname)>4 && 0==memcmp(listNameEnd-4, ".dat", 4)) {
    137        // read the ICU .dat package
    138        // Accept a .dat file whose name differs from the ToC prefixes.
    139        listPkg->setAutoPrefix();
    140        listPkg->readPackage(listname);
    141    } else {
    142        // list the single file itself
    143        if(readContents) {
    144            listPkg->addFile(filesPath, listname);
    145        } else {
    146            listPkg->addItem(listname);
    147        }
    148    }
    149 
    150    return listPkg;
    151 }
    152 
    153 U_CAPI int U_EXPORT2
    154 writePackageDatFile(const char *outFilename, const char *outComment, const char *sourcePath, const char *addList, Package *pkg, char outType) {
    155    LocalPointer<Package> ownedPkg;
    156    LocalPointer<Package> addListPkg;
    157 
    158    if (pkg == nullptr) {
    159        ownedPkg.adoptInstead(new Package);
    160        if(ownedPkg.isNull()) {
    161            fprintf(stderr, "icupkg: not enough memory\n");
    162            return U_MEMORY_ALLOCATION_ERROR;
    163        }
    164        pkg = ownedPkg.getAlias();
    165 
    166        addListPkg.adoptInstead(readList(sourcePath, addList, true, nullptr));
    167        if(addListPkg.isValid()) {
    168            pkg->addItems(*addListPkg);
    169        } else {
    170            return U_ILLEGAL_ARGUMENT_ERROR;
    171        }
    172    }
    173 
    174    pkg->writePackage(outFilename, outType, outComment);
    175    return 0;
    176 }