OSDN Git Service

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