gHtmlOpt.cpp

Go to the documentation of this file.
00001 // gHtmlOpt, part of gUnweb
00002 
00003 #include <string.h>
00004 #include "gHtmlOpt.h"
00005 #include "gHtmlCtrl.h"
00006 #include "gstringext.h"
00007 ////////////////////////////////////////////////////////////
00008 char* sHOutFormat::GetBeginLineStr (t_uint16 state, t_uint16 rLine)
00009 {
00010  bool isFirst = rLine<=1;
00011  if ( state>=e_HS_Last ) return nil;
00012  if ( isFirst==true || state==e_HS_HeadAfter ) state = e_HS_Last; //empty string
00013  return sBeginLine[state].Str();
00014 }
00015 
00016 void sHOutFormat::Prepare ()
00017 {
00018  t_uint16 state;
00019 
00020  // sBeginLine[e_HS_Last] is always empty
00021  for (state=e_HS_Start; state<e_HS_Last; state++) {
00022      sBeginLine[state].SetEmpty();
00023      switch ( state ) {
00024      case e_HS_Start:
00025      case e_HS_StartAfter:
00026      case e_HS_Html:
00027      case e_HS_End:
00028          ;
00029          break;
00030      default:
00031          if ( oIndentLevel1.IsOn() ) {
00032              SetIndentString( cIndentLevel, 4, sBeginLine[state] );
00033          }
00034          break;
00035      }//END case
00036  }
00037 }
00038 
00039 int sHOutFormat::SetIndentString (char cIndent, t_uint16 nBlanks, gString& sResult)
00040 {
00041  t_uint16 uIdx;
00042 
00043  if ( cIndent=='\t' ) {
00044      sResult.Add( '\t' );
00045      return 0;
00046  }
00047  for (uIdx=0; uIdx<nBlanks; uIdx++)
00048      sResult.Add( cIndent );
00049 
00050  return 0;
00051 }
00052 
00053 void sHOutFormat::CopyHOutFormat (sHOutFormat& copy)
00054 {
00055  cIndentLevel = copy.cIndentLevel;
00056  oIndentLevel1.SetOn( copy.oIndentLevel1.IsOn() );
00057  Prepare();
00058 }
00059 ////////////////////////////////////////////////////////////
00060 int sAttrsTagNorm::CopyDefaultAttrNorms (t_int16 idTag0, t_int16 idTag1, bool doDefault)
00061 {
00062  t_int16 idxNorm;
00063  t_int16 idTag;
00064  sAttrNorm* pNorm;
00065  gSmartList* pList;
00066 
00067  Reset();
00068  if ( idTag0>idTag1 ) return -1;
00069  lstNorms = new gSmartList[ idTag1+1 ];
00070  ASSERTION(lstNorms!=nil,"lstNorms!=nil");
00071 
00072  pNorm = gHtmlCtrl::Self().ParserPtr()->GetDefaultAttrNorm( 0 );
00073  pList = pNorm->pAttrSeq;
00074  if ( pList!=nil ) {
00075      // There are norms for all-tags, here stated:
00076      allTagNorm.CopyList( *pList );
00077  }
00078 
00079  for (idxNorm=1;
00080       (pNorm = gHtmlCtrl::Self().ParserPtr()->GetDefaultAttrNorm( idxNorm ))!=nil;
00081       idxNorm++) {
00082      idTag = pNorm->idTag;
00083      if ( idTag<idTag0 || idTag>idTag1 ) continue;
00084      pList = pNorm->pAttrSeq;
00085      if ( pList==nil ) continue;
00086      lstNorms[ idTag ].CopyList( *pList );
00087  }
00088 
00089  return 0;
00090 }
00091 ////////////////////////////////////////////////////////////
00092 gHInOpt::gHInOpt ()
00093     : vLineLTE( -1 ),
00094       vLineGTE( -1 ),
00095       vLineSupLTE( -1 ),
00096       vLineSupGTE( -1 ),
00097       hasLineAddRestriction( false )
00098 {
00099 }
00100 
00101 gHInOpt::~gHInOpt ()
00102 {
00103 }
00104 
00105 bool gHInOpt::HasToSkip (int iLine)
00106 {
00107  // Check if LTE or GTE rules apply to 'iLine'
00108  if ( (vLineSupLTE>-1 && iLine<=vLineSupLTE) ||
00109      (vLineSupGTE>-1 && iLine>=vLineSupGTE) ) return true;
00110 
00111  // Now check if we want to skip individual lines
00112  if ( lLineSuppress.FindInt( iLine )>0 ) return true;
00113 
00114  return thisHasToShow( iLine )==false;
00115 }
00116 
00117 bool gHInOpt::ConvertToInt (char* str, int& v)
00118 {
00119  t_uint32 vRes;
00120  lastOpError = gStrControl::Self().ConvertToUInt32( str, vRes )!=0;
00121  if ( lastOpError!=0 ) return false;
00122  v = (int)vRes;
00123  return true;
00124 }
00125 
00126 bool gHInOpt::SetFromString (char* str)
00127 {
00128  char c;
00129  char* s = str;
00130  char* sAux;
00131  unsigned n;
00132  int v, vEnd;
00133  bool doExclude;
00134 
00135  DBGPRINT_MIN("gHInOpt::SetFromString: %s\n",str);
00136 
00137  if ( s==nil ) return true;
00138 
00139  // E.g.:
00140  //  @12     Suppress line 12
00141  //  @12 @14 Suppress line 12 and 14
00142  //  @12-14  Suppress line 12 to 14
00143  //  @12-    Suppress line 12 till the end
00144  //  12-15   Shows line 12 till 15, including 12 and 15.
00145  for ( ; (c = *s)!=0; ) {
00146      if ( c==' ' ) {
00147          s++;
00148          continue;
00149      }
00150      doExclude = c=='@';
00151      if ( doExclude ) s++;
00152      c = *s;
00153      if ( c==0 ) return false;
00154      gParam aParam( s, " ", gParam::e_StopSplitOnFirst );
00155      sAux = aParam.Str( 1 );
00156      gParam aParamSup( sAux, "-" );
00157      n = aParamSup.N();
00158      sAux = aParamSup.Str( 1 );
00159      if ( n<1 ) return false;
00160      if ( ConvertToInt( sAux, v )==false ) return false;
00161      if ( n==1 ) {
00162          gString sOne( s );
00163          if ( sOne.FindBack('-')>0 ) {
00164              // e.g.: @12-
00165              if ( thisAddLineSupGTE( v, doExclude )!=0 ) return false;
00166          }
00167          else {
00168              if ( thisAddLineSup( v, doExclude )!=0 ) return false;
00169          }
00170      }
00171      else {
00172          if ( n!=2 ) return false;
00173          if ( ConvertToInt( aParamSup.Str(2), vEnd )==false ) return false;
00174          if ( v>vEnd ) return false;
00175          for ( ; v<=vEnd; v++) {
00176              thisAddLineSup( v, doExclude );
00177          }
00178      }
00179      for ( ; (c = *s)!=0 && c!=' '; ) s++;
00180  }//end FOR (str...)
00181 
00182  DBGPRINT_MIN("gHInOpt::SetFromString: %s (END)\n",str);
00183 
00184  return true;
00185 }
00186 
00187 int gHInOpt::thisAddLineSup (int v, bool doExclude)
00188 {
00189  if ( v<1 ) return -1;
00190  if ( doExclude ) {
00191      lLineSuppress.Append( v );
00192  }
00193  else {
00194      lLineAdd.Append( v );
00195      hasLineAddRestriction = true;
00196  }
00197  return 0;
00198 }
00199 
00200 int gHInOpt::thisAddLineSupGTE (int v, bool doExclude)
00201 {
00202  // e.g.: @12- (Greater Than or Equal... than 12)
00203  if ( doExclude ) {
00204      // returns error (-1) if already specified GTE
00205      if ( vLineSupGTE>-1 ) return -1;
00206      vLineSupGTE = v;
00207  }
00208  else {
00209      if ( vLineGTE>-1 ) return -1;
00210      vLineGTE = v;
00211      hasLineAddRestriction = true;
00212  }
00213  return 0;
00214 }
00215 
00216 bool gHInOpt::thisHasToShow (int iLine)
00217 {
00218  // Returns true if the line is to be shown
00219  if ( hasLineAddRestriction==false ) return true;
00220 
00221  if ( vLineGTE>-1 && iLine>=vLineGTE ) return true;
00222  return lLineAdd.FindInt( iLine )>0;
00223 }
00224 ////////////////////////////////////////////////////////////
00225 void sTidyArray::Copy (sTidyArray& copy)
00226 {
00227  unsigned i;
00228  Release();
00229  n = copy.n;
00230  doTidyAll = copy.doTidyAll;
00231  if ( copy.lst==nil ) return;
00232  lst = new sTidyElem[ n+1 ];
00233  ASSERTION(lst!=nil,"lst!=nil");
00234  for (i=1; i<=n; i++) {
00235      lst[i].Copy( copy.lst[i] );
00236  }
00237 }
00238 ////////////////////////////////////////////////////////////
00239 gHOutOpt::gHOutOpt (FILE* afRepErr)
00240     : fRepErr( afRepErr ),
00241       myConfig( nil )
00242 {
00243 }
00244 
00245 gHOutOpt::~gHOutOpt ()
00246 {
00247  delete myConfig;
00248 }
00249 
00250 gConfig& gHOutOpt::Config ()
00251 {
00252  ASSERTION(myConfig!=nil,"myConfig!=nil");
00253  return *myConfig;
00254 }
00255 
00256 bool gHOutOpt::HasToSkip (char* sFullTagStr)
00257 {
00258  unsigned pos;
00259  if ( sFullTagStr==nil ) return false;
00260  gString s( sFullTagStr );
00261  s.UpString();
00262  if ( lSkipFSt.Match( s.Str() )>0 ) return true;
00263  pos = s.Find( " " );
00264  if ( pos>0 ) s[ pos ] = '\0';
00265  return lSkipStt.Match( s.Str() )>0;
00266 }
00267 
00268 void gHOutOpt::CopyHOutOpt (gHOutOpt& copy)
00269 {
00270  fRepErr = copy.fRepErr;
00271  // myConfig must not be copied
00272  aTidy.Copy( copy.aTidy );
00273  lSkipTag.CopyList( copy.lSkipTag );
00274  lSkipFSt.CopyList( copy.lSkipFSt );
00275  lSkipStt.CopyList( copy.lSkipStt );
00276 }
00277 
00278 int gHOutOpt::CopyDefaultAttrs ()
00279 {
00280  return CopyDefaultAttrNorms( 0, gHtmlCtrl::Self().ParserPtr()->GetTagMaxId(), true );
00281 }
00282 
00283 int gHOutOpt::CopyDefaultAttrNorms (t_int16 idTag0, t_int16 idTag1, bool doDefault)
00284 {
00285  return lAttrsNorm.CopyDefaultAttrNorms( idTag0, idTag1, doDefault );
00286 }
00287 
00288 int gHOutOpt::ConfigFromFile (char* fName)
00289 {
00290  ASSERTION(fName!=nil,"fName!=nil");
00291  delete myConfig;
00292  myConfig = new gConfig( gConfig::e_ConfSectionStrict, fName, true );
00293  ASSERTION(myConfig!=nil,"myConfig!=nil");
00294  lastOpError = myConfig->lastOpError;
00295  if ( lastOpError!=0 ) return lastOpError;
00296  return thisConfig( *myConfig );
00297 }
00298 
00299 bool gHOutOpt::thisHasTidy (char* strTag, unsigned& idx)
00300 {
00301  unsigned i;
00302  gString s( strTag );
00303  sHtmlElement* pElem;
00304 
00305  if ( aTidy.doTidyAll ) return true;
00306 
00307  s.UpString();
00308  pElem = gHtmlCtrl::Self().ParserPtr()->FindTag( s.Str() );
00309  DBGPRINT_MIN("DBG: thisHasTidy-possibly(%s)?%c\n",strTag,ISyORn(pElem!=nil));
00310  for (i=1; pElem!=nil && i<=aTidy.n; i++) {
00311      if ( pElem==aTidy.lst[i].pElem ) {
00312          idx = i;
00313          DBGPRINT("DBG: thisHasTidy(%s|%s,attr:%s):%u/%u\n",strTag,pElem->elemName,aTidy.lst[i].sAttr.Str(),i,aTidy.n);
00314          return true;
00315      }
00316  }
00317  return false;
00318 }
00319 
00320 bool gHOutOpt::thisHasTidyAttr (char* strTag, gString& sAttr, unsigned& idx)
00321 {
00322  unsigned i;
00323  gString s( strTag );
00324  sHtmlElement* pElem;
00325 
00326  if ( aTidy.doTidyAll ) return true;
00327 
00328  s.UpString();
00329  pElem = gHtmlCtrl::Self().ParserPtr()->FindTag( s.Str() );
00330  for (i=1; pElem!=nil && i<=aTidy.n; i++) {
00331      if ( pElem==aTidy.lst[i].pElem ) {
00332          if ( aTidy.lst[i].AnyAttr() || aTidy.lst[i].sAttr.Match( sAttr ) ) {
00333              idx = i;
00334              DBGPRINT("DBG: thisHasTidyAttr(%s|%s,attr:%s):%u/%u\n",strTag,pElem->elemName,sAttr.Str(),i,aTidy.n);
00335              return true;
00336          }
00337      }
00338  }
00339  return false;
00340 }
00341 
00342 int gHOutOpt::thisConfig (gConfig& cfg)
00343 {
00344  unsigned i, n, nTotal=cfg.nConf;
00345  unsigned k, len;
00346  int tLine;
00347  char* str;
00348  char* strWord1;
00349  char* strWord2;
00350  gList* pSkip;
00351  sHtmlElement* pElem;
00352 
00353  for (i=1; i<=nTotal; i++) {
00354      tLine = cfg.nIdxSectL.GetInt( i );
00355      str = cfg.sectL.Str( i );
00356      gString sCmdTrim( str );
00357      sCmdTrim.Trim();
00358      str = sCmdTrim.Str();
00359      gParam aParam( str, " " );
00360      strWord1 = aParam.Str( 1 );
00361      strWord2 = aParam.Str( 2 );
00362      if ( strcmp(str,"SKIP")!=0 && strcmp(strWord1,"TIDY")!=0 ) {
00363          cfg.iLineError = tLine;
00364          return 16;
00365      }
00366      ASSERTION(strWord2!=nil,"strWord2!=nil");
00367      if ( strWord2[0]!=0 ) {
00368          if ( strcmp( strWord2, "ATTR" )!=0 ) {
00369              cfg.iLineError = tLine;
00370              return 16;
00371          }
00372      }
00373  }//end FOR (first check)
00374 
00375  pSkip = cfg.GetSection( "SKIP" );
00376  if ( pSkip!=nil ) {
00377      tLine = cfg.nIdxSectL.GetInt( cfg.GetSectionFromName( "SKIP" ) );
00378 
00379      // Check if all upper-case skipped tags are valid elems
00380      for (i=1, n=pSkip->N(); i<=n; i++) {
00381          tLine++;
00382          str = pSkip->Str( i );
00383          gString sTemp( str );
00384          bool isAllUppercase = true;
00385          for (k=1, len=sTemp.Length(); k<=len && isAllUppercase==true; k++)
00386              if ( sTemp[k]<'A' || sTemp[k]>'Z' ) isAllUppercase = false;
00387          ;
00388          if ( len<=0 ) continue;
00389          DBGPRINT_WEB2("DBG: opt(SKIP): '%s'\n",str);
00390          sTemp.UpString();
00391          pElem = gHtmlCtrl::Self().ParserPtr()->FindTag( str );
00392          cfg.iLineError = tLine;  // Assume an error for line tLine
00393          if ( isAllUppercase ) {
00394              if ( pElem==nil ) {
00395                  fprintf(fRepErr,"SKIP: Invalid tag: %s\n",str);
00396                  return 32;
00397              }
00398              // Check if not already skipped
00399              switch ( pElem->ctrl ) {
00400              case -1:
00401                  fprintf(fRepErr,"SKIP: Duplicated tag: %s\n",str);
00402                  return 34;
00403              case 1://tidy
00404                  fprintf(fRepErr,"SKIP: Tidy applied on tag: %s\n",str);
00405                  return 34;
00406              case 0:
00407              default:  // 0 is default...
00408                  pElem->ctrl = -1;  // Do skip tag
00409                  break;
00410              }
00411          }
00412          else {
00413              if ( pElem!=nil ) {
00414                  return 33;
00415              }
00416          }
00417          cfg.iLineError = 0;
00418          // Ugly (but quick) replacement of skipped tag, by upper-case
00419          strcpy( str, sTemp.Str() );
00420          lSkipTag.Add( str );
00421          gString sSkipStart;
00422          sSkipStart.Add( "<" );
00423          gString sSkipEnd = sSkipStart;
00424          sSkipStart.Add( str );
00425          sSkipEnd.Add( "/" );
00426          sSkipEnd.Add( str );
00427          lSkipStt.Add( sSkipStart );
00428          sSkipStart.Add( ">" );
00429          sSkipEnd.Add( ">" );
00430          lSkipFSt.Add( sSkipStart );
00431          lSkipFSt.Add( sSkipEnd );
00432      }//end FOR i
00433  }//end token:SKIP
00434 
00435  str = "TIDY ATTR";
00436  pSkip = cfg.GetSection( str );
00437  if ( pSkip!=nil ) {
00438      tLine = cfg.nIdxSectL.GetInt( cfg.GetSectionFromName( str ) );
00439 
00440      n = pSkip->N();
00441      aTidy.Release();
00442      aTidy.lst = new sTidyElem[ n+1 ];  // highly-maximized array (1..n-indexed)
00443      ASSERTION(aTidy.lst!=nil,"aTidy.lst!=nil");
00444 
00445      for (i=1; i<=n; i++) {
00446          tLine++;
00447          str = pSkip->Str( i );
00448          if ( str==nil || str[0]==0 ) continue;
00449          DBGPRINT("DBG: TIDY: str=%s!\n",str);
00450          gString sUp( str );
00451          sUp.UpString();
00452          str = sUp.Str();
00453          gParam aParam( str, ".", gParam::e_StopSplitOnFirst );
00454          strWord1 = aParam.Str( 1 );
00455          strWord2 = aParam.Str( 2 );
00456          ASSERTION(strWord2!=nil,"strWord2!=nil");
00457          // strWord1 must be a valid tag
00458          // Example:
00459          //   IMG.SRC ==>Param<==> IMG , SRC  as Word1 , Word2
00460          //   <IMG SRC=abc> is tidyed as <IMG SRC="abc">  (quoted)
00461          pElem = gHtmlCtrl::Self().ParserPtr()->FindTag( strWord1 );
00462          if ( pElem==nil ) {
00463              fprintf(fRepErr,"TIDY: Invalid tag%s%s\n",strWord1[0]==0 ? "." : ": ",strWord1);
00464              return 36;
00465          }
00466          if ( pElem->ctrl<0 ) {
00467              fprintf(fRepErr,"TIDY: Tag was marked to be skipped: %s\n",strWord1);
00468              return 38;
00469          }
00470          pElem->ctrl = 1; //tidy
00471          unsigned iter = ++aTidy.n;
00472          DBGPRINT("DBG: aTidy(%s|%s,n=%u (n=%u,nSections=%u)\n",strWord1,strWord2,iter,n,nTotal);
00473          aTidy.lst[iter].pElem = pElem;
00474          aTidy.lst[iter].sAttr.Set( strWord2 );
00475          aTidy.lst[iter].sAttr.UpString();
00476      }//end FOR i
00477  }//end token:TIDY ATTR
00478 
00479  return 0;
00480 }
00481 
00482 void gHOutOpt::Show (bool doShowAll)
00483 {
00484  unsigned i;
00485  gList* pSection;
00486 
00487  if ( myConfig==nil ) return;
00488  printf("nConf=%d\n",myConfig->nConf); myConfig->sectL.Show(true);
00489  for (i=1; i<=myConfig->nConf; i++) {
00490      printf("DBG: i=%u: ",i); myConfig->conpL[i].Show(true);
00491  }
00492  if ( doShowAll ) {
00493      printf("nIdxSectL: "); myConfig->nIdxSectL.Show( true );
00494  }
00495  pSection = myConfig->GetSection( "SKIP" );
00496  if ( pSection!=nil ) {
00497      printf("SKIP: ");
00498      pSection->Show( false );
00499      printf("!\n");
00500  }
00501  printf("lSkipFSt: "); lSkipFSt.Show( true );
00502 }
00503 ////////////////////////////////////////////////////////////
00504 gHtmlOpt::gHtmlOpt ()
00505     : outOpt( stderr )
00506 {
00507 }
00508 
00509 gHtmlOpt::~gHtmlOpt ()
00510 {
00511 }
00512 
00513 char* gHtmlOpt::GetBaseHRef ()
00514 {
00515  ;
00516  // "<BASE HREF=sBaseHREF>", but just returning attributes
00517  sStrAux.Set( "HREF=" );
00518  sStrAux.Add( '"' );
00519  sStrAux.AddString( sBaseHREF );
00520  sStrAux.Add( '"' );
00521  return sStrAux.Str();
00522 }
00523 
00524 void gHtmlOpt::CopyOptions (gHtmlOpt& copy)
00525 {
00526  short idx;
00527  sBaseHREF = copy.sBaseHREF;
00528  oErrStateAllSuppress.SetOn( copy.oErrStateAllSuppress.IsOn() );
00529  for (idx=0; idx<10; idx++) oErrStateSuppress[idx].SetOn( copy.oErrStateSuppress[idx].IsOn() );
00530  lIdTagOptEnd.CopyList( copy.lIdTagOptEnd );
00531  outFmt.CopyHOutFormat( copy.outFmt );
00532  outOpt.CopyHOutOpt( copy.outOpt );
00533 }
00534 ////////////////////////////////////////////////////////////
00535 

Generated on Sat Aug 18 02:40:55 2007 for xpfweb_v2x lib by  doxygen 1.4.2