OSDN Git Service

AI003:AI_Think_CandidateWordList_Filter()は実装途中。
[chnosproject/CHNOSProject.git] / CHNOSProject / chn / chnlib01.c
1 //\r
2 //  chnlib01.c\r
3 //  AI003\r
4 //\r
5 //  Created by 西田 耀 on 13/02/03.\r
6 //  Copyright (c) 2013年 Hikaru Nishida. All rights reserved.\r
7 //\r
8 \r
9 //String関連のうち、このソースファイルで完結する関数群\r
10 \r
11 //\r
12 //Include headers\r
13 //\r
14 \r
15 #include <stdio.h>\r
16 #include <stdlib.h>\r
17 #include <string.h>\r
18 #include "chnlib.h"\r
19 \r
20 //\r
21 //Define values\r
22 //\r
23 \r
24 //\r
25 //Define static values\r
26 //\r
27 char *CHNLIB_String_Intenal_NullCString = "";\r
28 \r
29 //\r
30 //Declare internal functions\r
31 //\r
32 \r
33 CHNLIB_String *CHNLIB_String_Internal_Allocate(void);\r
34 \r
35 //\r
36 //Define types\r
37 //\r
38 \r
39 struct CHNLIB_STRING {\r
40     //文字列を保持する\r
41     CHNLIB_StructureHeader header;\r
42     char *str;\r
43 };\r
44 \r
45 //\r
46 //Functions(CHNLIB_String)\r
47 //\r
48 \r
49 CHNLIB_String *CHNLIB_String_Initialize(const char str[])\r
50 {\r
51     //指定された引数strと等価なStringを確保し返す。\r
52     //str==NULLの時は、NULLポインタへの参照を持つStringを返す。\r
53     CHNLIB_String *strtag;\r
54     \r
55     strtag = CHNLIB_String_Internal_Allocate();\r
56     \r
57     if(str != NULL){\r
58         CHNLIB_String_SetStringFromCString(strtag, str);\r
59     }\r
60     return strtag;\r
61 }\r
62 \r
63 void CHNLIB_String_Free(CHNLIB_String *strtag)\r
64 {\r
65     //strtagを解放する。\r
66     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
67         return;\r
68     }\r
69     \r
70     if(strtag->str != NULL){\r
71         CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);\r
72     }\r
73     strtag->header.typeid = CHNLIB_STRUCT_ID_Null;\r
74     strtag->header.signature = 0;\r
75     CHNLIB_System_FreeMemory(strtag, CHNLIB_DEBUG_ARGUMENTS);\r
76     \r
77     return;\r
78 }\r
79 \r
80 int CHNLIB_String_SetStringFromCString(CHNLIB_String *strtag, const char s[])\r
81 {\r
82     //strtagにsと等価な文字列を代入する。\r
83     //strtag==Invalid || s==NULLのときは何もしない。\r
84     int i, size;\r
85     \r
86     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
87         return 0;\r
88     }\r
89     \r
90     if(s == NULL){\r
91         return 0;\r
92     }\r
93     \r
94     size = CHNLIB_CString_GetByteLength(s) + 1;\r
95     if(strtag->str != NULL){\r
96         CHNLIB_System_FreeMemory(strtag->str, CHNLIB_DEBUG_ARGUMENTS);\r
97     }\r
98     strtag->str = CHNLIB_System_AllocateMemory_Strict(size, CHNLIB_DEBUG_ARGUMENTS);\r
99     for(i = 0; i < size - 1; i++){\r
100         strtag->str[i] = s[i];\r
101     }\r
102     strtag->str[i] = '\0';\r
103     return size;\r
104 }\r
105 \r
106 int CHNLIB_String_Print(CHNLIB_String *strtag)\r
107 {\r
108     //strtagが格納している文字列を標準出力に出力する。\r
109     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
110         return 0;\r
111     }\r
112     if(strtag->str == NULL){\r
113         return 0;\r
114     }\r
115     \r
116     return fputs(strtag->str, stdout);\r
117 }\r
118 \r
119 const char *CHNLIB_String_GetReferencePointerOfCString(const CHNLIB_String *strtag)\r
120 {\r
121     //strtagが格納している文字列へのポインタを返す。\r
122     //strtag->str==NULLの場合、constな空文字へのポインタを返す。\r
123     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
124         return NULL;\r
125     }\r
126     \r
127     if(strtag->str == NULL){\r
128         return CHNLIB_String_Intenal_NullCString;\r
129     }\r
130     \r
131     return (const char *)strtag->str;\r
132 }\r
133 \r
134 CHNLIB_String *CHNLIB_String_ExtractByLength(const CHNLIB_String *strtag, int start, int len)\r
135 {\r
136     //strtagが格納している文字列sについて、\r
137     //s[start]からs[start + len - 1]の文字を含む文字列と等価なStringを確保し返す。\r
138     //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。\r
139     //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。\r
140     char *retstr;\r
141     CHNLIB_String *retstrtag;\r
142     \r
143     retstr = CHNLIB_CString_ExtractByLength(strtag->str, start, len);\r
144     \r
145     if(retstr == NULL){\r
146         return NULL;\r
147     }\r
148     \r
149     retstrtag = CHNLIB_String_Initialize(NULL);\r
150     retstrtag->str = retstr;\r
151     \r
152     return retstrtag;\r
153 }\r
154 \r
155 int CHNLIB_String_GetLength(const CHNLIB_String *strtag)\r
156 {\r
157     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
158         return 0;\r
159     }\r
160     \r
161     return CHNLIB_CString_GetByteLength(strtag->str);\r
162 }\r
163 \r
164 void CHNLIB_String_DeleteLastCRLF(CHNLIB_String *strtag)\r
165 {\r
166     if(CHNLIB_StructureHeader_GetTypeID(strtag) != CHNLIB_STRUCT_ID_String){\r
167         return;\r
168     }\r
169     \r
170     CHNLIB_CString_DeleteLastCRLF(strtag->str);\r
171     \r
172     return;\r
173 }\r
174 \r
175 int CHNLIB_String_CompareStringWithCString(const CHNLIB_String *s, const char search[])\r
176 {\r
177     return CHNLIB_CString_CompareString(CHNLIB_String_GetReferencePointerOfCString(s), search);\r
178 }\r
179 \r
180 int CHNLIB_String_CompareString_Strict(const CHNLIB_String *s, const CHNLIB_String *search)\r
181 {\r
182     return CHNLIB_CString_CompareString_Strict(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));\r
183 }\r
184 \r
185 uint CHNLIB_String_GetCountOfContain(const CHNLIB_String *s, const CHNLIB_String *search)\r
186 {\r
187     return CHNLIB_UTF8_GetCountOfContain(CHNLIB_String_GetReferencePointerOfCString(s), CHNLIB_String_GetReferencePointerOfCString(search));\r
188 }\r
189 \r
190 //\r
191 //Functions(CString(char[]))\r
192 //\r
193 \r
194 int CHNLIB_CString_GetByteLength(const char s[])\r
195 {\r
196     //[CString]\r
197     //終端文字を除いた、文字列本体のバイト数を返す。\r
198     int i;\r
199     \r
200     if(s == NULL){\r
201         return 0;\r
202     }\r
203     \r
204     for(i = 0; s[i] != 0x00; i++){\r
205         \r
206     }\r
207     \r
208     return i;\r
209 }\r
210 \r
211 void CHNLIB_CString_DeleteLastCRLF(char s[])\r
212 {\r
213     //末尾のLF, CR/LFを\0に置換する\r
214     int i, crlf;\r
215     \r
216     if(s == NULL){\r
217         return;\r
218     }\r
219     \r
220     crlf = -1;\r
221     for(i = 0; s[i] != '\0'; i++){\r
222         if(s[i] == '\n'){\r
223             if(crlf == -1 || crlf + 1 != i){\r
224                 crlf = i;\r
225             }\r
226         }\r
227         if(s[i] == '\r'){\r
228             if(crlf == -1 || crlf + 1 != i){\r
229                 crlf = i;\r
230             }\r
231         }\r
232     }\r
233     if(crlf != -1){\r
234         for(i = crlf; s[i] != '\0'; i++){\r
235             s[i] = '\0';\r
236         }\r
237     }\r
238     return;\r
239 }\r
240 \r
241 char *CHNLIB_CString_ExtractByLength(const char s[], int start, int len)\r
242 {\r
243     //s[start]からs[start + len - 1]の文字を含む文字列を、新たにメモリを確保して書き込み、その先頭アドレスを返す。\r
244     //lenに満たずにsが終端文字を迎えた場合は、sの終端文字直前までの文字列がコピーされる。\r
245     //(len < 0)のときは、NULLを返す。また、結果として(len < 0)となった時も同様にNULLを返す。\r
246     char *str;\r
247     int i;\r
248     int utf8type;\r
249     \r
250     if(s == NULL){\r
251         CHNLIB_ReportError("Null s[]\n", CHNLIB_DEBUG_ARGUMENTS);\r
252         return NULL;\r
253     }\r
254     \r
255     i = CHNLIB_CString_GetByteLength(s) + 1;\r
256     \r
257     if(i > (len + 1)){\r
258         i = len + 1;\r
259     }\r
260     \r
261     if(len == 0){\r
262         return NULL;\r
263     }\r
264     \r
265     str = CHNLIB_System_AllocateMemory_Strict(i, CHNLIB_DEBUG_ARGUMENTS);\r
266 \r
267     for(i = 0; s[i + start] != '\0'; i++){\r
268         if(len <= 0){\r
269             break;\r
270         }\r
271         //**UTF-8\r
272         utf8type = CHNLIB_UTF8_GetCharacterType(s[i + start]);\r
273         if(len < utf8type){\r
274             break;\r
275         }\r
276         //****\r
277         len--;\r
278         str[i] = s[i + start];\r
279     }\r
280     str[i] = '\0';\r
281     \r
282     return str;\r
283 }\r
284 \r
285 int CHNLIB_CString_CompareString(const char s[], const char search[])\r
286 {\r
287     //s[]の先頭からsearch[]と比較し、searchの終端まで一致したらTrue, 一致しなかったらFalseを返す。\r
288     //終端文字'\0'はカウントしない。\r
289     //search[]に含まれる文字(終端文字除く)がすべて入っていれば一致とみなす。\r
290     int i;\r
291     \r
292     if(s == NULL || search == NULL){\r
293         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
294         return False;\r
295     }\r
296     \r
297     for(i = 0; search[i] != '\0'; i++){\r
298         if(s[i] != search[i]){\r
299             return False;\r
300         }\r
301     }\r
302     return True;\r
303 }\r
304 \r
305 int CHNLIB_CString_CompareString_Strict(const char s[], const char search[])\r
306 {\r
307     //二つの文字列が終端文字までを含めて完全に一致するかどうか調べる。一致していればTrueを返す。\r
308     //StrictよりExactの方が適する?<関数名\r
309     int i;\r
310     \r
311     if(s == NULL || search == NULL){\r
312         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
313         return False;\r
314     }\r
315     \r
316     for(i = 0; search[i] != '\0'; i++){\r
317         if(s[i] != search[i]){\r
318             return False;\r
319         }\r
320     }\r
321     if(s[i] != '\0'){\r
322         return False;\r
323     }\r
324     return True;\r
325 }\r
326 \r
327 int CHNLIB_CString_CompareString_LeftHand(const char s[], const char search[])\r
328 {\r
329     //二つの文字列がどの程度一致するか調べる。前方一致。\r
330     //戻り値は、終端文字を除く、同一だったバイト数。\r
331     int i;\r
332     \r
333     if(s == NULL || search == NULL){\r
334         CHNLIB_ReportError("Null str.\n", CHNLIB_DEBUG_ARGUMENTS);\r
335         return 0;\r
336     }\r
337     \r
338     for(i = 0; search[i] != '\0'; i++){\r
339         if(s[i] != search[i]){\r
340             break;\r
341         }\r
342     }\r
343 \r
344     return i;\r
345 }\r
346     \r
347 //\r
348 //Internal functions\r
349 //\r
350 \r
351 CHNLIB_String *CHNLIB_String_Internal_Allocate(void)\r
352 {\r
353     CHNLIB_String *tag;\r
354     \r
355     tag = (CHNLIB_String *)CHNLIB_System_AllocateMemory_Strict(sizeof(CHNLIB_String), CHNLIB_DEBUG_ARGUMENTS);\r
356     \r
357     CHNLIB_StructureHeader_Initialize(&tag->header, CHNLIB_STRUCT_ID_String);\r
358     \r
359     return tag;\r
360 }