00001
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;
00013 return sBeginLine[state].Str();
00014 }
00015
00016 void sHOutFormat::Prepare ()
00017 {
00018 t_uint16 state;
00019
00020
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 }
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
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
00108 if ( (vLineSupLTE>-1 && iLine<=vLineSupLTE) ||
00109 (vLineSupGTE>-1 && iLine>=vLineSupGTE) ) return true;
00110
00111
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
00140
00141
00142
00143
00144
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
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 }
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
00203 if ( doExclude ) {
00204
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
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
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 }
00374
00375 pSkip = cfg.GetSection( "SKIP" );
00376 if ( pSkip!=nil ) {
00377 tLine = cfg.nIdxSectL.GetInt( cfg.GetSectionFromName( "SKIP" ) );
00378
00379
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;
00393 if ( isAllUppercase ) {
00394 if ( pElem==nil ) {
00395 fprintf(fRepErr,"SKIP: Invalid tag: %s\n",str);
00396 return 32;
00397 }
00398
00399 switch ( pElem->ctrl ) {
00400 case -1:
00401 fprintf(fRepErr,"SKIP: Duplicated tag: %s\n",str);
00402 return 34;
00403 case 1:
00404 fprintf(fRepErr,"SKIP: Tidy applied on tag: %s\n",str);
00405 return 34;
00406 case 0:
00407 default:
00408 pElem->ctrl = -1;
00409 break;
00410 }
00411 }
00412 else {
00413 if ( pElem!=nil ) {
00414 return 33;
00415 }
00416 }
00417 cfg.iLineError = 0;
00418
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 }
00433 }
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 ];
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
00458
00459
00460
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;
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 }
00477 }
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
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