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|