code cleanup
[TortoiseGit.git] / ext / hunspell / dictmgr.cxx
blobd5b2cb3a3c27406b3a616b2c3127d479e484b228
2 #include <cstdlib>
3 #include <cstring>
4 #include <cctype>
5 #include <cstdio>
7 #include "dictmgr.hxx"
9 using namespace std;
11 DictMgr::DictMgr(const char * dictpath, const char * etype)
13 // load list of etype entries
14 numdict = 0;
15 pdentry = (dictentry *)malloc(MAXDICTIONARIES*sizeof(struct dictentry));
16 if (pdentry) {
17 if (parse_file(dictpath, etype)) {
18 numdict = 0;
19 // no dictionary.lst found is okay
21 } else {
22 numdict = 0;
27 DictMgr::~DictMgr()
29 dictentry * pdict = NULL;
30 if (pdentry) {
31 pdict = pdentry;
32 for (int i=0;i<numdict;i++) {
33 if (pdict->lang) {
34 free(pdict->lang);
35 pdict->lang = NULL;
37 if (pdict->region) {
38 free(pdict->region);
39 pdict->region=NULL;
41 if (pdict->filename) {
42 free(pdict->filename);
43 pdict->filename = NULL;
45 pdict++;
47 free(pdentry);
48 pdentry = NULL;
49 pdict = NULL;
51 numdict = 0;
55 // read in list of etype entries and build up structure to describe them
56 int DictMgr::parse_file(const char * dictpath, const char * etype)
59 int i;
60 char line[MAXDICTENTRYLEN+1];
61 dictentry * pdict = pdentry;
63 // open the dictionary list file
64 FILE * dictlst;
65 dictlst = fopen(dictpath,"r");
66 if (!dictlst) {
67 return 1;
70 // step one is to parse the dictionary list building up the
71 // descriptive structures
73 // read in each line ignoring any that dont start with etype
74 while (fgets(line,MAXDICTENTRYLEN,dictlst)) {
75 mychomp(line);
77 /* parse in a dictionary entry */
78 if (strncmp(line,etype,4) == 0) {
79 if (numdict < MAXDICTIONARIES) {
80 char * tp = line;
81 char * piece;
82 i = 0;
83 while ((piece=mystrsep(&tp,' '))) {
84 if (*piece != '\0') {
85 switch(i) {
86 case 0: break;
87 case 1: pdict->lang = mystrdup(piece); break;
88 case 2: if (strcmp (piece, "ANY") == 0)
89 pdict->region = mystrdup("");
90 else
91 pdict->region = mystrdup(piece);
92 break;
93 case 3: pdict->filename = mystrdup(piece); break;
94 default: break;
96 i++;
98 free(piece);
100 if (i == 4) {
101 numdict++;
102 pdict++;
103 } else {
104 fprintf(stderr,"dictionary list corruption in line \"%s\"\n",line);
105 fflush(stderr);
110 fclose(dictlst);
111 return 0;
114 // return text encoding of dictionary
115 int DictMgr::get_list(dictentry ** ppentry)
117 *ppentry = pdentry;
118 return numdict;
123 // strip strings into token based on single char delimiter
124 // acts like strsep() but only uses a delim char and not
125 // a delim string
127 char * DictMgr::mystrsep(char ** stringp, const char delim)
129 char * rv = NULL;
130 char * mp = *stringp;
131 int n = strlen(mp);
132 if (n > 0) {
133 char * dp = (char *)memchr(mp,(int)((unsigned char)delim),n);
134 if (dp) {
135 *stringp = dp+1;
136 int nc = (int)((unsigned long)dp - (unsigned long)mp);
137 rv = (char *) malloc(nc+1);
138 memcpy(rv,mp,nc);
139 *(rv+nc) = '\0';
140 return rv;
141 } else {
142 rv = (char *) malloc(n+1);
143 memcpy(rv, mp, n);
144 *(rv+n) = '\0';
145 *stringp = mp + n;
146 return rv;
149 return NULL;
153 // replaces strdup with ansi version
154 char * DictMgr::mystrdup(const char * s)
156 char * d = NULL;
157 if (s) {
158 int sl = strlen(s);
159 d = (char *) malloc(((sl+1) * sizeof(char)));
160 if (d) memcpy(d,s,((sl+1)*sizeof(char)));
162 return d;
166 // remove cross-platform text line end characters
167 void DictMgr:: mychomp(char * s)
169 int k = strlen(s);
170 if ((k > 0) && ((*(s+k-1)=='\r') || (*(s+k-1)=='\n'))) *(s+k-1) = '\0';
171 if ((k > 1) && (*(s+k-2) == '\r')) *(s+k-2) = '\0';