Htmlpars.c
[目次 | 関数]
1|/**************************************************************************
2|* 1. <<< HTML パーサ (HtmlPars) >>>
3|***************************************************************************/
4|
5|#include "mixer_precomp.h" /* Auto precompiled header, Look at mixer-... folder */
6|// #pragma hdrstop
7|
8|#ifdef USES_MXP_AUTOINC
9| #include <htmlpars.ah> /* Auto include header, Look at mixer-... folder */
10|#endif
11|
12|
13|/*---------------------------------------------------------------------*/
14|/* 2. <<<◆(HtmlPars) HTML パーサ >>> */
15|/*---------------------------------------------------------------------*/
16|
17|
18|/**************************************************************************
19|* 3. <<< [HtmlPars_init] 初期化する >>>
20|*【引数】
21|* ・HtmlPars* m; HTML パーサ
22|* ・void* mem; 文字列記憶領域1
23|* ・int mem_size; mem の領域サイズ、最大の全文字数
24|* ・char** mem2; 文字列記憶領域2、char* 型配列
25|* ・int mem2_size; mem2 の領域サイズ、最大の属性数×2×sizeof(char*)
26|***************************************************************************/
27|void HtmlPars_init( HtmlPars* m, void* mem, int mem_size,
28| char** mem2, int mem2_size )
29|{
30| ERRORS_INITCHK( m, 0 );
31|
32| m->engU = NULL;
33|
34| BLex3_Pos_init( &m->parsedPos );
35| m->prevTokenType = BLex3_OutOfToken;
36| m->bInTag = false;
37|
38| m->name = NULL;
39| m->attr_names = mem2;
40| m->attr_values = mem2 + mem2_size / (sizeof(char*) * 2);
41| m->attr_n = 0;
42| StrX_Mem_init( &m->mem, mem, mem_size );
43|}
44|
45|
46|
47|/**************************************************************************
48|* 4. <<< [HtmlPars_print] デバッグ表示する >>>
49|***************************************************************************/
50|#ifndef ERRORS_CUT_DEBUG_TOOL
51|void HtmlPars_print( HtmlPars* m, const char* title )
52|{
53| int i;
54|
55| ERRORS_INITCHK( m, 1 );
56|
57| Errors_printf( "%sHtmlPars[%p] engU=[%p]", title, m, m->engU );
58| BLex3_Pos_print( &m->parsedPos, title );
59| Errors_printf( "%s prevTokenType = %d", title, m->prevTokenType );
60|
61| Errors_printf( "%s name = %s, attr_n = %d", title, m->name, m->attr_n );
62|
63| for ( i = 0; i < m->attr_n; i++ ) {
64| Errors_printf( "%s attr_name = %s, attr_value = %s", title,
65| m->attr_names[i], m->attr_values[i] );
66| }
67| Errors_printf( "%s mem = [%p]", title, &m->mem );
68|}
69|#endif
70|
71|
72|
73|/**************************************************************************
74|* 5. <<< [HtmlPars_linkEngine] 字句解析エンジンと関連付ける >>>
75|*【引数】
76|* ・HtmlPars* m; HTML パーサ
77|* ・BLex3_EngineU* engU; 字句解析エンジン
78|***************************************************************************/
79|void HtmlPars_linkEngine( HtmlPars* m, BLex3_EngineU* engU )
80|{
81| ERRORS_INITCHK( m, 1 );
82|
83| m->engU = engU;
84|}
85|
86|
87|
88|/**************************************************************************
89|* 6. <<< [HtmlPars_parse] HTML タグを解析する >>>
90|*【引数】
91|* ・HtmlPars* m; HTML パーサ
92|*【補足】
93|*・前回に本関数を呼び出したときより、ファイルポインタが進んでいること。
94|***************************************************************************/
95|void HtmlPars_parse( HtmlPars* m )
96|{
97| BLex3_EngineU* engU = m->engU;
98| char* fp;
99| char* fp0;
100| char* fp2;
101| char* fp_over;
102| BLex3_Pos pos;
103|
104| ERRORS_INITCHK( m, 1 );
105|
106| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &pos );
107| if ( pos.pos < m->parsedPos.pos ) {
108| m->prevTokenType = BLex3_MiddleOfToken;
109| return;
110| }
111|
112| /* 前回が、タグの開始だったとき */
113| if ( m->bInTag ) {
114| m->prevTokenType = HtmlPars_EndOfTag;
115| m->bInTag = false;
116| return;
117| }
118|
119| /* それ以外のとき, '<' を見つけてタグを解析する */
120| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 0 );
121| fp2 = BLex3_Engine_getSJisPtr( &engU->inherit_BLex3_Engine );
122| fp_over = BLex3_Engine_getOverPtr( &engU->inherit_BLex3_Engine );
123|
124| fp0 = fp;
125| while ( fp < fp_over ) {
126|
127| if ( *fp == '<' && *fp2 != BLex3_SJisSecond ) {
128| char* p;
129|
130| /* 数バイト先にタグの開始があるとき、そこまで解析して一旦抜ける */
131| if ( fp != fp0 ) {
132| BLex3_Engine_getPos2( &engU->inherit_BLex3_Engine, fp, &m->parsedPos );
133| m->prevTokenType = BLex3_OutOfToken;
134| return;
135| }
136|
137| /* タグ名を取得する: get tag name */
138| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
139|
140| StrX_Mem_toEmpty( &m->mem );
141| m->attr_n = 0;
142|
143| p = StrX_Mem_alloc( &m->mem );
144| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &pos );
145| BLex3_EngineU_readWord( engU,
146| p, StrX_Mem_getLeftSize( &m->mem ), " >", true );
147| StrX_cpyLower( p, p );
148| m->name = p;
149| if ( ! StrX_isAlpha( *p ) && *p != '/' && *p != '!' && *p != '?' ) {
150| BLex3_Pos_copy( &m->parsedPos, &pos );
151| m->prevTokenType = BLex3_OutOfToken;
152| return;
153| }
154|
155| /* コメントタグのとき: case of comment tag */
156| if ( strncmp( m->name, "!--", 3 ) == 0 ) {
157| m->name[3] = '\0';
158| BLex3_Engine_setPos2( &engU->inherit_BLex3_Engine, &pos, +2 );
159| BLex3_EngineU_skipToStr( engU, "-->", 3, false );
160| }
161|
162| /* 一般のタグのとき: case of general tag */
163| else {
164| for (;;) {
165|
166| /* 属性名を取得する: get attribute name */
167| BLex3_EngineU_skip( engU, " \t\n\r" );
168| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 1 );
169| if ( fp == NULL || *fp == '>' )
170| { m->endCh = '\0'; break; }
171| if ( ( *fp == '/' || *fp == '?' ) && *(fp+1) == '>' ) {
172| m->endCh = *fp;
173| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
174| break;
175| }
176| if ( ! StrX_isAlpha( *fp ) ) {
177| BLex3_EngineU_skipTo( engU, ">", 0 );
178| break;
179| }
180| if ( m->attr_names + m->attr_n >= m->attr_values ) {
181| BLex3_EngineU_skipTo( engU, ">", 0 );
182| break;
183| }
184| p = StrX_Mem_alloc( &m->mem );
185| BLex3_EngineU_readWord( engU,
186| p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true );
187| StrX_cpyLower( p, p );
188| m->attr_names[m->attr_n] = p;
189|
190| /* 属性値を取得する: get attribute value */
191| BLex3_EngineU_skip( engU, " \t\n\r" );
192| fp = BLex3_Engine_getFilePtr( &engU->inherit_BLex3_Engine, 1 );
193| if ( fp == NULL || *fp == '>' ) break;
194| p = StrX_Mem_alloc( &m->mem );
195| if ( *fp == '=' ) {
196| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
197| BLex3_EngineU_skip( engU, " \t\n\r" );
198| BLex3_EngineU_readWord( engU,
199| p, StrX_Mem_getLeftSize( &m->mem ), " =>\r\n\t", true );
200| }
201| else {
202| *p = '\0';
203| }
204| m->attr_values[m->attr_n] = p;
205| m->attr_n ++;
206| }
207| BLex3_Engine_next( &engU->inherit_BLex3_Engine, 1 );
208| }
209| BLex3_Engine_getPos( &engU->inherit_BLex3_Engine, &m->parsedPos );
210| m->prevTokenType = HtmlPars_StartOfTag;
211| m->bInTag = true;
212| return;
213| }
214| fp++; fp2++;
215| }
216|
217| BLex3_Engine_getPos2( &engU->inherit_BLex3_Engine, fp_over, &m->parsedPos );
218| m->prevTokenType = BLex3_OutOfToken;
219| return;
220|}
221|
222|
223|
224|/**************************************************************************
225| 7. <<< [HtmlPars_getTokenType] 現在位置のトークンタイプを返す >>>
226|【補足】
227|・HtmlPars用トークンタイプを返します。
228|***************************************************************************/
229|int HtmlPars_getTokenType( HtmlPars* m )
230|{
231| return m->prevTokenType;
232|}
233|
234|/**************************************************************************
235|* 8. <<< [HtmlPars_getNextParsePos] 次に解析すべき位置を取得する >>>
236|***************************************************************************/
237|void HtmlPars_getNextParsePos( HtmlPars* m, BLex3_Pos* pos )
238|{
239| *pos = m->parsedPos;
240|}
241|
242|
243|/**************************************************************************
244|* 9. <<< [HtmlPars_isInTag] タグの途中またはコメントの途中かどうかを返す >>>
245|***************************************************************************/
246|bool HtmlPars_isInTag( HtmlPars* m )
247|{
248| return m->bInTag && m->prevTokenType != HtmlPars_StartOfTag;
249|}
250|
251|
252|/**************************************************************************
253|* 10. <<< [HtmlPars_getValue] 属性の値を返す >>>
254|*【補足】
255|*・該当する属性が無いときは NULL を返します。
256|***************************************************************************/
257|char* HtmlPars_getValue( HtmlPars* m, const char* attr_name )
258|{
259| char** s;
260| char** s_over = m->attr_names + m->attr_n;
261|
262| #ifndef NDEBUG
263| {
264| /* attr_name は小文字を指定してください */
265| const char* p;
266| for ( p = attr_name; *p != '\0'; p++ ) {
267| ASSERT( (*p >= 'a' && *p <= 'z') || (*p >= '0' && *p <= '9') ||
268| *p == '_' || *p == ':' );
269| }
270| }
271| #endif
272|
273| for ( s = m->attr_names; s < s_over; s++ ) {
274| if ( stricmp( *s, attr_name ) == 0 )
275| return m->attr_values[ s - m->attr_names ];
276| }
277| return NULL;
278|}
279|
280|
281|/**************************************************************************
282|* 11. <<< [HtmlPars_getTokenFirstPos] 現在位置にあるタグの先頭のファイルアドレスを返す >>>
283|*【引数】
284|* ・HtmlPars* m; HTML パーサ
285|* ・int 返り値; 現在位置にあるタグの先頭のファイルアドレス
286|***************************************************************************/
287|#if 0
288|int HtmlPars_getTokenFirstPos( HtmlPars* m )
289|{
290| ERRORS_INITCHK( m, 1 );
291|
292| return m->firstPos;
293|}
294|#endif
295|
296|
297|/**************************************************************************
298|* 12. <<< [HtmlPars_getTokenOverPos] 現在位置にあるタグの末尾の次のファイルアドレスを返す >>>
299|*【引数】
300|* ・HtmlPars* m; HTML パーサ
301|* ・int 返り値; 現在位置にあるタグの末尾の次のファイルアドレス
302|***************************************************************************/
303|#if 0
304|int HtmlPars_getTokenOverPos( HtmlPars* m )
305|{
306| ERRORS_INITCHK( m, 1 );
307|
308| return m->overPos;
309|}
310|#endif
311|
312|
313|/**************************************************************************
314|* 13. <<< [HtmlPars_printLastMsg] ファイル解析後に結果を出力する >>>
315|*【引数】
316|* ・HtmlPars* m; HTML パーサ
317|***************************************************************************/
318|void HtmlPars_printLastMsg( HtmlPars* m, FILE* f, const char* title )
319|{
320| ERRORS_INITCHK( m, 1 );
321|
322| /* no printing */
323|}
324|
325|
326|
327|