RXML.C
[目次 | 関数 | マクロ]
1|/***********************************************************************
2|* 1. <<< Replacing teXt Markup Language (RXML) >>>
3|************************************************************************/
4|
5|#ifdef USES_MXP_AUTOINC
6| #include "rxml.ah" /* Auto include header, Look at mixer-... folder */
7|#else
8| #include "all.h"
9|#endif
10|
11|#ifdef USES_RXML_ACTOR
12| #define RXML_POSRET( x ) ((x).pos)
13|#else
14| #define RXML_POSRET( x ) (x)
15|#endif
16|
17|
18|/*--------------------------------------------------------------------*/
19|/* 2. <<< ◆(RXML) RXML プロジェクト >>> */
20|/*--------------------------------------------------------------------*/
21|
22|
23|/***********************************************************************
24|* 3. <<< [RXML_init] 初期化する >>>
25|*【補足】
26|*・RXML_DB_init( &RXML_db ); を呼び出してから実行してください。
27|*・内部で Sym モジュールを使用しているので、Sym_init, Sym_finish 関数を
28|* 使って、sym グローバル変数が有効になっているようにしてください。
29|************************************************************************/
30|void RXML_init( RXML* m, Log* log )
31|{
32| ListX_init( &m->tags );
33| ListX_init( &m->files );
34| ListX_init( &m->dataClasses );
35| m->log = log;
36|
37| ERRORS_FINISHCHK_FOR_INIT( RXML_finish );
38|}
39|
40|
41|/***********************************************************************
42|* 4. <<< [RXML_finish] 後始末する >>>
43|************************************************************************/
44|void RXML_finish( RXML* m )
45|{
46| ERRORS_FINISHCHK_FOR_FINISH( RXML_finish );
47|
48| ListX_finish2( &m->tags, RXML_Tag, RXML_Tag_finish );
49| ListX_finish2( &m->files, RXML_File, RXML_File_finish );
50| ListX_finish2( &m->dataClasses, RXML_Tag, RXML_Tag_finish );
51|}
52|
53|
54|/***********************************************************************
55|* 5. <<< [RXML_print] デバッグ表示する >>>
56|************************************************************************/
57|#ifndef ERRORS_CUT_DEBUG_TOOL
58|void RXML_print( RXML* m, const char* title )
59|{
60| RXML_File* file;
61| RXML_Tag* tag;
62|
63| for ( ListX_forEach( &m->files, &file, RXML_File ) )
64| RXML_File_print( file, title );
65|
66| Errors_printf( "%s", title );
67| Errors_printf( "%s", title );
68| Errors_printf( "%sRXML::dataClasses =============================", title );
69| for ( ListX_forEach( &m->dataClasses, &tag, RXML_Tag ) )
70| RXML_Tag_print( tag, title );
71|}
72|#endif
73|
74|/***********************************************************************
75|* 6. <<< [RXML_addFile] プロジェクトに含める RXML ファイルを登録する >>>
76|************************************************************************/
77|RXML_File* RXML_addFile( RXML* m, const char* path )
78|{
79| RXML_File* file;
80| bool bExist;
81|
82| bExist = FileX_isExist( path );
83|
84| file = ListX_addLastMalloc( &m->files, RXML_File );
85| RXML_File_init( file, path, m );
86| file->bExist = bExist;
87|
88| if ( ! bExist )
89| error2_1( RXML_Err_FileNotFound, "%s ファイルが見つかりません", path );
90|
91| return file;
92|}
93|
94|/***********************************************************************
95|* 7. <<< [RXML_toEmpty] RXML ファイルを登録をすべてなくす >>>
96|************************************************************************/
97|void RXML_toEmpty( RXML* m )
98|{
99| ListX_toEmptyDelete( &m->files, RXML_File, RXML_File_finish );
100|}
101|
102|
103|/***********************************************************************
104|* 8. <<< [RXML_pickupDC] RXML データ・クラス定義ステップ >>>
105|************************************************************************/
106|#ifndef USES_RXML_ACTOR
107|void RXML_pickupDC( RXML* m )
108|{
109| RXML_File* file;
110|
111| for ( ListX_forEach( &m->files, &file, RXML_File ) ) {
112| RXML_File_pickupDC( file );
113| }
114|}
115|#endif
116|
117|/***********************************************************************
118|* 9. <<< [RXML_pickupTags] タグ抽出ステップ >>>
119|************************************************************************/
120|#ifndef USES_RXML_ACTOR
121|void RXML_pickupTags( RXML* m )
122|{
123| RXML_File* file;
124|
125| for ( ListX_forEach( &m->files, &file, RXML_File ) ) {
126| RXML_File_pickupTags( file );
127| }
128|}
129|#endif
130|
131|/***********************************************************************
132|* 10. <<< [RXML_out] ドキュメント変換ステップ >>>
133|************************************************************************/
134|#ifdef USES_BLEX2
135|void RXML_out( RXML* m )
136|{
137| RXML_File* file;
138| FILE* out;
139| bool bOut = false;
140| char outPath[_MAX_PATH];
141|
142| c_try {
143| for ( ListX_forEach( &m->files, &file, RXML_File ) ) {
144| strcpy( outPath, file->path );
145| StrX_cdFName( outPath, "html" );
146| out = FileX_open( outPath, "wb" ); bOut = true;
147|
148| RXML_File_out( file, out );
149|
150| bOut = false; fclose( out );
151| }
152| }
153| c_finally {
154| if ( bOut ) fclose( out );
155| } c_end_finally;
156|}
157|#endif
158|
159|/***********************************************************************
160|* 11. <<< [RXML_getFullHref] ループ変数を展開した href 属性を取得する >>>
161|*【引数】
162|* ・char* href; 最も下位の VAR タグまたは TEMPLATE タグの href 属性の値
163|* ・ArrX_Buf* tmps; var を含む TEMPLATE タグ(RXML_Tag* 型配列)
164|* ・char* fullHref; ループ変数を展開した href 属性(出力)
165|* ・int fullHref_size; fullHref のメモリサイズ(バイト)
166|*【補足】
167|*・tmps は、以下の場合、First が TEMPLATE(A), Last が TEMPLATE(B) です。
168|* <TEMPLATE name="A"><TEMPLATE name="B"><VAR href="i"></TEMPLATE></TEMPLATE>
169|*・該当するループ変数がなければ、そのまま fullHref に出力します。
170|************************************************************************/
171|void RXML_getFullHref( const char* href, ArrX_Buf* tmps, char* fullHref,
172| int fullHref_size )
173|{
174| RXML_Tag** tag;
175| char* href2;
176| char* arg;
177| char name[RXML_NameSize];
178|
179| StrX_cpy( fullHref, href, fullHref_size );
180|
181| if ( strchr( href, '#' ) != NULL )
182| return;
183|
184| /* ループ変数を展開する */
185| StrX_wordCpy( name, sizeof(name)-1, fullHref, '.' );
186| for ( ArrX_Buf_forEachReverse( tmps, &tag, RXML_Tag* ) ) {
187| arg = RXML_Tag_getAttrValue( *tag, "arg" );
188| if ( ( arg == NULL && name[0] == '\0' ) ||
189| ( arg != NULL && stricmp( arg, name ) == 0 ) ) {
190|
191| StrX_del( fullHref, strlen(name) );
192| href2 = RXML_Tag_getAttrValue( *tag, "href" );
193| if ( strlen( fullHref ) + strlen( href2 ) + 2 > (unsigned)fullHref_size )
194| error();
195| StrX_ins( fullHref, href2 );
196| if ( strchr( fullHref, '#' ) != NULL )
197| return;
198| StrX_wordCpy( name, sizeof(name)-1, fullHref, '.' );
199| }
200| }
201|}
202|
203|/***********************************************************************
204|* 12. <<< [RXML_getHrefFile] href属性で指定しているリンク先のファイルを返す >>>
205|*【引数】
206|* ・char* href; href属性
207|* ・char* basePath; href属性が所属しているファイルの絶対パス
208|* ・bool bAdd; 無いときは追加するかどうか
209|* ・RXML_File* 返り値; リンク先のファイル
210|*【補足】
211|*・href 属性が、タグを指定している場合、所属しているファイルを返します。
212|*・bAdd = false で RXML::files に存在しないときは、NULL を返します。
213|************************************************************************/
214|RXML_File* RXML_getHrefFile( RXML* m, const char* href,
215| const char* basePath, bool bAdd )
216|{
217| RXML_File* file;
218| char* p;
219| char path[_MAX_PATH];
220|
221| /* リンク先のファイルパスを path に格納する */
222| p = strchr( href, '#' );
223| if ( p == href ) {
224| strcpy( path, basePath );
225| }
226| else {
227| if ( p != NULL ) *p = '\0';
228| StrX_cpyAbsPath2( path, href, _MAX_PATH, basePath );
229| if ( p != NULL ) *p = '#';
230| }
231|
232| /* ファイルを返す */
233| p = StrX_MemV2_alloc( &RXML_db.dic, path );
234| for ( ListX_forEach( &m->files, &file, RXML_File ) ) {
235| if ( file->path == p ) break;
236| }
237| if ( file == NULL && bAdd ) {
238| file = RXML_addFile( m, path );
239| }
240|
241| return file;
242|}
243|
244|
245|/***********************************************************************
246|* 13. <<< [RXML_getHrefTag] href 属性で指定しているリンク先のタグを返す >>>
247|*【引数】
248|* ・char* href; href属性
249|* ・char* basePath; href属性が所属しているファイルの絶対パス
250|* ・ArrX_Buf* tmps; href属性を含んでいる TEMPLATE タグ(RXML_Tag* 型)のスタック
251|*【補足】
252|*・href 属性がファイルを指定している場合、NULL を返します。
253|*・tmps は、以下の場合、First が TEMPLATE(A), Last が TEMPLATE(B) です。
254|* <TEMPLATE name="A"><TEMPLATE name="B"><VAR href="i"></TEMPLATE></TEMPLATE>
255|*・関連:RXML_getHrefRef 関数
256|************************************************************************/
257|RXML_Tag* RXML_getHrefTag( RXML* m, const char* href,
258| const char* basePath, ArrX_Buf* tmps )
259|{
260| RXML_File* file;
261| RXML_Tag* tag;
262| RXML_Tag* tmpTag;
263| char* p;
264| char str[256];
265|
266| if ( href[0] == '\0' ) return NULL;
267|
268| /* str にファイルパスまたはループ変数を代入する */
269| /* p を href 中の '#' または '.' 文字のある位置へ */
270| p = strchr( href, '#' );
271| if ( p == NULL ) {
272| StrX_wordCpy( str, sizeof(str)-1, href, '.' );
273| p = strchr( href, '.' );
274| }
275| else
276| StrX_wordCpy( str, sizeof(str)-1, href, '#' );
277|
278| /* ループ変数が所属する TEMPLATE タグを tmpTag へ */
279| tmpTag = RXML_getLoopTmp( str, tmps );
280| if ( tmpTag != NULL ) {
281| tag = tmpTag->loopTag;
282| }
283| else {
284|
285| /* href 参照が filepath のみの場合 NULL を返す */
286| if ( p == NULL ) return NULL;
287|
288| /* 参照するファイルを file へ */
289| if ( stricmp( str, "all" ) == 0 ) file = NULL;
290| else if ( str[0] == '\0' ) {
291| file = RXML_getHrefFile( m, basePath, basePath, false );
292| ASSERT( file != NULL );
293| }
294| else {
295| file = RXML_getHrefFile( m, str, basePath, false );
296| if ( file == NULL ) return NULL; /* ファイルが見つからない */
297| }
298|
299| /* タグを tag へ */
300| ASSERT( p != NULL );
301| StrX_wordCpy( str, sizeof(str)-1, p + 1, '.' );
302| p = strchr( p + 1, '.' );
303| if ( file == NULL ) tag = RXML_getTagInAllFile( m, str );
304| else tag = RXML_File_getTag( file, str );
305| }
306|
307| /* href のピリオド '.' ごとに tag を走査する */
308| while ( p != NULL && tag != NULL ) {
309| if ( p[1] == '\0' ) break;
310| StrX_wordCpy( str, sizeof(str)-1, p + 1, '.' );
311| p = strchr( p + 1, '.' );
312| tag = RXML_Tag_getSubTag( tag, str );
313| }
314|
315| return tag;
316|}
317|
318|/***********************************************************************
319|* 14. <<< [RXML_getHrefRef] href 属性で指定しているリンク先のプログラムデータを返す >>>
320|*【引数】
321|* ・char* href; href属性
322|* ・ArrX_Buf* tmps; href属性を含んでいる TEMPLATE タグ(RXML_Tag* 型)のスタック
323|* ・Sym_Ref* ref; プログラムデータの参照を格納するアドレス(出力)
324|* ・bool 返り値; 該当するデータがあったかどうか
325|*【補足】
326|*・tmps は、以下の場合、First が TEMPLATE(A), Last が TEMPLATE(B) です。
327|* <TEMPLATE name="A"><TEMPLATE name="B"><VAR href="i"></TEMPLATE></TEMPLATE>
328|*・関連:RXML_getHrefTag 関数
329|************************************************************************/
330|#ifdef USES_SYM
331|bool RXML_getHrefRef( const char* href, ArrX_Buf* tmps, Sym_Ref* ref )
332|{
333| bool ret = false;
334| RXML_Tag* tmpTag;
335| char* p;
336| char str[RXML_NameSize];
337|
338| StrX_wordCpy( str, sizeof(str), href, '.' );
339| p = strchr( href, '.' );
340|
341| c_try {
342|
343| /* ループ変数が所属する TEMPLATE タグを tmpTag へ */
344| tmpTag = RXML_getLoopTmp( str, tmps );
345| if ( tmpTag == NULL ) {
346| if ( Sym_getVar( &sym, str ) != NULL ) {
347| Sym_getRef( &sym, href, ref );
348| ret = true;
349| }
350| }
351| else {
352| if ( tmpTag->loopTag == NULL ) {
353| if ( p == NULL ) *ref = tmpTag->loopRef;
354| else Sym_Ref_getRef( &tmpTag->loopRef, p + 1, ref );
355| ret = true;
356| }
357| }
358| } Errors_ignore_catch( case Sym_Err_NotFindSymbol:
359| case Sym_Err_ManyNest: );
360|
361| return ret;
362|}
363|#endif
364|
365|/***********************************************************************
366|* 15. <<< [RXML_getLoopTmp] 指定のループ変数が所属するテンプレート・タグを返す >>>
367|*【引数】
368|* ・char* loopName; ループ変数名(無名ループ変数="" または ".")
369|* ・ArrX_Buf* tmps; href属性を含んでいる TEMPLATE タグ(RXML_Tag* 型)のスタック
370|* ・RXML_Tag* 返り値; loopName が所属するテンプレート・タグ(NULL あり)
371|*【補足】
372|*・tmps は、以下の場合、First が TEMPLATE(A), Last が TEMPLATE(B) です。
373|* <TEMPLATE name="A"><TEMPLATE name="B"><VAR href="i"></TEMPLATE></TEMPLATE>
374|************************************************************************/
375|RXML_Tag* RXML_getLoopTmp( const char* loopName, ArrX_Buf* tmps )
376|{
377| char* value;
378| RXML_Tag** tmpTag;
379|
380| if ( loopName[0] == '\0' || loopName[0] == '.' ) {
381| for ( ArrX_Buf_forEachReverse( tmps, &tmpTag, RXML_Tag* ) ) {
382| ASSERT( strcmp( (*tmpTag)->tagName, "template" ) == 0 );
383| value = RXML_Tag_getAttrValue( *tmpTag, "arg" );
384| if ( value == NULL ) return *tmpTag;
385| }
386| }
387| else {
388| for ( ArrX_Buf_forEachReverse( tmps, &tmpTag, RXML_Tag* ) ) {
389| ASSERT( strcmp( (*tmpTag)->tagName, "template" ) == 0 );
390| value = RXML_Tag_getAttrValue( *tmpTag, "arg" );
391| if ( value != NULL && strcmp( value, loopName ) == 0 )
392| return *tmpTag;
393| }
394| }
395|
396| return NULL;
397|}
398|
399|/***********************************************************************
400|* 16. <<< [RXML_getTagInAllFile] すべてのファイルから指定のタグを返す >>>
401|*【引数】
402|* ・char* tagName; タグ名
403|*【補足】
404|*・見つからなければ、NULL を返します。
405|*・複数見つかったときは、最初のタグを返します。
406|************************************************************************/
407|RXML_Tag* RXML_getTagInAllFile( RXML* m, const char* tagName )
408|{
409| RXML_File* file;
410| RXML_Tag* tag;
411|
412| for ( ListX_forEach( &m->files, &file, RXML_File ) ) {
413| tag = RXML_File_getTag( file, tagName );
414| if ( tag != NULL ) return tag;
415| }
416| return NULL;
417|}
418|
419|
420|/***********************************************************************
421|* 17. <<< [RXML_getDataClass] データクラス(のトップ)を取得する >>>
422|************************************************************************/
423|RXML_Tag* RXML_getDataClass( RXML* m, const char* name )
424|{
425| RXML_Tag* tag;
426| char* name2 = StrX_MemV2_alloc( &RXML_db.dic, name );
427|
428| for ( ListX_forEach( &m->dataClasses, &tag, RXML_Tag ) ) {
429| if ( name2 == tag->name ) return tag;
430| }
431| return NULL;
432|}
433|
434|
435|/***********************************************************************
436|* 18. <<< [RXML_DB_getTagInFile] ファイルの中からタグを返す >>>
437|*【引数】
438|* ・char* path; ファイルパス
439|* ・char* name; タグ名
440|*【補足】
441|*・見つからなければ、NULL を返します。
442|************************************************************************/
443|#if 0
444|RXML_Tag* RXML_DB_getTagInFile( RXML_DB* m,
445| const char* path, const char* name )
446|{
447| TakeX_RXMLFile* file;
448| char* path2 = StrX_MemV2_alloc( &m->dic, path );
449| bool bFind = false;
450|
451| /* ファイル file を検索する */
452| for ( ListX_forEach( &m->files, &file, TakeX_RXMLFile ) ) {
453| if ( file->path == path2 )
454| { bFind = true; break; }
455| }
456|
457| /* ファイルがあったら、タグ tag を検索する */
458| if ( bFind ) {
459| RXML_File* nextFile = (RXML_File*)ListX_Elem_getNext( file );
460| Take_Tag* tag;
461| Take_Tag* tag_over;
462| char* name2 = StrX_MemV2_alloc( &m->dic, name );
463|
464| tag_over = ( nextFile == NULL ) ? NULL : nextFile->firstTag;
465| for ( tag = file->firstTag; tag != tag_over;
466| tag = (Take_Tag*)ListX_Elem_getNext( tag ) ) {
467| if ( tag->name == name2 )
468| return tag;
469| }
470| }
471| return NULL;
472|}
473|#endif
474|
475|/*--------------------------------------------------------------------*/
476|/* 19. <<< ◆(RXML_DB) RXML データベース >>> */
477|/*--------------------------------------------------------------------*/
478|
479|RXML_DB RXML_db;
480|void* RXML_DB_chker;
481|
482|/***********************************************************************
483|* 20. <<< [RXML_DB_init] 初期化する >>>
484|************************************************************************/
485|void RXML_DB_init( RXML_DB* m )
486|{
487| ERRORS_SINGLETON_FOR_INIT( &RXML_DB_chker, m );
488|
489| StrX_MemV2_init( &m->dic, RXML_DB_width, StrX_getHashI, false );
490|
491| ERRORS_FINISHCHK_FOR_INIT( RXML_DB_finish );
492|}
493|
494|
495|/***********************************************************************
496|* 21. <<< [RXML_DB_finish] 後始末する >>>
497|************************************************************************/
498|void RXML_DB_finish( RXML_DB* m )
499|{
500| ERRORS_SINGLETON_FOR_FINISH( &RXML_DB_chker, m );
501| ERRORS_FINISHCHK_FOR_FINISH( RXML_DB_finish );
502|
503| StrX_MemV2_finish( &m->dic );
504|}
505|
506|
507|/*--------------------------------------------------------------------*/
508|/* 22. <<< ◆(RXML_File) RXML ファイル >>> */
509|/*--------------------------------------------------------------------*/
510|
511|
512|/***********************************************************************
513|* 23. <<< [RXML_File_init] 初期化する >>>
514|************************************************************************/
515|void RXML_File_init( RXML_File* m, const char* path, RXML* top )
516|{
517| m->top = top;
518| m->path = StrX_MemV2_alloc( &RXML_db.dic, path );
519| m->bExist = true;
520| ListX_init( &m->tags );
521| ListX_init( &m->dataClasses );
522| ListX_init( &m->progDataRef );
523|
524| ERRORS_FINISHCHK_FOR_INIT( RXML_File_finish );
525|}
526|
527|/***********************************************************************
528|* 24. <<< [RXML_File_finish] 後始末する >>>
529|************************************************************************/
530|void RXML_File_finish( RXML_File* m )
531|{
532| ERRORS_FINISHCHK_FOR_FINISH( RXML_File_finish );
533|
534| ListX_finish2( &m->tags, RXML_Tag, RXML_Tag_finish );
535| ListX_finish2( &m->dataClasses, RXML_Tag, RXML_Tag_finish );
536| ListX_finish2( &m->progDataRef, RXML_Tag, RXML_Tag_finish );
537|}
538|
539|/***********************************************************************
540|* 25. <<< [RXML_File_print] デバッグ表示する >>>
541|************************************************************************/
542|#ifndef ERRORS_CUT_DEBUG_TOOL
543|void RXML_File_print( RXML_File* m, const char* title )
544|{
545| RXML_Tag* tag;
546|
547| Errors_printf( "%s--------------------------------------", title );
548| Errors_printf( "%spath = %s", title, m->path );
549|
550| Errors_printf( "tags:" );
551| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
552| RXML_Tag_print( tag, title );
553| Errors_printf( "" );
554| }
555| Errors_printf( "dataClasses:" );
556| for ( ListX_forEach( &m->dataClasses, &tag, RXML_Tag ) ) {
557| RXML_Tag_print( tag, title );
558| Errors_printf( "" );
559| }
560| Errors_printf( "progDataRef:" );
561| for ( ListX_forEach( &m->progDataRef, &tag, RXML_Tag ) ) {
562| RXML_Tag_print( tag, title );
563| Errors_printf( "" );
564| }
565|}
566|#endif
567|
568|/***********************************************************************
569|* 26. <<< [RXML_File_pickupDC] RXML データ・クラスを構築する >>>
570|************************************************************************/
571|#ifndef USES_RXML_ACTOR
572|void RXML_File_pickupDC( RXML_File* m )
573|{
574| BLex2 lex;
575| bool bLex = false;
576| BLex2_HTMLTags tags;
577| BLex2_Line lexLine;
578| RXML_File* file;
579| RXML_Tag* tag;
580| RXML_Tag* tag0;
581| RXML_Tag** pTag;
582| int c;
583| char* s;
584| char* href;
585| char* arg;
586| StrX_Mem mem;
587| ArrX_Buf tmpStack; /* テンプレート・スタック、RXML_Tag 型リスト */
588| bool bTmpStack = false;
589| char name[RXML_NameSize];
590| char buf[1024];
591| int buf2[256];
592| char memX[1024];
593| char* mem2[32];
594| char fullHref[RXML_HrefSize];
595| RXML_Tag* tmpStackX[32];
596|
597| c_try {
598| BLex2_init( &lex, m->path, buf, sizeof(buf) );
599| bLex = true;
600| BLex2_setSizeBuf( &lex, buf2, sizeof(buf2) );
601| BLex2_Line_init( &lexLine );
602| ArrX_Buf_init( &tmpStack, tmpStackX, sizeof(tmpStackX) ); bTmpStack = true;
603|
604| /* ファイル file を解析する BLex 字句解析ループ */
605| while ( ( c = BLex2_peek( &lex, 0 ) ) != EOF ) {
606| BLex2_Line_fetch( &lexLine, &lex );
607| if ( c == '<' ) {
608| if ( BLex2_peek( &lex, 1 ) != '<' ) {
609| StrX_Mem_init( &mem, memX, sizeof(memX) );
610| lexLine.lineNum += BLex2_readHTML( &lex, &tags, &mem, mem2, sizeof(mem2) );
611| s = BLex2_HTMLTags_getName( &tags );
612|
613| /* TEMPLATE タグの href 属性と arg 属性をスタックへ積む */
614| if ( strcmp( s, "template" ) == 0 ) {
615| href = BLex2_HTMLTags_getVar( &tags, "href" );
616| arg = BLex2_HTMLTags_getVar( &tags, "arg" );
617| if ( href == NULL ) {
618| BLex2_Line_nextFetch( &lexLine, &lex );
619| continue;
620| }
621| file = RXML_getHrefFile( m->top, href, m->path, false );
622|
623| if ( ArrX_Buf_getN( &tmpStack, RXML_Tag* ) == 0 )
624| tag = NULL;
625| else
626| tag = *ArrX_Buf_getLast( &tmpStack, RXML_Tag* );
627|
628| /* テンプレート・スタックにプッシュする */
629| pTag = ArrX_Buf_alloc( &tmpStack, RXML_Tag* );
630| *pTag = malloc( sizeof(RXML_Tag) );
631| RXML_Tag_init( *pTag, "template", tag, m, lexLine.lineNum );
632| if ( href != NULL ) RXML_Tag_addAttr( *pTag, "href", href );
633| if ( arg != NULL ) RXML_Tag_addAttr( *pTag, "arg", arg );
634| }
635| else if ( strcmp( s, "/template" ) == 0 ) {
636| int n;
637|
638| /* テンプレート・スタックからポップする */
639| n = ArrX_Buf_getN( &tmpStack, RXML_Tag* );
640| if ( n == 0 ) {
641| error2_1( RXML_Err_Many_EndOfTemplate,
642| "<""/TEMPLATE> が多すぎます(line=%d)", lexLine.lineNum );
643| }
644| pTag = ArrX_Buf_getLast( &tmpStack, RXML_Tag* );
645| RXML_Tag_finish( *pTag );
646| free( *pTag );
647| ArrX_Buf_free( &tmpStack, pTag, RXML_Tag* );
648| }
649|
650| /* VAR タグの href 属性から RXML データ・クラスを構築する */
651| if ( strcmp( s, "var" ) == 0 ) {
652| href = BLex2_HTMLTags_getVar( &tags, "href" );
653| if ( href == NULL ) continue;
654| RXML_getFullHref( href, &tmpStack, fullHref, sizeof(fullHref) );
655| s = strchr( fullHref, '#' );
656| if ( s != NULL ) {
657| tag0 = NULL;
658| if ( strnicmp( fullHref, "all#", 4 ) == 0 ) {
659|
660| /* RXML::dataClasses に無ければ追加する */
661| StrX_wordCpy( name, sizeof(name), s + 1, '.' );
662| s = strchr( s + 1, '.' );
663| tag0 = RXML_getDataClass( m->top, name );
664| if ( tag0 == NULL ) {
665| tag0 = ListX_addLastMalloc( &m->top->dataClasses, RXML_Tag );
666| RXML_Tag_init( tag0, "DC", NULL, m, lexLine.lineNum );
667| RXML_Tag_setName( tag0, name );
668| }
669| }
670| else {
671| file = RXML_getHrefFile( m->top, fullHref, m->path, false );
672| if ( file != NULL ) {
673|
674| /* RXML_File::dataClasses に無ければ追加する */
675| StrX_wordCpy( name, sizeof(name), s + 1, '.' );
676| s = strchr( s + 1, '.' );
677| tag0 = RXML_File_getDataClass( file, name );
678| if ( tag0 == NULL ) {
679| tag0 = ListX_addLastMalloc( &file->dataClasses, RXML_Tag );
680| RXML_Tag_init( tag0, "DC", NULL, m, lexLine.lineNum );
681| RXML_Tag_setName( tag0, name );
682| }
683| }
684| }
685|
686| if ( tag0 != NULL ) {
687|
688| /* RXML::dataClasses に無ければ追加する */
689| while ( s != NULL ) {
690| StrX_wordCpy( name, sizeof(name), s + 1, '.' );
691| s = strchr( s + 1, '.' );
692| tag = RXML_Tag_getSubTag2( tag0, name );
693| if ( tag == NULL ) {
694| tag = ListX_addLastMalloc( &tag0->tags, RXML_Tag );
695| RXML_Tag_init( tag, "DC", tag0, m, lexLine.lineNum );
696| RXML_Tag_setName( tag, name );
697| }
698| tag0 = tag;
699| }
700| }
701| }
702| else {
703|
704| /* RXML_File::progDataRef に無ければ追加する */
705| StrX_wordCpy( name, sizeof(name), fullHref, '.' );
706| s = strchr( fullHref, '.' );
707| tag = RXML_File_getProgDataRef( m, name );
708| if ( tag == NULL ) {
709| tag = ListX_addLastMalloc( &m->progDataRef, RXML_Tag );
710| RXML_Tag_init( tag, "PD", tag0, m, lexLine.lineNum );
711| RXML_Tag_setName( tag, name );
712| }
713|
714| while ( s != NULL ) {
715| StrX_wordCpy( name, sizeof(name), s + 1, '.' );
716| s = strchr( s + 1, '.' );
717| tag0 = tag;
718| tag = RXML_Tag_getSubTag2( tag0, name );
719| if ( tag == NULL ) {
720| tag = ListX_addLastMalloc( &tag0->tags, RXML_Tag );
721| RXML_Tag_init( tag, "PD", tag0, m, lexLine.lineNum );
722| RXML_Tag_setName( tag, name );
723| }
724| }
725| }
726| }
727| }
728| else {
729| do {
730| BLex2_next( &lex, 1 );
731| c = BLex2_peek( &lex, 0 );
732| } while ( c == '<' );
733| }
734| }
735| else
736| BLex2_next( &lex, 1 );
737|
738| BLex2_Line_nextFetch( &lexLine, &lex );
739| }
740| } c_finally {
741| if ( bLex ) BLex2_finish( &lex );
742| if ( bTmpStack ) {
743| for ( ArrX_Buf_forEach( &tmpStack, &pTag, RXML_Tag* ) ) {
744| RXML_Tag_finish( *pTag );
745| free( *pTag );
746| }
747| }
748| } c_end_finally;
749|}
750|#endif
751|
752|/***********************************************************************
753|* 27. <<< [RXML_File_pickupTags] 特定のファイルのタグ抽出ステップ >>>
754|************************************************************************/
755|#if ERRORS_DEBUG_FALSE
756|void RXML_File_pickupTags_tagStack_print( ArrX_Buf*, const char* title );
757|#endif
758|
759|#ifndef USES_RXML_ACTOR
760|void RXML_File_pickupTags( RXML_File* m )
761|{
762| BLex2 lex;
763| bool bLex = false;
764| BLex2_Pos pos;
765| BLex2_Line lexLine;
766| int c;
767| char* s;
768| RXML_Tag* tag;
769| RXML_Tag** pTag;
770| RXML_Tag* tagG;
771| RXML_Tag** pTagG;
772| BLex2_HTMLTags tags;
773| StrX_Mem mem;
774| ArrX_Buf tagStack; /* RXML タグ・スタック、RXML_Tag* 型配列 */
775| ArrX_Buf dcStack; /* RXML データ・クラス・スタック、RXML_Tag* 型配列 */
776| ArrX_Buf dcGStack; /* グローバル参照する dcStack */
777| ListX* childTags; /* 現在もっとも内側の TEMPLATE タグの RXML_Tag::tags または RXML_File::tags */
778| char buf[1024];
779| int buf2[256];
780| char memX[1024];
781| char* mem2[32];
782| RXML_Tag* tagStackX[32];
783| RXML_Tag* dcStackX[32];
784| RXML_Tag* dcGStackX[32];
785|
786| c_try {
787| BLex2_init( &lex, m->path, buf, sizeof(buf) );
788| bLex = true;
789| BLex2_setSizeBuf( &lex, buf2, sizeof(buf2) );
790| BLex2_Line_init( &lexLine );
791| ArrX_Buf_init( &tagStack, tagStackX, sizeof(tagStackX) );
792| ArrX_Buf_init( &dcStack, dcStackX, sizeof(dcStackX) );
793| ArrX_Buf_init( &dcGStack, dcGStackX, sizeof(dcGStackX) );
794|
795| childTags = &m->tags;
796|
797| /* ファイル m を解析する BLex 字句解析ループ */
798| while ( ( c = BLex2_peek( &lex, 0 ) ) != EOF ) {
799| BLex2_Line_fetch( &lexLine, &lex );
800| if ( c == '<' ) {
801| if ( BLex2_peek( &lex, 1 ) != '<' ) {
802| BLex2_getPos( &lex, &pos );
803| StrX_Mem_init( &mem, memX, sizeof(memX) );
804| lexLine.lineNum += BLex2_readHTML( &lex, &tags, &mem, mem2, sizeof(mem2) );
805| s = BLex2_HTMLTags_getName( &tags );
806|
807| /* TEMPLATE タグについて */
808| if ( strcmp( s, "template" ) == 0 ) {
809| if ( ArrX_Buf_getN( &tagStack, RXML_Tag* ) == 0 )
810| pTag = NULL;
811| else
812| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
813|
814| /* TEMPLATE タグの生成 */
815| tag = ListX_addLastMalloc( childTags, RXML_Tag );
816| RXML_Tag_init( tag, "template", ( pTag == NULL ? NULL : *pTag ),
817| m, lexLine.lineNum );
818| RXML_Tag_addAttrFromBLex2( tag, &tags );
819| tag->start = (long)pos;
820|
821| /* RXML タグ・スタックにプッシュする */
822| pTag = ArrX_Buf_alloc( &tagStack, RXML_Tag* );
823| *pTag = tag;
824| childTags = &tag->tags;
825| }
826| else if ( strcmp( s, "/template" ) == 0 ) {
827| int n;
828|
829| /* RXML タグ・スタックからポップする */
830| n = ArrX_Buf_getN( &tagStack, RXML_Tag* );
831| if ( n == 0 ) {
832| error2_0( RXML_Err_Many_EndOfTemplate, "<""/TEMPLATE> が多すぎます" );
833| }
834| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
835| BLex2_getPos( &lex, &(*pTag)->end );
836| ArrX_Buf_free( &tagStack, pTag, RXML_Tag* );
837| if ( n == 1 )
838| childTags = &m->tags;
839| else {
840| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
841| childTags = &((*pTag)->tags);
842| }
843| }
844|
845| /* VAR タグについて */
846| else if ( strcmp( s, "var" ) == 0 ) {
847|
848| /* VAR タグの生成 */
849| if ( ArrX_Buf_getN( &tagStack, RXML_Tag* ) == 0 )
850| pTag = NULL;
851| else
852| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
853| tag = ListX_addLastMalloc( childTags, RXML_Tag );
854| RXML_Tag_init( tag, "var", ( pTag == NULL ? NULL : *pTag ),
855| m, lexLine.lineNum );
856| RXML_Tag_addAttrFromBLex2( tag, &tags );
857| tag->start = (long)pos;
858| BLex2_getPos( &lex, &tag->end );
859| }
860|
861| else {
862| if ( ArrX_Buf_getN( &dcStack, RXML_Tag* ) == 0 ) pTag = NULL;
863| else pTag = ArrX_Buf_getLast( &dcStack, RXML_Tag* );
864|
865| if ( ArrX_Buf_getN( &dcGStack, RXML_Tag* ) == 0 ) pTagG = NULL;
866| else pTagG = ArrX_Buf_getLast( &dcGStack, RXML_Tag* );
867|
868| /* RXML データ・クラスの開始タグについて */
869| if ( s[0] != '/' ) {
870| if ( pTag == NULL ) tag = RXML_File_getDataClass( m, s );
871| else {
872| if ( *pTag == NULL ) tag = NULL;
873| else tag = RXML_Tag_getSubTag2( *pTag, s );
874| }
875|
876| if ( pTagG == NULL ) tagG = RXML_getDataClass( m->top, s );
877| else {
878| if ( *pTagG == NULL ) tagG = NULL;
879| else tagG = RXML_Tag_getSubTag2( *pTagG, s );
880| }
881|
882| if ( tag != NULL || tagG != NULL ) {
883|
884| /* データ・クラス・スタックにプッシュする */
885| pTag = ArrX_Buf_alloc( &dcStack, RXML_Tag* );
886| *pTag = tag;
887| pTagG = ArrX_Buf_alloc( &dcGStack, RXML_Tag* );
888| *pTagG = tagG;
889|
890| /* タグの生成 */
891| if ( ArrX_Buf_getN( &tagStack, RXML_Tag* ) == 0 )
892| pTag = NULL;
893| else
894| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
895| tag = ListX_addLastMalloc( childTags, RXML_Tag );
896| RXML_Tag_init( tag, s, ( pTag == NULL ? NULL : *pTag ),
897| m, lexLine.lineNum );
898| RXML_Tag_addAttrFromBLex2( tag, &tags );
899| tag->start = (long)pos;
900|
901| /* RXML タグ・スタックにプッシュする */
902| pTag = ArrX_Buf_alloc( &tagStack, RXML_Tag* );
903| *pTag = tag;
904| childTags = &tag->tags;
905| }
906| }
907|
908| /* RXML データ・クラスの終了タグについて */
909| else {
910| if ( ( pTag != NULL && *pTag != NULL &&
911| stricmp( (*pTag)->name, s + 1 ) == 0 ) ||
912| ( pTagG != NULL && *pTagG != NULL &&
913| stricmp( (*pTagG)->name, s + 1 ) == 0 ) ) {
914| int n;
915|
916| if ( pTag == NULL ) {
917| error2_3( RXML_Err_Many_EndOfRXMLTag,
918| "<%s> が多すぎます in %s(%d)", s, m->path, lexLine.lineNum );
919| }
920|
921| /* RXML タグ・スタックからポップする */
922| n = ArrX_Buf_getN( &tagStack, RXML_Tag* );
923| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
924| BLex2_getPos( &lex, &(*pTag)->end );
925| ArrX_Buf_free( &tagStack, pTag, RXML_Tag* );
926| if ( n == 1 )
927| childTags = &m->tags;
928| else {
929| pTag = ArrX_Buf_getLast( &tagStack, RXML_Tag* );
930| childTags = &((*pTag)->tags);
931| }
932|
933| /* データ・クラス・スタックからポップする */
934| ArrX_Buf_free( &dcStack, ArrX_Buf_getLast( &dcStack, RXML_Tag* ), RXML_Tag* );
935| ArrX_Buf_free( &dcGStack, ArrX_Buf_getLast( &dcGStack, RXML_Tag* ), RXML_Tag* );
936| }
937| }
938| }
939| }
940| else {
941| do {
942| BLex2_next( &lex, 1 );
943| c = BLex2_peek( &lex, 0 );
944| } while ( c == '<' );
945| }
946| }
947| else
948| BLex2_next( &lex, 1 );
949|
950| BLex2_Line_nextFetch( &lexLine, &lex );
951| }
952|
953| if ( ArrX_Buf_getN( &tagStack, RXML_Tag* ) != 0 ) {
954| RXML_Tag* tag = *ArrX_Buf_getLast( &tagStack, RXML_Tag* );
955| error2_3( RXML_Err_Few_EndOfRXMLTag, "%s(%d):対応する </%s> がありません",
956| m->path, tag->line, tag->tagName );
957| }
958| } c_finally {
959| if ( bLex ) BLex2_finish( &lex );
960| } c_end_finally;
961|}
962|#endif
963|
964|#if ERRORS_DEBUG_FALSE
965|void RXML_File_pickupTags_tagStack_print( ArrX_Buf* m, const char* title )
966|{
967| RXML_Tag** tag;
968|
969| Errors_printf( "tagStack ---------------------------------" );
970| for ( ArrX_Buf_forEach( m, &tag, RXML_Tag* ) ) {
971| Errors_printf( " tag[%p]->tagName = %s in %s(%d)", *tag,
972| (*tag)->tagName, (*tag)->file->path, (*tag)->line );
973| }
974| Errors_printf( "" );
975|}
976|#endif
977|
978|
979|/***********************************************************************
980|* 28. <<< [RXML_File_out] 特定ファイルのドキュメント変換ステップ >>>
981|************************************************************************/
982|void RXML_File_out( RXML_File* m, FILE* out )
983|{
984| FILE* in;
985| bool bIn = false;
986| long in_pos;
987| RXML_Tag* nextTag;
988| ArrX_Buf tmpStack; /* テンプレート・スタック、RXML_Tag* 型配列 */
989| RXML_Tag* tmpStackX[32];
990| RXML_Out outSet;
991|
992| c_try {
993|
994| #if ERRORS_DEBUG_FALSE
995| Errors_startPool();
996| Errors_printf( "RXML read from %s", m->path );
997| #endif
998|
999| in = FileX_open( m->path, "rb" ); bIn = true;
1000| ArrX_Buf_init( &tmpStack, tmpStackX, sizeof(tmpStackX) );
1001|
1002| outSet.top = m->top;
1003| outSet.basePath = (char*)m->path;
1004| outSet.in = in;
1005| outSet.out = out;
1006| outSet.tmps = &tmpStack;
1007| outSet.bTopSpcs = true;
1008| outSet.topSpcs[0] = '\0';
1009|
1010| in_pos = 0;
1011| nextTag = ListX_getFirst( &m->tags, RXML_Tag );
1012| while ( nextTag != NULL ) {
1013|
1014| /* 最初または次のタグまで出力する */
1015| RXML_Out_outPart( &outSet, in_pos, RXML_POSRET( nextTag->start ) );
1016|
1017| /* タグ(開始タグ〜終了タグ)を出力する */
1018| in_pos = RXML_Tag_out( nextTag, &outSet );
1019|
1020| nextTag = (RXML_Tag*)ListX_Elem_getNext( nextTag );
1021| }
1022|
1023| /* ファイルの最後まで出力する */
1024| RXML_Out_outPart( &outSet, in_pos, -1 );
1025| }
1026| c_finally {
1027| if ( bIn ) fclose( in );
1028|
1029| #if ERRORS_DEBUG_FALSE
1030| Errors_endPool();
1031| #endif
1032| } c_end_finally;
1033|}
1034|
1035|/***********************************************************************
1036|* 29. <<< [RXML_File_getTag] タグを取得する >>>
1037|************************************************************************/
1038|RXML_Tag* RXML_File_getTag( RXML_File* m, const char* tagName )
1039|{
1040| RXML_Tag* tag;
1041| char* tagName2 = StrX_MemV2_alloc( &RXML_db.dic, tagName );
1042|
1043| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
1044| if ( tagName2 == tag->tagName ) return tag;
1045| }
1046| return NULL;
1047|}
1048|
1049|
1050|/***********************************************************************
1051|* 30. <<< [RXML_File_getDataClass] データクラス(のトップ)を取得する >>>
1052|************************************************************************/
1053|RXML_Tag* RXML_File_getDataClass( RXML_File* m, const char* name )
1054|{
1055| RXML_Tag* tag;
1056| char* name2 = StrX_MemV2_alloc( &RXML_db.dic, name );
1057|
1058| for ( ListX_forEach( &m->dataClasses, &tag, RXML_Tag ) ) {
1059| if ( name2 == tag->name ) return tag;
1060| }
1061| return NULL;
1062|}
1063|
1064|
1065|/***********************************************************************
1066|* 31. <<< [RXML_File_getProgDataRef] プログラムデータの参照を取得する >>>
1067|************************************************************************/
1068|RXML_Tag* RXML_File_getProgDataRef( RXML_File* m, const char* name )
1069|{
1070| RXML_Tag* tag;
1071| char* name2 = StrX_MemV2_alloc( &RXML_db.dic, name );
1072|
1073| for ( ListX_forEach( &m->progDataRef, &tag, RXML_Tag ) ) {
1074| if ( name2 == tag->name ) return tag;
1075| }
1076| return NULL;
1077|}
1078|
1079|
1080|/*--------------------------------------------------------------------*/
1081|/* 32. <<< ◆(RXML_Tag) RXML_Tag へのポインタ >>> */
1082|/*--------------------------------------------------------------------*/
1083|
1084|
1085|/***********************************************************************
1086|* 33. <<< [RXML_Tag_init] 初期化する >>>
1087|************************************************************************/
1088|void RXML_Tag_init( RXML_Tag* m, const char* tagName, RXML_Tag* parent,
1089| RXML_File* file, int line )
1090|{
1091| m->tagName = StrX_MemV2_alloc( &RXML_db.dic, tagName );
1092| m->name = Errors_null;
1093| #ifdef USES_BLEX2
1094| m->start = 0;
1095| m->end = 0;
1096| #else
1097| BLex3_Pos_init( &m->start );
1098| BLex3_Pos_init( &m->end );
1099| #endif
1100| ListX_init( &m->attrs );
1101| ListX_init( &m->tags );
1102| m->loopTag = NULL;
1103| #ifdef USES_SYM
1104| Sym_Ref_init( &m->container, NULL, Sym_NoID, NULL, Sym_NoID, NULL, NULL );
1105| Sym_Ref_init( &m->loopRef, NULL, Sym_NoID, NULL, Sym_NoID, NULL, NULL );
1106| #endif
1107| m->parent = parent;
1108| m->file = file;
1109| m->line = line;
1110|
1111| ERRORS_FINISHCHK_FOR_INIT( RXML_Tag_finish );
1112|}
1113|
1114|
1115|/***********************************************************************
1116|* 34. <<< [RXML_Tag_finish] 後始末する >>>
1117|************************************************************************/
1118|void RXML_Tag_finish( RXML_Tag* m )
1119|{
1120| StrX_ListElem2* str;
1121|
1122| ERRORS_FINISHCHK_FOR_FINISH( RXML_Tag_finish );
1123|
1124| for ( ListX_forEach( &m->attrs, &str, StrX_ListElem2 ) ) {
1125| free( str->data );
1126| }
1127| ListX_finish2( &m->attrs, StrX_ListElem2, NULL );
1128| ListX_finish2( &m->tags, RXML_Tag, RXML_Tag_finish );
1129|}
1130|
1131|
1132|/***********************************************************************
1133|* 35. <<< [RXML_Tag_print] デバッグ表示する >>>
1134|************************************************************************/
1135|#ifndef ERRORS_CUT_DEBUG_TOOL
1136|void RXML_Tag_print( RXML_Tag* m, const char* title )
1137|{
1138| RXML_Tag* tag;
1139| StrX_ListElem2* attr;
1140|
1141| Errors_printf( "%sTagPtr[%p] <%s> ----------------------", title, m, m->tagName );
1142| Errors_printf( "%sname = %s", title, m->name );
1143| for ( ListX_forEach( &m->attrs, &attr, StrX_ListElem2 ) ) {
1144| Errors_printf( "%sattr(%s) = %s", title, attr->p, (char*)attr->data );
1145| }
1146| #ifdef USES_BLEX2
1147| Errors_printf( "%sstart = %ld, end = %ld", title, m->start, m->end );
1148| #else
1149| Errors_printf( "%sstart = %ld, end = %ld", title, m->start.pos, m->end.pos );
1150| #endif
1151| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
1152| Errors_printf( "%schild TagPtr[%p] <%s name=\"%s\">",
1153| title, tag, tag->tagName, tag->name );
1154| }
1155| Errors_printf( "%sloopTag[%p]", title, m->loopTag );
1156| Errors_printf( "%sparent[%p]", title, m->parent );
1157| Errors_printf( "%sfile[%p]", title, m->file );
1158|
1159| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
1160| RXML_Tag_print( tag, title );
1161| }
1162|}
1163|#endif
1164|
1165|/***********************************************************************
1166|* 36. <<< [RXML_Tag_setName] 名前を設定する >>>
1167|************************************************************************/
1168|void RXML_Tag_setName( RXML_Tag* m, const char* name )
1169|{
1170| m->name = StrX_MemV2_alloc( &RXML_db.dic, name );
1171|}
1172|
1173|/***********************************************************************
1174|* 37. <<< [RXML_Tag_addAttr] 属性を追加する >>>
1175|************************************************************************/
1176|void RXML_Tag_addAttr( RXML_Tag* m, const char* name, const char* value )
1177|{
1178| StrX_ListElem2* str;
1179|
1180| str = ListX_addLastMalloc( &m->attrs, StrX_ListElem2 );
1181| str->p = StrX_MemV2_alloc( &RXML_db.dic, name );
1182| str->data = malloc( strlen( value ) + 1 );
1183| strcpy( str->data, value );
1184|}
1185|
1186|
1187|/***********************************************************************
1188|* 38. <<< [RXML_Tag_addAttrFromBLex2] BLex2_HTMLTags から属性を追加する >>>
1189|************************************************************************/
1190|#ifdef USES_BLEX2
1191|void RXML_Tag_addAttrFromBLex2( RXML_Tag* m, BLex2_HTMLTags* tags )
1192|{
1193| char** sp;
1194| char** sp2;
1195| char** sp_over = tags->attr_names + tags->attr_n;
1196|
1197| for ( sp = tags->attr_names, sp2 = tags->attr_vars;
1198| sp < sp_over; sp++, sp2++ ) {
1199| if ( strcmp( *sp, "name" ) == 0 )
1200| RXML_Tag_setName( m, *sp2 );
1201| else
1202| RXML_Tag_addAttr( m, *sp, *sp2 );
1203| }
1204|}
1205|#endif
1206|
1207|/***********************************************************************
1208|* 39. <<< [RXML_Tag_addAttrFromHtmlPars] HtmlPars から属性を追加する >>>
1209|************************************************************************/
1210|#ifdef USES_HTMLPARS
1211|void RXML_Tag_addAttrFromHtmlPars( RXML_Tag* m, HtmlPars* htmlp )
1212|{
1213| char** sp;
1214| char** sp2;
1215| char** sp_over = htmlp->attr_names + htmlp->attr_n;
1216|
1217| for ( sp = htmlp->attr_names, sp2 = htmlp->attr_values;
1218| sp < sp_over; sp++, sp2++ ) {
1219| if ( strcmp( *sp, "name" ) == 0 )
1220| RXML_Tag_setName( m, *sp2 );
1221| else
1222| RXML_Tag_addAttr( m, *sp, *sp2 );
1223| }
1224|}
1225|#endif
1226|
1227|/***********************************************************************
1228|* 40. <<< [RXML_Tag_getAttrValue] 属性の値を参照する >>>
1229|*【引数】
1230|* ・char* attr_name; 属性名
1231|* ・char* 返り値; 属性の値(文字列型)NULL=属性が見つからない
1232|************************************************************************/
1233|char* RXML_Tag_getAttrValue( RXML_Tag* m, const char* attr_name )
1234|{
1235| StrX_ListElem2* str;
1236| char* attr_name2 = StrX_MemV2_alloc( &RXML_db.dic, attr_name );
1237|
1238| for ( ListX_forEach( &m->attrs, &str, StrX_ListElem2 ) ) {
1239| if ( str->p == attr_name2 ) return str->data;
1240| }
1241| return NULL;
1242|}
1243|
1244|
1245|/***********************************************************************
1246|* 41. <<< [RXML_Tag_getSubTag] ツリーの子のタグを返す(タグ名指定)>>>
1247|*【引数】
1248|* ・char* tagName; タグ名
1249|* ・RXML_Tag* 返り値; ツリーの子のタグ、NULL=タグが見つからない
1250|************************************************************************/
1251|RXML_Tag* RXML_Tag_getSubTag( RXML_Tag* m, const char* tagName )
1252|{
1253| RXML_Tag* tag;
1254| char* tagName2 = StrX_MemV2_alloc( &RXML_db.dic, tagName );
1255|
1256| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
1257| if ( tagName2 == tag->tagName ) return tag;
1258| }
1259| return NULL;
1260|}
1261|
1262|
1263|/***********************************************************************
1264|* 42. <<< [RXML_Tag_getSubTag2] ツリーの子のタグを返す(name属性指定) >>>
1265|*【引数】
1266|* ・char* name; name 属性の値
1267|* ・RXML_Tag* 返り値; ツリーの子のタグ、NULL=タグが見つからない
1268|************************************************************************/
1269|RXML_Tag* RXML_Tag_getSubTag2( RXML_Tag* m, const char* name )
1270|{
1271| RXML_Tag* tag;
1272| char* name2 = StrX_MemV2_alloc( &RXML_db.dic, name );
1273|
1274| for ( ListX_forEach( &m->tags, &tag, RXML_Tag ) ) {
1275| if ( name2 == tag->name ) return tag;
1276| }
1277|
1278| return NULL;
1279|}
1280|
1281|
1282|/***********************************************************************
1283|* 43. <<< [RXML_Tag_getNextSameTag] 同じタグ名の次のタグを返す >>>
1284|*【引数】
1285|* ・RXML_Tag* 返り値; 同じタグ名の次のタグ、NULL=同じタグ名のは無い
1286|************************************************************************/
1287|RXML_Tag* RXML_Tag_getNextSameTag( RXML_Tag* m )
1288|{
1289| RXML_Tag* tag;
1290| ListX* tags;
1291| bool b;
1292|
1293| if ( m->parent == NULL )
1294| tags = &m->file->tags;
1295| else
1296| tags = &m->parent->tags;
1297|
1298| b = false;
1299| for ( ListX_forEach( tags, &tag, RXML_Tag ) ) {
1300| if ( ! b ) {
1301| if ( tag == m ) b = true;
1302| continue;
1303| }
1304| if ( tag->tagName == m->tagName )
1305| return tag;
1306| }
1307|
1308| return NULL;
1309|}
1310|
1311|
1312|/***********************************************************************
1313|* 44. <<< [RXML_Tag_out] タグを変換した内容をファイルに出力する >>>
1314|*【引数】
1315|* ・long 返り値; 出力後の入力ファイルのアドレス
1316|*【補足】
1317|*・VAR タグと TEMPLATE タグの変換も行います。
1318|* 参照:RXML_Tag_outVar(), RXML_Tag_outTemplate()
1319|************************************************************************/
1320|long RXML_Tag_out( RXML_Tag* m, RXML_Out* out )
1321|{
1322| long ret;
1323|
1324| #if ERRORS_DEBUG_FALSE
1325| static int level = 0;
1326|
1327| level ++;
1328| #if defined( USES_BLEX2 )
1329| Errors_printf( " [Lv %d] Start pos= 0x%lX 〜 0x%lX: tagName = %s",
1330| level, m->start, m->end, m->tagName );
1331| #elif defined( USES_BLEX3 )
1332| Errors_printf( " [Lv %d] Start pos= 0x%lX 〜 0x%lX: tagName = %s",
1333| level, m->start.pos, m->end.pos, m->tagName );
1334| #endif
1335| #endif
1336|
1337| if ( strcmp( m->tagName, "template" ) == 0 ) {
1338| ret = RXML_Tag_outTemplate( m, out );
1339| }
1340| else if ( strcmp( m->tagName, "var" ) == 0 ) {
1341| ret = RXML_Tag_outVar( m, out );
1342| }
1343| else {
1344| ret = RXML_Tag_outThrough( m, out );
1345| }
1346|
1347| #if ERRORS_DEBUG_FALSE
1348| #if defined( USES_BLEX2 )
1349| Errors_printf( " [Lv %d] End pos= 0x%lX 〜 0x%lX: tagName = %s",
1350| level, m->start, m->end, m->tagName );
1351| #elif defined( USES_BLEX3 )
1352| Errors_printf( " [Lv %d] End pos= 0x%lX 〜 0x%lX: tagName = %s",
1353| level, m->start.pos, m->end.pos, m->tagName );
1354| #endif
1355| level --;
1356| #endif
1357|
1358| return ret;
1359|}
1360|
1361|
1362|/***********************************************************************
1363|* 45. <<< [RXML_Tag_outThrough] タグの内容をそのままファイルに出力する >>>
1364|*【引数】
1365|* ・long 返り値; 出力後の入力ファイルのアドレス
1366|************************************************************************/
1367|long RXML_Tag_outThrough( RXML_Tag* m, RXML_Out* out )
1368|{
1369| RXML_Tag* nextTag;
1370| long in_pos;
1371|
1372| RXML_Out_outStrong( out );
1373|
1374| #ifdef USES_BLEX2
1375| in_pos = m->start;
1376| #else
1377| in_pos = m->start.pos;
1378| #endif
1379| nextTag = ListX_getFirst( &m->tags, RXML_Tag );
1380| while ( nextTag != NULL ) {
1381|
1382| /* 最初または次のタグまで出力する */
1383| #ifdef USES_BLEX2
1384| FileX_outPart( out->out, out->in, in_pos, nextTag->start );
1385| #else
1386| FileX_outPart( out->out, out->in, in_pos, nextTag->start.pos );
1387| #endif
1388|
1389| /* ネストしたタグ(開始タグ〜終了タグ)を出力する */
1390| in_pos = RXML_Tag_out( nextTag, out );
1391|
1392| nextTag = (RXML_Tag*)ListX_Elem_getNext( nextTag );
1393| }
1394|
1395| /* タグの最後まで出力する */
1396| #ifdef USES_BLEX2
1397| FileX_outPart( out->out, out->in, in_pos, m->end );
1398| #else
1399| FileX_outPart( out->out, out->in, in_pos, m->end.pos );
1400| #endif
1401|
1402| #ifdef USES_BLEX2
1403| return m->end;
1404| #else
1405| return m->end.pos;
1406| #endif
1407|}
1408|
1409|/***********************************************************************
1410|* 46. <<< [RXML_Tag_outVar] VAR タグの内容を変換してファイルに出力する >>>
1411|*【引数】
1412|* ・RXML* rxml; m が所属するトップ
1413|* ・long 返り値; 出力後の入力ファイルのアドレス
1414|*【補足】
1415|*・内部で Sym_getRef 関数を使用しているので、VAR タグをプログラムデータに
1416|* 変換することもできます。
1417|************************************************************************/
1418|long RXML_Tag_outVar( RXML_Tag* m, RXML_Out* out )
1419|{
1420| char* href;
1421| char* interval;
1422| RXML_Tag* refTag;
1423|
1424| interval = RXML_Tag_getAttrValue( m, "interval" );
1425| href = RXML_Tag_getAttrValue( m, "href" );
1426|
1427| #if ERRORS_DEBUG_FALSE
1428| if ( strstr( href, "mxp.multi" ) != NULL )
1429| Errors_break(1);
1430| #endif
1431|
1432| /* インターバル(次の要素が無ければ出力しない) */
1433| if ( interval != NULL ) {
1434| #ifdef USES_SYM
1435| refTag = RXML_getLoopTmp( interval, out->tmps );
1436| if ( refTag == NULL ) return RXML_POSRET(m->end);
1437|
1438| if ( refTag->loopTag == NULL ) {
1439| Sym_Ref ref = refTag->loopRef;
1440|
1441| if ( ! Sym_Ref_getNext( &refTag->container, &ref ) )
1442| return RXML_POSRET(m->end);
1443| }
1444| else {
1445| #endif
1446|
1447| refTag = RXML_getHrefTag( out->top, interval, out->basePath, out->tmps );
1448| if ( refTag == NULL || RXML_Tag_getNextSameTag( refTag ) == NULL ) {
1449| return RXML_POSRET( m->end );
1450| }
1451|
1452| #ifdef USES_SYM
1453| }
1454| #endif
1455| }
1456|
1457| /* value 属性の値をそのまま出力する */
1458| if ( href == NULL ) {
1459| char* value;
1460|
1461| value = RXML_Tag_getAttrValue( m, "value" );
1462| if ( value == NULL )
1463| RXML_Tag_outThrough( m, out );
1464| else
1465| fputs( value, out->out );
1466| }
1467|
1468| /* href 属性で参照している内容を出力する */
1469| else {
1470| #ifdef USES_SYM
1471| Sym_Ref ref;
1472| bool bOut = false;
1473| static char strX[4096];
1474| char* str = strX;
1475| int str_size = sizeof(strX);
1476|
1477| c_try {
1478| if ( RXML_getHrefRef( href, out->tmps, &ref ) ) {
1479| int size = Sym_Ref_getStringSize( &ref );
1480|
1481| if ( size > str_size ) { str = malloc( size ); str_size = size; }
1482|
1483| Sym_Ref_getString( &ref, str, str_size );
1484| bOut = true;
1485| }
1486| }
1487| c_catch ( Errors_Msg*, msg ) {
1488| if ( msg->code == Sym_Err_NullAsign ) {
1489| strcpy( str, msg->msg );
1490| bOut = true;
1491| }
1492| else {
1493| if ( str_size > sizeof(strX) ) free( str );
1494| c_throw_again();
1495| }
1496| } c_end_catch;
1497| if ( bOut ) {
1498| RXML_Out_outStrong( out );
1499| fputs( str, out->out );
1500| if ( str_size > sizeof(strX) ) free( str );
1501| return RXML_POSRET(m->end);
1502| }
1503| if ( str_size > sizeof(strX) ) free( str );
1504| #endif
1505|
1506| refTag = RXML_getHrefTag( out->top, href, out->basePath, out->tmps );
1507|
1508| /* 参照しているタグの内容を出力する */
1509| if ( refTag != NULL ) {
1510| FILE* in;
1511| bool bIn = false;
1512|
1513| c_try {
1514| in = out->in;
1515| out->in = FileX_open( refTag->file->path, "rb" ); bIn = true;
1516| RXML_Out_outStrong( out );
1517| RXML_Tag_outText( refTag, out );
1518| }
1519| c_finally {
1520| if ( bIn ) { fclose( out->in ); out->in = in; }
1521| } c_end_finally;
1522| }
1523|
1524| /* 参照しているファイルの内容を出力する */
1525| else {
1526| RXML_File* refFile;
1527| refFile = RXML_getHrefFile( out->top, href, out->basePath, false );
1528|
1529| if ( refFile != NULL && strchr( href, '#' ) == NULL )
1530| RXML_File_out( refFile, out->out );
1531| else
1532| RXML_Tag_outThrough( m, out );
1533| }
1534| }
1535|
1536| #ifdef USES_BLEX2
1537| return m->end;
1538| #else
1539| return m->end.pos;
1540| #endif
1541|}
1542|
1543|
1544|/***********************************************************************
1545|* 47. <<< [RXML_Tag_outTemplate] TEMPLATE タグの内容を変換してファイルに出力する >>>
1546|*【引数】
1547|* ・long 返り値; 出力後の入力ファイルのアドレス
1548|************************************************************************/
1549|long RXML_Tag_outTemplate( RXML_Tag* m, RXML_Out* out )
1550|{
1551| char* href;
1552|
1553| href = RXML_Tag_getAttrValue( m, "href" );
1554|
1555| #if ERRORS_DEBUG_FALSE
1556| if ( strstr( href, "makeOrder" ) != NULL )
1557| Errors_break(1);
1558| #endif
1559|
1560| if ( href == NULL )
1561| RXML_Tag_outThrough( m, out );
1562|
1563| else {
1564| RXML_Tag* refTag;
1565| RXML_Tag** pTag;
1566|
1567| /* プログラムデータの集合に対するループ処理を行う */
1568| #ifdef USES_SYM
1569| {
1570| if ( RXML_getHrefRef( href, out->tmps, &m->container ) ) {
1571| bool bRet = false;
1572| c_try {
1573| pTag = ArrX_Buf_alloc( out->tmps, RXML_Tag* );
1574| *pTag = m;
1575|
1576| for ( Sym_Ref_forEach( &m->container, &m->loopRef ) ) {
1577| RXML_Tag_outText( m, out );
1578| }
1579| ArrX_Buf_free( out->tmps, pTag, RXML_Tag* );
1580| bRet = true;
1581|
1582| } Errors_ignore_catch( case Sym_Err_NotFindSymbol:
1583| case Sym_Err_ManyNest: );
1584|
1585| if ( bRet ) return RXML_POSRET(m->end);
1586| }
1587| }
1588| #endif
1589|
1590| /* タグの集合に対するループ処理を行う */
1591| refTag = RXML_getHrefTag( out->top, href, out->basePath, out->tmps );
1592|
1593| if ( refTag != NULL ) {
1594| m->loopTag = refTag;
1595| pTag = ArrX_Buf_alloc( out->tmps, RXML_Tag* );
1596| *pTag = m;
1597|
1598| do {
1599| RXML_Tag_outText( m, out );
1600|
1601| m->loopTag = RXML_Tag_getNextSameTag( m->loopTag );
1602| } while( m->loopTag != NULL );
1603|
1604| ArrX_Buf_free( out->tmps, pTag, RXML_Tag* );
1605| }
1606| else
1607| RXML_Tag_outThrough( m, out );
1608| }
1609|
1610| #ifdef USES_BLEX2
1611| return m->end;
1612| #else
1613| return m->end.pos;
1614| #endif
1615|}
1616|
1617|/***********************************************************************
1618|* 48. <<< [RXML_Tag_outText] タグの間のテキストをファイルに出力する >>>
1619|*【引数】
1620|* ・long 返り値; 出力後の入力ファイルのアドレス
1621|************************************************************************/
1622|long RXML_Tag_outText( RXML_Tag* m, RXML_Out* out )
1623|{
1624| RXML_Tag* nextTag;
1625| long in_pos;
1626| int c;
1627|
1628| /* 最初のタグをスキップする */
1629| #ifdef USES_BLEX2
1630| fseek( out->in, m->start, SEEK_SET );
1631| #else
1632| fseek( out->in, m->start.pos, SEEK_SET );
1633| #endif
1634| for (;;) {
1635| c = fgetc( out->in );
1636| if ( c == '>' ) break;
1637| ASSERT( ! feof( out->in ) );
1638| }
1639|
1640| /* 開始タグのみの行をスキップする(→開始・終了タグ・行スキップ処理)*/
1641| if ( out->bTopSpcs ) {
1642| in_pos = ftell( out->in );
1643| for (;;) {
1644| c = fgetc( out->in );
1645| if ( c == '\n' ) break; /* skip */
1646| if ( c != ' ' && c != '\t' && c != '\r' ) { /* not skip */
1647| fputs( out->topSpcs, out->out );
1648| FileX_outPart( out->out, out->in, in_pos, ftell( out->in ) );
1649| break;
1650| }
1651| }
1652| }
1653|
1654| in_pos = ftell( out->in );
1655| nextTag = ListX_getFirst( &m->tags, RXML_Tag );
1656| while ( nextTag != NULL ) {
1657|
1658| /* 最初または次のタグまで出力する */
1659| #ifdef USES_BLEX2
1660| RXML_Out_outPart( out, in_pos, nextTag->start );
1661| #else
1662| RXML_Out_outPart( out, in_pos, nextTag->start.pos );
1663| #endif
1664|
1665| /* ネストしたタグ(開始タグ〜終了タグ)を出力する */
1666| in_pos = RXML_Tag_out( nextTag, out );
1667|
1668| nextTag = (RXML_Tag*)ListX_Elem_getNext( nextTag );
1669| }
1670|
1671| /* 終了タグの前まで出力する */
1672|#if 0 /* 2001/03/02 02:01 */
1673| {
1674| long pos;
1675| int n; /* m->tagName[n], 終了タグを出力しないため */
1676|
1677| n = -2;
1678| out->bTopSpcs = false;
1679| fseek( out->in, in_pos, SEEK_SET );
1680| #ifdef USES_BLEX2
1681| for ( ; in_pos < m->end; in_pos ++ )
1682| #else
1683| for ( ; in_pos < m->end.pos; in_pos ++ )
1684| #endif
1685| {
1686| c = fgetc( out->in );
1687|
1688| /* 終了タグ認識中の処理 */
1689| if ( n == -1 ) {
1690| if ( c == '/' ) n = 0;
1691| else {
1692| FileX_outPart( out->out, out->in, pos, in_pos );
1693| fseek( out->in, +1, SEEK_CUR );
1694| n = -2;
1695| }
1696| }
1697| else if ( n >= 0 ) {
1698| if ( tolower( c ) == tolower( m->tagName[n] ) )
1699| n++;
1700| else {
1701| if ( c == '>' && m->tagName[n] == '\0' )
1702| { n = -2; break; } /* 出力の終了 */
1703| FileX_outPart( out->out, out->in, pos, in_pos );
1704| fseek( out->in, +1, SEEK_CUR );
1705| out->bTopSpcs = false;
1706| n = -2;
1707| }
1708| }
1709|
1710| /* 終了タグから行頭までの空白を取っておく(→開始・終了タグ・行スキップ処理)*/
1711| if ( n <= -3 ) {
1712| if ( c == '<' )
1713| { out->topSpcs[-n-3] = '\0'; n = -1; }
1714| else if ( c == ' ' || c == '\t' || c == '\r' )
1715| { out->topSpcs[-n-3] = c; n--; }
1716| else {
1717| FileX_outPart( out->out, out->in, pos, in_pos );
1718| fseek( out->in, +1, SEEK_CUR );
1719| out->bTopSpcs = false;
1720| n = -2;
1721| }
1722| }
1723|
1724| /* 通常の出力 */
1725| if ( n == -2 ) {
1726| if ( c == '<' ) { pos = in_pos; n = -1; }
1727| else {
1728| fputc( c, out->out );
1729| if ( c == '\n' ) {
1730| pos = in_pos + 1;
1731| out->bTopSpcs = true; out->bStrongOut = false;
1732| n = -3;
1733| }
1734| }
1735| }
1736| }
1737| if ( n > -2 ) {
1738| #ifdef USES_BLEX2
1739| FileX_outPart( out->out, out->in, pos, m->end );
1740| #else
1741| FileX_outPart( out->out, out->in, pos, m->end.pos );
1742| #endif
1743| }
1744| }
1745| #ifdef USES_BLEX2
1746| return m->end;
1747| #else
1748| return m->end.pos;
1749| #endif
1750|#else
1751|
1752| /* 終了タグの前まで出力する */
1753| /* ただし、KWORD タグは出力しない */
1754| {
1755| BLex3_EngineU lexU;
1756| BLex3_Engine* lex = &lexU.inherit_BLex3_Engine;
1757| BLex3_Pos lex_pos;
1758| int maxlen;
1759| int tag_len;
1760| int kword_len;
1761| char* fp;
1762| char* kword = "kword";
1763| char buf[512+1];
1764| char buf2[512+1];
1765|
1766| /* in_pos の位置から始まる lex を初期化する */
1767| tag_len = strlen( m->tagName );
1768| kword_len = strlen( kword );
1769| if ( tag_len < kword_len ) maxlen = kword_len + 1;
1770| else maxlen = tag_len + 1;
1771|
1772| BLex3_Engine_init( lex, m->file->path /*out->basePath*/, buf, sizeof(buf), 256 );
1773| BLex3_Engine_setSJisBuf( lex, buf2, sizeof(buf2) );
1774|
1775| lex_pos.pos = in_pos;
1776| lex_pos.sjis_type = BLex3_Ascii;
1777| BLex3_Engine_setPos( lex, &lex_pos );
1778|
1779| for (;;) {
1780| BLex3_EngineU_skipTo( &lexU, "<", +1 );
1781|
1782| fp = BLex3_Engine_getFilePtr( lex, maxlen );
1783| if ( fp == NULL ) {
1784| FileX_outPart( out->out, out->in, in_pos, RXML_POSRET( m->end ) );
1785| break;
1786| }
1787|
1788| if ( *BLex3_Engine_getSJisPtr( lex ) == BLex3_Ascii ) {
1789|
1790| /* 終了タグなら、その直前まで出力して関数を抜ける */
1791| if ( fp[0] == '/' &&
1792| strnicmp( fp + 1, m->tagName, tag_len ) == 0 &&
1793| fp[tag_len + 1] == '>' ) {
1794| long endPos = RXML_POSRET( m->end );
1795|
1796| BLex3_Engine_getPos( lex, &lex_pos );
1797| if ( lex_pos.pos - 1 < endPos )
1798| RXML_Out_outPart( out, in_pos, lex_pos.pos - 1 );
1799| //FileX_outPart( out->out, out->in, in_pos, lex_pos.pos - 1 );
1800| else
1801| RXML_Out_outPart( out, in_pos, RXML_POSRET( m->end ) );
1802| //FileX_outPart( out->out, out->in, in_pos, RXML_POSRET( m->end ) );
1803| break;
1804| }
1805|
1806| /* KWORD タグなら、そのタグを出力しない(タグの前まで出力) */
1807| else if ( ( strnicmp( fp, kword, kword_len ) == 0 &&
1808| fp[kword_len] == '>' ) ||
1809| ( fp[0] == '/' &&
1810| strnicmp( fp + 1, kword, kword_len ) == 0 &&
1811| fp[kword_len + 1] == '>' ) ) {
1812| long endPos = RXML_POSRET( m->end );
1813| BLex3_Engine_getPos( lex, &lex_pos );
1814| if ( lex_pos.pos - 1 < endPos )
1815| RXML_Out_outPart( out, in_pos, lex_pos.pos - 1 );
1816| //FileX_outPart( out->out, out->in, in_pos, lex_pos.pos - 1 );
1817| else {
1818| RXML_Out_outPart( out, in_pos, RXML_POSRET( m->end ) );
1819| //FileX_outPart( out->out, out->in, in_pos, RXML_POSRET( m->end ) );
1820| break;
1821| }
1822|
1823| in_pos = lex_pos.pos + kword_len + 1;
1824| if ( fp[0] == '/' ) in_pos += 1;
1825| BLex3_Engine_next( lex, kword_len + 1 );
1826| }
1827| else
1828| BLex3_Engine_next( lex, +1 );
1829| }
1830| else
1831| BLex3_Engine_next( lex, +1 );
1832| }
1833|
1834| BLex3_Engine_finish( lex );
1835| }
1836|
1837| #ifdef USES_BLEX2
1838| return m->end;
1839| #else
1840| return m->end.pos;
1841| #endif
1842|#endif
1843|}
1844|
1845|
1846|/*--------------------------------------------------------------------*/
1847|/* 49. <<< ◆(RXML_TagInf) RXML データ・オブジェクト・インターフェイス >>> */
1848|/*--------------------------------------------------------------------*/
1849|
1850|
1851|/***********************************************************************
1852|* 50. <<< RXML_TagInf インターフェイス・関数定義 >>>
1853|************************************************************************/
1854|#ifndef NDEBUG
1855|INF_FUNC_0( RXML_TagInf, finish, void, RXML_TagInf_finish, RXML_TagInf, t )
1856|INF_FUNC_1( RXML_TagInf, print, void, RXML_TagInf_print, RXML_TagInf, const char*, t,a )
1857|INF_FUNC_R0( RXML_TagInf, getAttrVar, char*, RXML_TagInf_getAttrVar, RXML_TagInf,t )
1858|INF_FUNC_R0( RXML_TagInf, getFirstAttrInf, RXML_AttrInf, RXML_TagInf_getFirstAttrInf, RXML_TagInf, t )
1859|#endif
1860|
1861|
1862|/*--------------------------------------------------------------------*/
1863|/* 51. <<< ◆(RXML_AttrInf] 属性・インターフェイス >>> */
1864|/*--------------------------------------------------------------------*/
1865|
1866|
1867|/***********************************************************************
1868|* 52. <<< RXML_AttrInf インターフェイス・関数定義 >>>
1869|************************************************************************/
1870|#ifndef NDEBUG
1871|INF_FUNC_1( RXML_AttrInf, print, void, RXML_AttrInf_print, RXML_AttrInf, const char*, t,a )
1872|INF_FUNC_R0( RXML_AttrInf, getVar, char*, RXML_AttrInf_getVar, RXML_AttrInf,t )
1873|INF_FUNC_R0( RXML_AttrInf, getNextAttrInf, RXML_AttrInf, RXML_AttrInf_getNextAttrInf, RXML_AttrInf, t )
1874|#endif
1875|
1876|
1877|/*--------------------------------------------------------------------*/
1878|/* 53. <<< ◆(RXML_Out) >>> */
1879|/*--------------------------------------------------------------------*/
1880|
1881|/***********************************************************************
1882|* 54. <<< [RXML_Out_outPart] ファイルの一部を出力する(行スキップ考慮) >>>
1883|*【引数】
1884|* ・long 返り値; 出力後の入力ファイルアドレス(EOF あり)
1885|*【補足】
1886|*・初めて出力するときは、m->bTopSpcs = false を設定しておいてください。
1887|*・ファイルの末尾まで出力するときは endPos = -1 を指定してください。
1888|*・開始・終了タグ・行スキップ処理を含んでいます。
1889|************************************************************************/
1890|long RXML_Out_outPart( RXML_Out* m, long in_pos, long endPos )
1891|{
1892| long pos;
1893| int c = 0;
1894| int i = ( m->bTopSpcs ? strlen( m->topSpcs ) : -1 );
1895|
1896| fseek( m->in, in_pos, SEEK_SET );
1897| if ( endPos == -1 )
1898| endPos = 0x7FFFFFFF;
1899|
1900| /* 終了タグから行末までの空白と改行を出力するかスキップする */
1901| if ( m->bTopSpcs ) {
1902| i = strlen( m->topSpcs );
1903| for ( ; in_pos < endPos; in_pos++ ) {
1904| c = fgetc( m->in );
1905| if ( c == '\n' ) { /* skip */
1906| in_pos ++;
1907| i = -1; m->bTopSpcs = false; break;
1908| }
1909| else if ( c != ' ' && c != '\t' && c != '\r' ) { /* not skip */
1910| m->topSpcs[i] = '\0';
1911| fputs( m->topSpcs, m->out );
1912| fseek( m->in, -1, SEEK_CUR );
1913| i = -1; m->bTopSpcs = false; break;
1914| }
1915| else {
1916| m->topSpcs[i] = c; i++;
1917| }
1918| }
1919| }
1920| if ( c == EOF ) return EOF;
1921|
1922| /* ファイルの一部を出力する */
1923| if ( endPos == 0x7FFFFFFF ) {
1924| fseek( m->in, 0, SEEK_END );
1925| FileX_outPart( m->out, m->in, in_pos, ftell( m->in ) + 1 );
1926| return EOF;
1927| }
1928|
1929| /* 同時に、行頭から開始タグまでの空白を取っておく */
1930| for ( pos = in_pos; pos < endPos; pos ++ ) {
1931| c = fgetc( m->in );
1932| if ( i >= 0 ) {
1933| if ( c == ' ' || c == '\t' || c == '\r' ) {
1934| m->topSpcs[i] = c;
1935| i++;
1936| }
1937| else {
1938| m->topSpcs[i] = '\0';
1939| fputs( m->topSpcs, m->out );
1940| m->bTopSpcs = false;
1941| i = -1;
1942| }
1943| }
1944| if ( i == -1 ) {
1945| fputc( c, m->out );
1946| if ( c == '\n' ) {
1947| m->bTopSpcs = true; m->bStrongOut = false;
1948| i = 0;
1949| }
1950| }
1951| }
1952| if ( i >= 0 )
1953| m->topSpcs[i] = '\0';
1954|
1955| return in_pos;
1956|}
1957|
1958|/***********************************************************************
1959|* 55. <<< [RXML_Out_outStrong] 行スキップをしないようにする >>>
1960|*【補足】
1961|*・行頭からの空白も出力します。
1962|************************************************************************/
1963|void RXML_Out_outStrong( RXML_Out* m )
1964|{
1965| if ( m->bTopSpcs ) {
1966| fputs( m->topSpcs, m->out );
1967| m->bTopSpcs = false;
1968| }
1969|}
1970|
1971|/*--------------------------------------------------------------------*/
1972|/* 56. <<< ◆(RXML_DCGet) RXML データ・クラス取得・アクター >>> */
1973|/*--------------------------------------------------------------------*/
1974|
1975|
1976|/***********************************************************************
1977|* 57. <<< [RXML_DCGet_init] 初期化する >>>
1978|*【補足】
1979|*・in_path は、内部でリンクしているので、削除のタイミングに注意してください。
1980|************************************************************************/
1981|#ifdef USES_RXML_ACTOR
1982|void RXML_DCGet_init( RXML_DCGet* m, HtmlPars* htmlp, LineCnt* linep,
1983| RXML_File* rxmlFile )
1984|{
1985| m->engU = htmlp->engU;
1986| m->htmlp = htmlp;
1987| m->linep = linep;
1988|
1989| m->rxmlFile = rxmlFile;
1990| m->rxmlTop = rxmlFile->top;
1991| ArrX_Buf_init( &m->tmpStack, m->tmpStackX, sizeof(m->tmpStackX) );
1992|}
1993|#endif
1994|
1995|
1996|/***********************************************************************
1997|* 58. <<< [RXML_DCGet_act] RXML データ・クラス取得を実行する >>>
1998|************************************************************************/
1999|#ifdef USES_RXML_ACTOR
2000|void RXML_DCGet_act( RXML_DCGet* m )
2001|{
2002| HtmlPars* htmlp = m->htmlp;
2003| char* name;
2004|
2005| if ( HtmlPars_getTokenType( htmlp ) != HtmlPars_StartOfTag )
2006| return;
2007|
2008| name = HtmlPars_getName( htmlp );
2009|
2010| /* VAR タグの処理のために、テンプレート・スタックを調節する */
2011| if ( strcmp( name, "template" ) == 0 ) {
2012| char* href;
2013| char* arg;
2014| RXML_Tag* parentTag;
2015| RXML_Tag* tag;
2016| RXML_Tag** pTag;
2017|
2018| /* テンプレート・スタックにプッシュする(VAR タグの処理のため) */
2019| parentTag = ( ArrX_Buf_isEmpty( &m->tmpStack ) ) ?
2020| NULL : *ArrX_Buf_getLast( &m->tmpStack, RXML_Tag* );
2021| pTag = ArrX_Buf_alloc( &m->tmpStack, RXML_Tag* );
2022| tag = malloc( sizeof(RXML_Tag) );
2023| *pTag = tag;
2024| RXML_Tag_init( tag, "template", parentTag, m->rxmlFile,
2025| m->linep->iLine );
2026| href = HtmlPars_getValue( m->htmlp, "href" );
2027| if ( href != NULL ) RXML_Tag_addAttr( tag, "href", href );
2028| arg = HtmlPars_getValue( m->htmlp, "arg" );
2029| if ( arg != NULL ) RXML_Tag_addAttr( tag, "arg", arg );
2030| }
2031|
2032| else if ( strcmp( name, "/template" ) == 0 ) {
2033| int n;
2034| RXML_Tag** pTag;
2035|
2036| /* テンプレート・スタックからポップする */
2037| n = ArrX_Buf_getN( &m->tmpStack, RXML_Tag* );
2038| if ( n == 0 ) {
2039| error2_2( RXML_Err_Many_EndOfTemplate,
2040| "<""/TEMPLATE> が多すぎます(file=%s, line=%d)",
2041| m->rxmlFile->path, m->linep->iLine );
2042| }
2043| pTag = ArrX_Buf_getLast( &m->tmpStack, RXML_Tag* );
2044| RXML_Tag_finish( *pTag );
2045| free( *pTag );
2046| ArrX_Buf_free( &m->tmpStack, pTag, RXML_Tag* );
2047| }
2048|
2049| /* VAR タグの href 属性から RXML データ・クラスを構築する */
2050| else if ( strcmp( name, "var" ) == 0 ) {
2051| char* href;
2052| char* pHref;
2053| char fullHref[RXML_HrefSize];
2054| char tagName[RXML_NameSize];
2055|
2056| /* href 属性が無いときは何もしない */
2057| href = HtmlPars_getValue( m->htmlp, "href" );
2058| if ( href == NULL ) return;
2059|
2060| /* TEMPLATE タグの href 属性も踏まえた参照アドレスを fullHref に取得する */
2061| RXML_getFullHref( href, &m->tmpStack, fullHref, sizeof(fullHref) );
2062|
2063| /* href の値の先頭がファイルパスのとき */
2064| pHref = strchr( fullHref, '#' );
2065| if ( pHref != NULL ) {
2066| RXML_Tag* parentTag = NULL;
2067|
2068| /* パスが "all" のとき、全ファイルのデータクラスのトップを登録する */
2069| if ( strnicmp( fullHref, "all#", 4 ) == 0 ) {
2070|
2071| StrX_wordCpy( tagName, sizeof(tagName), pHref + 1, '.' );
2072| pHref = strchr( pHref + 1, '.' );
2073| parentTag = RXML_getDataClass( m->rxmlTop, tagName );
2074| if ( parentTag == NULL ) {
2075| parentTag = ListX_addLastMalloc( &m->rxmlTop->dataClasses, RXML_Tag );
2076| RXML_Tag_init( parentTag, "DC", NULL, m->rxmlFile, m->linep->iLine );
2077| RXML_Tag_setName( parentTag, tagName );
2078| }
2079| }
2080|
2081| /* ★一般のファイルパスのとき、ファイルのデータクラスのトップを登録する */
2082| else {
2083| RXML_File* file;
2084|
2085| c_try {
2086| file = RXML_getHrefFile( m->rxmlTop, fullHref,
2087| m->rxmlFile->path, true );
2088| StrX_wordCpy( tagName, sizeof(tagName), pHref + 1, '.' );
2089| pHref = strchr( pHref + 1, '.' );
2090| parentTag = RXML_File_getDataClass( file, tagName );
2091| if ( parentTag == NULL ) {
2092| parentTag = ListX_addLastMalloc( &file->dataClasses, RXML_Tag );
2093| RXML_Tag_init( parentTag, "DC", NULL, m->rxmlFile, m->linep->iLine );
2094| RXML_Tag_setName( parentTag, tagName );
2095| }
2096| }
2097| c_catch ( Errors_Msg*, msg ) {
2098| if ( msg->code == RXML_Err_FileNotFound ) {
2099| char s[_MAX_PATH];
2100|
2101| strcpy( s, msg->orgMsg );
2102| s[ strlen(s) - 25 ] = '\0';
2103| Log_printf( m->rxmlTop->log,
2104| "ファイル %s(line=%d)から参照しているファイル %s が見つかりません\n",
2105| m->rxmlFile->path, m->linep->iLine, s );
2106| }
2107| else
2108| c_throw_again();
2109| } c_end_catch;
2110| }
2111|
2112| /* サブのデータクラスを登録する */
2113| if ( parentTag != NULL ) {
2114| RXML_Tag* tag;
2115|
2116| while ( pHref != NULL ) {
2117| StrX_wordCpy( tagName, sizeof(tagName), pHref + 1, '.' );
2118| pHref = strchr( pHref + 1, '.' );
2119| tag = RXML_Tag_getSubTag2( parentTag, tagName );
2120| if ( tag == NULL ) {
2121| tag = ListX_addLastMalloc( &parentTag->tags, RXML_Tag );
2122| RXML_Tag_init( tag, "DC", parentTag, m->rxmlFile, m->linep->iLine );
2123| RXML_Tag_setName( tag, tagName );
2124| }
2125| parentTag = tag;
2126| }
2127| }
2128| }
2129|
2130| /* href の値の先頭がプログラム・データのとき、RXML_File::progDataRef に追加する */
2131| else {
2132| RXML_Tag* parentTag = NULL;
2133| RXML_Tag* tag;
2134|
2135| StrX_wordCpy( tagName, sizeof(tagName), fullHref, '.' );
2136| pHref = strchr( fullHref, '.' );
2137| parentTag = RXML_File_getProgDataRef( m->rxmlFile, tagName );
2138| if ( parentTag == NULL ) {
2139| tag = ListX_addLastMalloc( &m->rxmlFile->progDataRef, RXML_Tag );
2140| RXML_Tag_init( tag, "PD", parentTag, m->rxmlFile, m->linep->iLine );
2141| RXML_Tag_setName( tag, tagName );
2142| }
2143| else
2144| tag = parentTag;
2145| while ( pHref != NULL ) {
2146| StrX_wordCpy( tagName, sizeof(tagName), pHref + 1, '.' );
2147| pHref = strchr( pHref + 1, '.' );
2148| parentTag = tag;
2149| tag = RXML_Tag_getSubTag2( parentTag, tagName );
2150| if ( tag == NULL ) {
2151| tag = ListX_addLastMalloc( &parentTag->tags, RXML_Tag );
2152| RXML_Tag_init( tag, "PD", parentTag, m->rxmlFile, m->linep->iLine );
2153| RXML_Tag_setName( tag, tagName );
2154| }
2155| }
2156| }
2157| }
2158|}
2159|#endif
2160|
2161|
2162|/*--------------------------------------------------------------------*/
2163|/* 59. <<< ◆(RXML_TagGet) RXML タグ抽出・アクター >>> */
2164|/*--------------------------------------------------------------------*/
2165|
2166|
2167|/***********************************************************************
2168|* 60. <<< [RXML_TagGet_init] 初期化する >>>
2169|*【補足】
2170|*・in_path は、内部でリンクしているので、削除のタイミングに注意してください。
2171|************************************************************************/
2172|#ifdef USES_RXML_ACTOR
2173|void RXML_TagGet_init( RXML_TagGet* m, HtmlPars* htmlp, LineCnt* linep,
2174| RXML_File* rxmlFile )
2175|{
2176| m->engU = htmlp->engU;
2177| m->htmlp = htmlp;
2178| m->linep = linep;
2179|
2180| m->rxmlFile = rxmlFile;
2181| m->rxmlTop = rxmlFile->top;
2182|
2183| ArrX_Buf_init( &m->tagStack, m->tagStackX, sizeof(m->tagStackX) );
2184| m->childTags = &rxmlFile->tags;
2185|
2186| m->dcTag = NULL;
2187| m->dcChildTags = &rxmlFile->dataClasses;
2188| m->gdcTag = NULL;
2189| m->gdcChildTags = &m->rxmlTop->dataClasses;
2190|}
2191|#endif
2192|
2193|
2194|/***********************************************************************
2195|* 61. <<< [RXML_TagGet_act] RXML タグ抽出を実行する >>>
2196|************************************************************************/
2197|#ifdef USES_RXML_ACTOR
2198|void RXML_TagGet_act( RXML_TagGet* m )
2199|{
2200| HtmlPars* htmlp = m->htmlp;
2201| char* name = HtmlPars_getName( htmlp );
2202| int type = HtmlPars_getTokenType( m->htmlp );
2203|
2204| if ( type != HtmlPars_StartOfTag && type != HtmlPars_EndOfTag )
2205| return;
2206|
2207| /* TEMPLATE タグを抽出する(1) */
2208| if ( strcmp( name, "template" ) == 0 ) {
2209| RXML_Tag* parentTag;
2210| RXML_Tag* tag;
2211| RXML_Tag** pTag;
2212| BLex3_Engine* eng;
2213|
2214| if ( type == HtmlPars_StartOfTag ) {
2215| eng = &m->engU->inherit_BLex3_Engine;
2216|
2217| parentTag = ( ArrX_Buf_isEmpty( &m->tagStack ) ) ?
2218| NULL : *ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2219| pTag = ArrX_Buf_alloc( &m->tagStack, RXML_Tag* );
2220| tag = ListX_addLastMalloc( m->childTags, RXML_Tag );
2221| *pTag = tag;
2222| RXML_Tag_init( tag, "template", parentTag, m->rxmlFile, m->linep->iLine );
2223| RXML_Tag_addAttrFromHtmlPars( tag, m->htmlp );
2224| BLex3_Engine_getPos( eng, &tag->start );
2225|
2226| m->childTags = &tag->tags;
2227| }
2228| }
2229|
2230| /* TEMPLATE タグを抽出する(2) */
2231| else if ( strcmp( name, "/template" ) == 0 ) {
2232| int n;
2233| RXML_Tag* tag;
2234| RXML_Tag** pTag;
2235| BLex3_Engine* eng;
2236|
2237| if ( type == HtmlPars_EndOfTag ) {
2238| eng = &m->engU->inherit_BLex3_Engine;
2239|
2240| n = ArrX_Buf_getN( &m->tagStack, RXML_Tag* );
2241| if ( n == 0 ) {
2242| error2_0( RXML_Err_Many_EndOfTemplate, "<""/TEMPLATE> が多すぎます" );
2243| }
2244|
2245| /* テンプレート・スタックから取り出す */
2246| pTag = ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2247| tag = *pTag;
2248| ArrX_Buf_free( &m->tagStack, pTag, RXML_Tag* );
2249|
2250| /* タグの抽出(2) */
2251| BLex3_Engine_getPos( eng, &tag->end );
2252|
2253| /* childTags を1つ上のタグに戻す */
2254| if ( n == 1 ) {
2255| m->childTags = &m->rxmlFile->tags;
2256| }
2257| else {
2258| pTag = ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2259| tag = *pTag;
2260| m->childTags = &tag->tags;
2261| }
2262| }
2263| }
2264|
2265| /* VAR タグを抽出する */
2266| else if ( strcmp( name, "var" ) == 0 ) {
2267| RXML_Tag* parentTag;
2268| RXML_Tag* tag;
2269| BLex3_Engine* eng;
2270|
2271| eng = &m->engU->inherit_BLex3_Engine;
2272|
2273| if ( type == HtmlPars_StartOfTag ) {
2274| parentTag = ( ArrX_Buf_isEmpty( &m->tagStack ) ) ?
2275| NULL : *ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2276| tag = ListX_addLastMalloc( m->childTags, RXML_Tag );
2277|
2278| RXML_Tag_init( tag, "var", parentTag, m->rxmlFile, m->linep->iLine );
2279| RXML_Tag_addAttrFromHtmlPars( tag, m->htmlp );
2280| BLex3_Engine_getPos( eng, &tag->start );
2281| }
2282| else if ( type == HtmlPars_EndOfTag ) {
2283| tag = ListX_getLast( m->childTags, RXML_Tag );
2284| BLex3_Engine_getPos( eng, &tag->end );
2285| }
2286| }
2287|
2288| /* データクラスにあるタグを抽出する */
2289| else {
2290| char* name2;
2291| RXML_Tag* dcTag;
2292| RXML_Tag* gdcTag;
2293|
2294| /* 開始タグなら、タグを抽出する(1) */
2295| if ( name[0] != '/' && type == HtmlPars_StartOfTag ) {
2296|
2297| name2 = StrX_MemV2_alloc( &RXML_db.dic, (name[0] == '/') ? name + 1 : name );
2298|
2299| for ( ListX_forEach( m->dcChildTags, &dcTag, RXML_Tag ) ) {
2300| if ( name2 == dcTag->name ) break;
2301| }
2302| for ( ListX_forEach( m->gdcChildTags, &gdcTag, RXML_Tag ) ) {
2303| if ( name2 == gdcTag->name ) break;
2304| }
2305|
2306| if ( dcTag != NULL || gdcTag != NULL ) {
2307| BLex3_Engine* eng = &m->engU->inherit_BLex3_Engine;
2308| RXML_Tag* parentTag;
2309| RXML_Tag* tag;
2310| RXML_Tag** pTag;
2311|
2312| m->dcTag = dcTag;
2313| if ( dcTag ) m->dcChildTags = &dcTag->tags;
2314| m->gdcTag = gdcTag;
2315| if ( gdcTag ) m->gdcChildTags = &gdcTag->tags;
2316|
2317| parentTag = ( ArrX_Buf_isEmpty( &m->tagStack ) ) ?
2318| NULL : *ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2319| pTag = ArrX_Buf_alloc( &m->tagStack, RXML_Tag* );
2320| tag = ListX_addLastMalloc( m->childTags, RXML_Tag );
2321| *pTag = tag;
2322| RXML_Tag_init( tag, name, parentTag, m->rxmlFile, m->linep->iLine );
2323| RXML_Tag_addAttrFromHtmlPars( tag, m->htmlp );
2324| BLex3_Engine_getPos( eng, &tag->start );
2325| m->childTags = &tag->tags;
2326| }
2327| }
2328|
2329| /* 終了タグなら、タグを抽出する(2) */
2330| else if ( name[0] == '/' && type == HtmlPars_EndOfTag ) {
2331| name2 = StrX_MemV2_alloc( &RXML_db.dic, (name[0] == '/') ? name + 1 : name );
2332| dcTag = ( m->dcTag != NULL && m->dcTag->name == name2 ) ?
2333| m->dcTag : NULL;
2334| gdcTag = ( m->gdcTag != NULL && m->gdcTag->name == name2 ) ?
2335| m->gdcTag : NULL;
2336|
2337| if ( dcTag != NULL || gdcTag != NULL ) {
2338| BLex3_Engine* eng = &m->engU->inherit_BLex3_Engine;
2339| RXML_Tag* tag;
2340| RXML_Tag** pTag;
2341|
2342| pTag = ArrX_Buf_getLast( &m->tagStack, RXML_Tag* );
2343| tag = *pTag;
2344| ArrX_Buf_free( &m->tagStack, pTag, RXML_Tag* );
2345|
2346| /* タグの抽出(2) */
2347| BLex3_Engine_getPos( eng, &tag->end );
2348|
2349| /* childTags を1つ上のタグに戻す */
2350| m->childTags = ( tag->parent == NULL ) ?
2351| &m->rxmlFile->tags : &tag->parent->tags;
2352| if ( dcTag != NULL ) {
2353| m->dcTag = dcTag->parent;
2354| m->dcChildTags = ( m->dcTag == NULL ) ?
2355| &m->rxmlFile->dataClasses : &m->dcTag->tags;
2356| }
2357| if ( gdcTag != NULL ) {
2358| m->gdcTag = gdcTag->parent;
2359| m->gdcChildTags = ( m->gdcTag == NULL ) ?
2360| &m->rxmlTop->dataClasses : &m->gdcTag->tags;
2361| }
2362| }
2363| }
2364| }
2365|}
2366|#endif
2367|
2368|