OSDN Git Service

(none)
[hos/hos-v4a.git] / cfgrtr / source / analyze.cpp
1 // ---------------------------------------------------------------------------
2 //  Hyper Operating System V4  コンフィギュレーター                           
3 //    構文解析クラス                                                          
4 //                                                                            
5 //                                    Copyright (C) 1998-2002 by Project HOS  
6 //                                    http://sourceforge.jp/projects/hos/     
7 // ---------------------------------------------------------------------------
8
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 #include "defercd.h"
14 #include "analyze.h"
15
16
17
18 // ステートメントをAPI名とパラメーターに分割
19 int CAnalyze::SplitState(char* pszApiName, char* pszParams, const char *pszState)
20 {
21         int iErr;
22
23         // コマンド名の切り出し
24         while ( *pszState != '(' )
25         {
26                 if ( *pszState == '\0' )
27                 {
28                         return CFG_ERR_SYNTAX;
29                 }
30                 *pszApiName++ = *pszState++;
31         }
32         *pszApiName = '\0';
33         pszState++;
34
35         // パラメーター部の切り出し
36         iErr = SearchChar(pszParams, pszState, ')');
37         if ( iErr != CFG_ERR_OK )
38         {
39                 return iErr;
40         }
41
42         // 後続チェック
43         if ( *pszState != '\0' )
44         {
45                 return CFG_ERR_SEMICOLON;
46         }
47
48         return CFG_ERR_OK;
49 }
50
51
52 // 特定文字のまでの切り出し
53 int CAnalyze::SearchChar(char* pszBuf, const char* &pszText, char c)
54 {
55         char cDelimiter = 0;
56         bool blText = false;
57         bool blEsc  = false;
58         int  iErr;
59
60         for ( ; ; )
61         {
62                 // 終端チェック
63                 if ( *pszText == '\0' )
64                 {
65                         iErr = CFG_ERR_SYNTAX;
66                         break;
67                 }
68
69                 // 文字チェック
70                 if ( *pszText == c )
71                 {
72                         pszText++;
73                         iErr = CFG_ERR_OK;
74                         break;
75                 }
76
77                 // '\' の次の文字は無条件にエスケープ
78                 if ( blEsc )
79                 {
80                         *pszBuf++ = *pszText++;
81                         blEsc = false;
82                         continue;
83                 }
84                 blEsc = false;
85
86                 // '\' チェック
87                 if ( *pszBuf == '\\' )
88                 {
89                         *pszBuf++ = *pszText++;
90                         blEsc = true;
91                         continue;
92                 }
93
94                 // 文字列開始チェック
95                 if ( !blText && *pszText == '\"' || *pszText == '\'' )
96                 {
97                         cDelimiter = *pszText;
98                         *pszBuf++ = *pszText++;
99                         blText = true;
100                         continue;
101                 }
102
103                 // 文字列内部
104                 if ( blText )
105                 {
106                         if ( *pszText == cDelimiter )
107                         {
108                                 *pszBuf++ = *pszText++;
109                                 blText = false;
110                         }
111                         else
112                         {
113                                 *pszBuf++ = *pszText++;
114                         }
115                         continue;
116                 }
117
118                 // '{' チェック
119                 if ( *pszText == '{' )
120                 {
121                         *pszBuf++ = *pszText++;
122                         iErr = SearchChar(pszBuf, pszText, '}');
123                         if ( iErr != CFG_ERR_OK )
124                         {
125                                 iErr = CFG_ERR_BRACE;
126                         }
127                         pszBuf  += strlen(pszBuf);
128                         *pszBuf++ = '}';
129                         continue;
130                 }
131
132                 // '(' チェック
133                 if ( *pszText == '(' )
134                 {
135                         *pszBuf++ = *pszText++;
136                         iErr = SearchChar(pszBuf, pszText, ')');
137                         if ( iErr != CFG_ERR_OK )
138                         {
139                                 iErr = CFG_ERR_PAREN;
140                         }
141                         pszBuf  += strlen(pszBuf);
142                         *pszBuf++ = ')';
143                         continue;
144                 }
145
146                 *pszBuf++ = *pszText++;
147         }
148
149         *pszBuf = '\0';
150
151         return iErr;
152 }
153
154
155 // パラメーターの切り出し
156 int CAnalyze::GetParameter(char* pszBuf, const char* &pszText)
157 {
158         int iErr;
159
160         // コンマまで切り出す
161         iErr = SearchChar(pszBuf, pszText, ',');
162         if ( iErr == CFG_ERR_SYNTAX )
163         {
164                 // 括弧対応OKで終端ならコンマが見つからなくても可
165                 iErr = CFG_ERR_OK;
166         }
167
168         return iErr;
169 }
170
171
172 // 文字列定数を展開する
173 int CAnalyze::DecodeText(char *pszBuf, const char* pszText)
174 {
175         bool blEsc = false;
176
177         if ( *pszText++ != '\"') 
178         {
179                 return CFG_ERR_TEXT;
180         }
181
182         for ( ; ; )
183         {
184                 if ( *pszText == '\0' )
185                 {
186                         return CFG_ERR_TEXT;
187                 }
188
189                 // 前の文字が '\' なら読み飛ばし
190                 if ( blEsc )
191                 {
192                         *pszBuf++ = *pszText++;
193                         blEsc = false;
194                         continue;
195                 }
196
197                 // エスケープ文字チェック
198                 if ( *pszText == '\\' )
199                 {
200                         pszText++;
201                         blEsc = true;
202                         continue;
203                 }
204
205                 // 終端チェック
206                 if ( *pszText == '\"' )
207                 {
208                         pszText++;
209                         break;
210                 }
211
212                 *pszBuf++ = *pszText++;
213         }
214
215         // 完結していなければエラー
216         if ( *pszText != '\0' )
217         {
218                         return CFG_ERR_TEXT;
219         }
220
221         *pszBuf = '\0';
222
223         return CFG_ERR_OK;
224 }
225
226
227 // 前後の空白を削除する
228 void CAnalyze::SpaceCut(char* pszText)
229 {
230         char *pszTmp;
231         int  i = 0;
232
233         pszTmp = pszText;
234
235         // 先頭の空白を読み飛ばす
236         while ( *pszTmp == ' ' )
237         {
238                 pszTmp++;
239         }
240
241         // コピー
242         while ( *pszTmp != '\0' )
243         {
244                 pszText[i++] = *pszTmp++;
245         }
246
247         // 末尾の空白を削除
248         while ( i > 0 && pszText[i - 1] == ' ' )
249         {
250                 i--;
251         }
252
253         pszText[i] = '\0';
254 }
255
256
257 // end of file