166
173
#define ParseAcc NULL
176
static void AdjustConfig( TidyDocImpl* doc );
178
/* parser for integer values */
179
static ParseProperty ParseInt;
181
/* parser for 't'/'f', 'true'/'false', 'y'/'n', 'yes'/'no' or '1'/'0' */
182
static ParseProperty ParseBool;
184
/* parser for 't'/'f', 'true'/'false', 'y'/'n', 'yes'/'no', '1'/'0'
186
static ParseProperty ParseAutoBool;
188
/* a string excluding whitespace */
189
static ParseProperty ParseName;
191
/* a CSS1 selector - CSS class naming for -clean option */
192
static ParseProperty ParseCSS1Selector;
194
/* a string including whitespace */
195
static ParseProperty ParseString;
197
/* a space or comma separated list of tag names */
198
static ParseProperty ParseTagNames;
201
static ParseProperty ParseSorter;
203
/* RAW, ASCII, LATIN0, LATIN1, UTF8, ISO2022, MACROMAN,
204
WIN1252, IBM858, UTF16LE, UTF16BE, UTF16, BIG5, SHIFTJIS
206
static ParseProperty ParseCharEnc;
207
static ParseProperty ParseNewline;
209
/* omit | auto | strict | loose | <fpi> */
210
static ParseProperty ParseDocType;
212
/* keep-first or keep-last? */
213
static ParseProperty ParseRepeatAttr;
169
216
static const TidyOptionImpl option_defs[] =
171
218
{ TidyUnknownOption, MS, "unknown!", IN, 0, NULL, NULL },
233
280
{ TidyEmacs, MS, "gnu-emacs", BL, no, ParseBool, boolPicks },
234
281
{ TidyEmacsFile, MS, "gnu-emacs-file", ST, 0, ParseString, NULL },
235
282
{ TidyLiteralAttribs, MU, "literal-attributes", BL, no, ParseBool, boolPicks },
236
{ TidyBodyOnly, MU, "show-body-only", BL, no, ParseBool, boolPicks },
283
{ TidyBodyOnly, MU, "show-body-only", IN, no, ParseAutoBool, autoBoolPicks },
237
284
{ TidyFixUri, MU, "fix-uri", BL, yes, ParseBool, boolPicks },
238
285
{ TidyLowerLiterals, MU, "lower-literals", BL, yes, ParseBool, boolPicks },
239
286
{ TidyHideComments, MU, "hide-comments", BL, no, ParseBool, boolPicks },
263
310
{ TidyPunctWrap, PP, "punctuation-wrap", BL, no, ParseBool, boolPicks },
265
312
{ TidyMergeDivs, MU, "merge-divs", IN, TidyAutoState, ParseAutoBool, autoBoolPicks },
313
{ TidyDecorateInferredUL, MU, "decorate-inferred-ul", BL, no, ParseBool, boolPicks },
314
{ TidyPreserveEntities, MU, "preserve-entities", BL, no, ParseBool, boolPicks },
315
{ TidySortAttributes, PP, "sort-attributes", IN, TidySortAttrNone,ParseSorter, sorterPicks },
316
{ TidyMergeSpans, MU, "merge-spans", IN, TidyAutoState, ParseAutoBool, autoBoolPicks },
266
317
{ N_TIDY_OPTIONS, XX, NULL, XY, 0, NULL, NULL }
292
static void FreeOptionValue( const TidyOptionImpl* option, ulong value )
343
static void FreeOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option, TidyOptionValue* value )
294
if ( value && option->type == TidyString && value != option->dflt )
296
MemFree( (void*) value );
345
if ( option->type == TidyString && value->p && value->p != option->pdflt )
346
TidyDocFree( doc, value->p );
300
static void CopyOptionValue( const TidyOptionImpl* option,
301
ulong* oldval, ulong newval )
349
static void CopyOptionValue( TidyDocImpl* doc, const TidyOptionImpl* option,
350
TidyOptionValue* oldval, const TidyOptionValue* newval )
303
352
assert( oldval != NULL );
304
FreeOptionValue( option, *oldval );
353
FreeOptionValue( doc, option, oldval );
306
if ( newval && option->type == TidyString && newval != option->dflt )
307
*oldval = (ulong) tmbstrdup( (ctmbstr) newval );
355
if ( option->type == TidyString )
357
if ( newval->p && newval->p != option->pdflt )
358
oldval->p = TY_(tmbstrdup)( doc->allocator, newval->p );
360
oldval->p = newval->p;
363
oldval->v = newval->v;
313
Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val )
367
static Bool SetOptionValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr val )
315
369
const TidyOptionImpl* option = &option_defs[ optId ];
316
370
Bool status = ( optId < N_TIDY_OPTIONS );
319
373
assert( option->id == optId && option->type == TidyString );
320
FreeOptionValue( option, doc->config.value[ optId ] );
321
doc->config.value[ optId ] = (ulong) tmbstrdup( val );
374
FreeOptionValue( doc, option, &doc->config.value[ optId ] );
375
doc->config.value[ optId ].p = TY_(tmbstrdup)( doc->allocator, val );
326
Bool SetOptionInt( TidyDocImpl* doc, TidyOptionId optId, ulong val )
380
Bool TY_(SetOptionInt)( TidyDocImpl* doc, TidyOptionId optId, ulong val )
328
382
Bool status = ( optId < N_TIDY_OPTIONS );
331
385
assert( option_defs[ optId ].type == TidyInteger );
332
doc->config.value[ optId ] = val;
386
doc->config.value[ optId ].v = val;
337
Bool SetOptionBool( TidyDocImpl* doc, TidyOptionId optId, Bool val )
391
Bool TY_(SetOptionBool)( TidyDocImpl* doc, TidyOptionId optId, Bool val )
339
393
Bool status = ( optId < N_TIDY_OPTIONS );
342
396
assert( option_defs[ optId ].type == TidyBoolean );
343
doc->config.value[ optId ] = val;
397
doc->config.value[ optId ].v = val;
348
Bool ResetOptionToDefault( TidyDocImpl* doc, TidyOptionId optId )
402
static void GetOptionDefault( const TidyOptionImpl* option,
403
TidyOptionValue* dflt )
405
if ( option->type == TidyString )
406
dflt->p = (char*)option->pdflt;
408
dflt->v = option->dflt;
411
static Bool OptionValueEqDefault( const TidyOptionImpl* option,
412
const TidyOptionValue* val )
414
return ( option->type == TidyString ) ?
415
val->p == option->pdflt :
416
val->v == option->dflt;
419
Bool TY_(ResetOptionToDefault)( TidyDocImpl* doc, TidyOptionId optId )
350
421
Bool status = ( optId > 0 && optId < N_TIDY_OPTIONS );
424
TidyOptionValue dflt;
353
425
const TidyOptionImpl* option = option_defs + optId;
354
ulong* value = &doc->config.value[ optId ];
426
TidyOptionValue* value = &doc->config.value[ optId ];
355
427
assert( optId == option->id );
356
CopyOptionValue( option, value, option->dflt );
428
GetOptionDefault( option, &dflt );
429
CopyOptionValue( doc, option, value, &dflt );
361
434
static void ReparseTagType( TidyDocImpl* doc, TidyOptionId optId )
363
436
ctmbstr tagdecl = cfgStr( doc, optId );
364
tmbstr dupdecl = tmbstrdup( tagdecl );
365
ParseConfigValue( doc, optId, dupdecl );
369
/* Not efficient, but effective */
370
static void ReparseTagDecls( TidyDocImpl* doc )
372
FreeDeclaredTags( doc, tagtype_null );
373
if ( cfg(doc, TidyInlineTags) )
374
ReparseTagType( doc, TidyInlineTags );
375
if ( cfg(doc, TidyBlockTags) )
376
ReparseTagType( doc, TidyBlockTags );
377
if ( cfg(doc, TidyEmptyTags) )
378
ReparseTagType( doc, TidyEmptyTags );
379
if ( cfg(doc, TidyPreTags) )
380
ReparseTagType( doc, TidyPreTags );
383
void ResetConfigToDefault( TidyDocImpl* doc )
386
const TidyOptionImpl* option = option_defs;
387
ulong* value = &doc->config.value[ 0 ];
388
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
390
assert( ixVal == (uint) option->id );
391
CopyOptionValue( option, &value[ixVal], option->dflt );
393
FreeDeclaredTags( doc, tagtype_null );
396
void TakeConfigSnapshot( TidyDocImpl* doc )
399
const TidyOptionImpl* option = option_defs;
400
ulong* value = &doc->config.value[ 0 ];
401
ulong* snap = &doc->config.snapshot[ 0 ];
437
tmbstr dupdecl = TY_(tmbstrdup)( doc->allocator, tagdecl );
438
TY_(ParseConfigValue)( doc, optId, dupdecl );
439
TidyDocFree( doc, dupdecl );
442
static Bool OptionValueIdentical( const TidyOptionImpl* option,
443
const TidyOptionValue* val1,
444
const TidyOptionValue* val2 )
446
if ( option->type == TidyString )
448
if ( val1->p == val2->p )
450
if ( !val1->p || !val2->p )
452
return TY_(tmbstrcmp)( val1->p, val2->p ) == 0;
455
return val1->v == val2->v;
458
static Bool NeedReparseTagDecls( const TidyOptionValue* current,
459
const TidyOptionValue* new,
460
uint *changedUserTags )
464
const TidyOptionImpl* option = option_defs;
465
*changedUserTags = tagtype_null;
467
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
469
assert( ixVal == (uint) option->id );
472
#define TEST_USERTAGS(USERTAGOPTION,USERTAGTYPE) \
473
case USERTAGOPTION: \
474
if (!OptionValueIdentical(option,¤t[ixVal],&new[ixVal])) \
476
*changedUserTags |= USERTAGTYPE; \
480
TEST_USERTAGS(TidyInlineTags,tagtype_inline);
481
TEST_USERTAGS(TidyBlockTags,tagtype_block);
482
TEST_USERTAGS(TidyEmptyTags,tagtype_empty);
483
TEST_USERTAGS(TidyPreTags,tagtype_pre);
489
static void ReparseTagDecls( TidyDocImpl* doc, uint changedUserTags )
491
#define REPARSE_USERTAGS(USERTAGTYPE) \
492
if ( changedUserTags & USERTAGTYPE ) \
494
TY_(FreeDeclaredTags)( doc, USERTAGTYPE ); \
495
ReparseTagType( doc, USERTAGTYPE ); \
497
REPARSE_USERTAGS(TidyInlineTags);
498
REPARSE_USERTAGS(TidyBlockTags);
499
REPARSE_USERTAGS(TidyEmptyTags);
500
REPARSE_USERTAGS(TidyPreTags);
503
void TY_(ResetConfigToDefault)( TidyDocImpl* doc )
506
const TidyOptionImpl* option = option_defs;
507
TidyOptionValue* value = &doc->config.value[ 0 ];
508
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
510
TidyOptionValue dflt;
511
assert( ixVal == (uint) option->id );
512
GetOptionDefault( option, &dflt );
513
CopyOptionValue( doc, option, &value[ixVal], &dflt );
515
TY_(FreeDeclaredTags)( doc, tagtype_null );
518
void TY_(TakeConfigSnapshot)( TidyDocImpl* doc )
521
const TidyOptionImpl* option = option_defs;
522
const TidyOptionValue* value = &doc->config.value[ 0 ];
523
TidyOptionValue* snap = &doc->config.snapshot[ 0 ];
403
525
AdjustConfig( doc ); /* Make sure it's consistent */
404
526
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
406
528
assert( ixVal == (uint) option->id );
407
CopyOptionValue( option, &snap[ixVal], value[ixVal] );
529
CopyOptionValue( doc, option, &snap[ixVal], &value[ixVal] );
411
void ResetConfigToSnapshot( TidyDocImpl* doc )
533
void TY_(ResetConfigToSnapshot)( TidyDocImpl* doc )
414
536
const TidyOptionImpl* option = option_defs;
415
ulong* value = &doc->config.value[ 0 ];
416
ulong* snap = &doc->config.snapshot[ 0 ];
537
TidyOptionValue* value = &doc->config.value[ 0 ];
538
const TidyOptionValue* snap = &doc->config.snapshot[ 0 ];
539
uint changedUserTags;
540
Bool needReparseTagsDecls = NeedReparseTagDecls( value, snap,
418
543
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
420
545
assert( ixVal == (uint) option->id );
421
CopyOptionValue( option, &value[ixVal], snap[ixVal] );
546
CopyOptionValue( doc, option, &value[ixVal], &snap[ixVal] );
423
FreeDeclaredTags( doc, tagtype_null );
424
ReparseTagDecls( doc );
548
if ( needReparseTagsDecls )
549
ReparseTagDecls( doc, changedUserTags );
427
void CopyConfig( TidyDocImpl* docTo, TidyDocImpl* docFrom )
552
void TY_(CopyConfig)( TidyDocImpl* docTo, TidyDocImpl* docFrom )
429
554
if ( docTo != docFrom )
432
557
const TidyOptionImpl* option = option_defs;
433
ulong* from = &docFrom->config.value[ 0 ];
434
ulong* to = &docTo->config.value[ 0 ];
558
const TidyOptionValue* from = &docFrom->config.value[ 0 ];
559
TidyOptionValue* to = &docTo->config.value[ 0 ];
560
uint changedUserTags;
561
Bool needReparseTagsDecls = NeedReparseTagDecls( to, from,
436
TakeConfigSnapshot( docTo );
564
TY_(TakeConfigSnapshot)( docTo );
437
565
for ( ixVal=0; ixVal < N_TIDY_OPTIONS; ++option, ++ixVal )
439
567
assert( ixVal == (uint) option->id );
440
CopyOptionValue( option, &to[ixVal], from[ixVal] );
568
CopyOptionValue( docTo, option, &to[ixVal], &from[ixVal] );
442
ReparseTagDecls( docTo );
570
if ( needReparseTagsDecls )
571
ReparseTagDecls( docTo, changedUserTags );
443
572
AdjustConfig( docTo ); /* Make sure it's consistent */
450
579
/* Debug accessor functions will be type-safe and assert option type match */
451
ulong _cfgGet( TidyDocImpl* doc, TidyOptionId optId )
580
ulong TY_(_cfgGet)( TidyDocImpl* doc, TidyOptionId optId )
453
582
assert( optId < N_TIDY_OPTIONS );
454
return doc->config.value[ optId ];
583
return doc->config.value[ optId ].v;
457
Bool _cfgGetBool( TidyDocImpl* doc, TidyOptionId optId )
586
Bool TY_(_cfgGetBool)( TidyDocImpl* doc, TidyOptionId optId )
459
ulong val = _cfgGet( doc, optId );
588
ulong val = TY_(_cfgGet)( doc, optId );
460
589
const TidyOptionImpl* opt = &option_defs[ optId ];
461
590
assert( opt && opt->type == TidyBoolean );
462
591
return (Bool) val;
465
TidyTriState _cfgGetAutoBool( TidyDocImpl* doc, TidyOptionId optId )
594
TidyTriState TY_(_cfgGetAutoBool)( TidyDocImpl* doc, TidyOptionId optId )
467
ulong val = _cfgGet( doc, optId );
596
ulong val = TY_(_cfgGet)( doc, optId );
468
597
const TidyOptionImpl* opt = &option_defs[ optId ];
469
assert( opt && opt->type == TidyInteger );
598
assert( opt && opt->type == TidyInteger
599
&& opt->parser == ParseAutoBool );
470
600
return (TidyTriState) val;
473
ctmbstr _cfgGetString( TidyDocImpl* doc, TidyOptionId optId )
603
ctmbstr TY_(_cfgGetString)( TidyDocImpl* doc, TidyOptionId optId )
475
ulong val = _cfgGet( doc, optId );
476
const TidyOptionImpl* opt = &option_defs[ optId ];
605
const TidyOptionImpl* opt;
607
assert( optId < N_TIDY_OPTIONS );
608
opt = &option_defs[ optId ];
477
609
assert( opt && opt->type == TidyString );
478
return (ctmbstr) val;
610
return doc->config.value[ optId ].p;
483
616
/* for use with Gnu Emacs */
484
617
void SetEmacsFilename( TidyDocImpl* doc, ctmbstr filename )
486
619
SetOptionValue( doc, TidyEmacsFile, filename );
490
623
static tchar GetC( TidyConfigImpl* config )
492
625
if ( config->cfgIn )
493
return ReadChar( config->cfgIn );
626
return TY_(ReadChar)( config->cfgIn );
494
627
return EndOfStream;
637
771
#define TIDY_MAX_NAME 64
640
int ParseConfigFile( TidyDocImpl* doc, ctmbstr file )
774
int TY_(ParseConfigFile)( TidyDocImpl* doc, ctmbstr file )
642
return ParseConfigFileEnc( doc, file, "ascii" );
776
return TY_(ParseConfigFileEnc)( doc, file, "ascii" );
645
779
/* open the file and parse its contents
647
int ParseConfigFileEnc( TidyDocImpl* doc, ctmbstr file, ctmbstr charenc )
781
int TY_(ParseConfigFileEnc)( TidyDocImpl* doc, ctmbstr file, ctmbstr charenc )
649
783
uint opterrs = doc->optionErrors;
650
tmbstr fname = (tmbstr) ExpandTilde( file );
784
tmbstr fname = (tmbstr) ExpandTilde( doc, file );
651
785
TidyConfigImpl* cfg = &doc->config;
652
786
FILE* fin = fopen( fname, "r" );
653
int enc = CharEncodingId( charenc );
787
int enc = TY_(CharEncodingId)( doc, charenc );
655
789
if ( fin == NULL || enc < 0 )
657
FileError( doc, fname, TidyConfig );
791
TY_(FileError)( doc, fname, TidyConfig );
663
cfg->cfgIn = FileInput( doc, fin, enc );
797
cfg->cfgIn = TY_(FileInput)( doc, fin, enc );
664
798
c = FirstChar( cfg );
666
800
for ( c = SkipWhite(cfg); c != EndOfStream; c = NextProperty(cfg) )
761
894
if (NULL != doc->pOptCallback)
762
895
status = (*doc->pOptCallback)( optnam, optval );
764
ReportUnknownOption( doc, optnam );
897
TY_(ReportUnknownOption)( doc, optnam );
767
status = ParseConfigValue( doc, option->id, optval );
900
status = TY_(ParseConfigValue)( doc, option->id, optval );
771
904
/* returns false if unknown option, missing parameter,
772
905
** or option doesn't use parameter
774
Bool ParseConfigValue( TidyDocImpl* doc, TidyOptionId optId, ctmbstr optval )
907
Bool TY_(ParseConfigValue)( TidyDocImpl* doc, TidyOptionId optId, ctmbstr optval )
776
909
const TidyOptionImpl* option = option_defs + optId;
777
910
Bool status = ( optId < N_TIDY_OPTIONS && optval != NULL );
780
ReportBadArgument( doc, option->name );
913
TY_(ReportBadArgument)( doc, option->name );
783
TidyBuffer inbuf = {0}; /* Set up input source */
784
tidyBufAttach( &inbuf, (byte*)optval, tmbstrlen(optval)+1 );
785
doc->config.cfgIn = BufferInput( doc, &inbuf, ASCII );
916
TidyBuffer inbuf; /* Set up input source */
917
tidyBufInitWithAllocator( &inbuf, doc->allocator );
918
tidyBufAttach( &inbuf, (byte*)optval, TY_(tmbstrlen)(optval)+1 );
919
doc->config.cfgIn = TY_(BufferInput)( doc, &inbuf, ASCII );
786
920
doc->config.c = GetC( &doc->config );
788
922
status = option->parser( doc, option );
790
freeStreamIn(doc->config.cfgIn); /* Release input source */
924
TY_(freeStreamIn)(doc->config.cfgIn); /* Release input source */
791
925
doc->config.cfgIn = NULL;
792
926
tidyBufDetach( &inbuf );
862
996
void AdjustConfig( TidyDocImpl* doc )
864
998
if ( cfgBool(doc, TidyEncloseBlockText) )
865
SetOptionBool( doc, TidyEncloseBodyText, yes );
999
TY_(SetOptionBool)( doc, TidyEncloseBodyText, yes );
867
1001
if ( cfgAutoBool(doc, TidyIndentContent) == TidyNoState )
868
SetOptionInt( doc, TidyIndentSpaces, 0 );
1002
TY_(SetOptionInt)( doc, TidyIndentSpaces, 0 );
870
1004
/* disable wrapping */
871
1005
if ( cfg(doc, TidyWrapLen) == 0 )
872
SetOptionInt( doc, TidyWrapLen, 0x7FFFFFFF );
1006
TY_(SetOptionInt)( doc, TidyWrapLen, 0x7FFFFFFF );
874
1008
/* Word 2000 needs o:p to be declared as inline */
875
1009
if ( cfgBool(doc, TidyWord2000) )
877
1011
doc->config.defined_tags |= tagtype_inline;
878
DefineTag( doc, tagtype_inline, "o:p" );
1012
TY_(DefineTag)( doc, tagtype_inline, "o:p" );
881
1015
/* #480701 disable XHTML output flag if both output-xhtml and xml input are set */
882
1016
if ( cfgBool(doc, TidyXmlTags) )
883
SetOptionBool( doc, TidyXhtmlOut, no );
1017
TY_(SetOptionBool)( doc, TidyXhtmlOut, no );
885
1019
/* XHTML is written in lower case */
886
1020
if ( cfgBool(doc, TidyXhtmlOut) )
888
SetOptionBool( doc, TidyXmlOut, yes );
889
SetOptionBool( doc, TidyUpperCaseTags, no );
890
SetOptionBool( doc, TidyUpperCaseAttrs, no );
891
/* SetOptionBool( doc, TidyXmlPIs, yes ); */
1022
TY_(SetOptionBool)( doc, TidyXmlOut, yes );
1023
TY_(SetOptionBool)( doc, TidyUpperCaseTags, no );
1024
TY_(SetOptionBool)( doc, TidyUpperCaseAttrs, no );
1025
/* TY_(SetOptionBool)( doc, TidyXmlPIs, yes ); */
894
1028
/* if XML in, then XML out */
895
1029
if ( cfgBool(doc, TidyXmlTags) )
897
SetOptionBool( doc, TidyXmlOut, yes );
898
SetOptionBool( doc, TidyXmlPIs, yes );
1031
TY_(SetOptionBool)( doc, TidyXmlOut, yes );
1032
TY_(SetOptionBool)( doc, TidyXmlPIs, yes );
901
1035
/* #427837 - fix by Dave Raggett 02 Jun 01
1317
1451
status = ParseString(doc, option);
1319
SetOptionInt( doc, TidyDoctypeMode, TidyDoctypeUser );
1453
TY_(SetOptionInt)( doc, TidyDoctypeMode, TidyDoctypeUser );
1324
1458
/* read first word */
1325
while ( i < sizeof(buf)-1 && c != EndOfStream && !IsWhite(c) )
1459
while ( i < sizeof(buf)-1 && c != EndOfStream && !TY_(IsWhite)(c) )
1327
1461
buf[i++] = (tmbchar) c;
1328
1462
c = AdvanceChar( cfg );
1332
if ( tmbstrcasecmp(buf, "auto") == 0 )
1466
if ( TY_(tmbstrcasecmp)(buf, "auto") == 0 )
1333
1467
dtmode = TidyDoctypeAuto;
1334
else if ( tmbstrcasecmp(buf, "omit") == 0 )
1468
else if ( TY_(tmbstrcasecmp)(buf, "omit") == 0 )
1335
1469
dtmode = TidyDoctypeOmit;
1336
else if ( tmbstrcasecmp(buf, "strict") == 0 )
1470
else if ( TY_(tmbstrcasecmp)(buf, "strict") == 0 )
1337
1471
dtmode = TidyDoctypeStrict;
1338
else if ( tmbstrcasecmp(buf, "loose") == 0 ||
1339
tmbstrcasecmp(buf, "transitional") == 0 )
1472
else if ( TY_(tmbstrcasecmp)(buf, "loose") == 0 ||
1473
TY_(tmbstrcasecmp)(buf, "transitional") == 0 )
1340
1474
dtmode = TidyDoctypeLoose;
1343
ReportBadArgument( doc, option->name );
1477
TY_(ReportBadArgument)( doc, option->name );
1348
SetOptionInt( doc, TidyDoctypeMode, dtmode );
1482
TY_(SetOptionInt)( doc, TidyDoctypeMode, dtmode );
1358
1492
TidyConfigImpl* cfg = &doc->config;
1359
1493
tchar c = SkipWhite( cfg );
1361
while (i < sizeof(buf)-1 && c != EndOfStream && !IsWhite(c))
1363
buf[i++] = (tmbchar) c;
1364
c = AdvanceChar( cfg );
1368
if ( tmbstrcasecmp(buf, "keep-first") == 0 )
1369
cfg->value[ TidyDuplicateAttrs ] = TidyKeepFirst;
1370
else if ( tmbstrcasecmp(buf, "keep-last") == 0 )
1371
cfg->value[ TidyDuplicateAttrs ] = TidyKeepLast;
1374
ReportBadArgument( doc, option->name );
1495
while (i < sizeof(buf)-1 && c != EndOfStream && !TY_(IsWhite)(c))
1497
buf[i++] = (tmbchar) c;
1498
c = AdvanceChar( cfg );
1502
if ( TY_(tmbstrcasecmp)(buf, "keep-first") == 0 )
1503
cfg->value[ TidyDuplicateAttrs ].v = TidyKeepFirst;
1504
else if ( TY_(tmbstrcasecmp)(buf, "keep-last") == 0 )
1505
cfg->value[ TidyDuplicateAttrs ].v = TidyKeepLast;
1508
TY_(ReportBadArgument)( doc, option->name );
1514
Bool ParseSorter( TidyDocImpl* doc, const TidyOptionImpl* option )
1517
tmbchar buf[64] = {0};
1520
TidyConfigImpl* cfg = &doc->config;
1521
tchar c = SkipWhite( cfg );
1523
while (i < sizeof(buf)-1 && c != EndOfStream && !TY_(IsWhite)(c))
1525
buf[i++] = (tmbchar) c;
1526
c = AdvanceChar( cfg );
1530
if ( TY_(tmbstrcasecmp)(buf, "alpha") == 0 )
1531
cfg->value[ TidySortAttributes ].v = TidySortAttrAlpha;
1532
else if ( TY_(tmbstrcasecmp)(buf, "none") == 0)
1533
cfg->value[ TidySortAttributes ].v = TidySortAttrNone;
1536
TY_(ReportBadArgument)( doc, option->name );
1380
1542
/* Use TidyOptionId as iterator.
1381
1543
** Send index of 1st option after TidyOptionUnknown as start of list.
1383
TidyIterator getOptionList( TidyDocImpl* ARG_UNUSED(doc) )
1545
TidyIterator TY_(getOptionList)( TidyDocImpl* ARG_UNUSED(doc) )
1385
return (TidyIterator) 1;
1547
return (TidyIterator) (size_t)1;
1388
1550
/* Check if this item is last valid option.
1389
1551
** If so, zero out iterator.
1391
const TidyOptionImpl* getNextOption( TidyDocImpl* ARG_UNUSED(doc),
1392
TidyIterator* iter )
1553
const TidyOptionImpl* TY_(getNextOption)( TidyDocImpl* ARG_UNUSED(doc),
1554
TidyIterator* iter )
1394
1556
const TidyOptionImpl* option = NULL;
1396
1558
assert( iter != NULL );
1397
optId = (ulong) *iter;
1559
optId = (size_t) *iter;
1398
1560
if ( optId > TidyUnknownOption && optId < N_TIDY_OPTIONS )
1400
1562
option = &option_defs[ optId ];
1403
*iter = (TidyIterator) ( optId < N_TIDY_OPTIONS ? optId : 0 );
1565
*iter = (TidyIterator) ( optId < N_TIDY_OPTIONS ? optId : (size_t)0 );
1407
1569
/* Use a 1-based array index as iterator: 0 == end-of-list
1409
TidyIterator getOptionPickList( const TidyOptionImpl* option )
1571
TidyIterator TY_(getOptionPickList)( const TidyOptionImpl* option )
1412
1574
if ( option && option->pickList )
1414
1576
return (TidyIterator) ix;
1417
ctmbstr getNextOptionPick( const TidyOptionImpl* option,
1418
TidyIterator* iter )
1579
ctmbstr TY_(getNextOptionPick)( const TidyOptionImpl* option,
1580
TidyIterator* iter )
1421
1583
ctmbstr val = NULL;
1422
1584
assert( option!=NULL && iter != NULL );
1586
ix = (size_t) *iter;
1425
1587
if ( ix > 0 && ix < 16 && option->pickList )
1426
1588
val = option->pickList[ ix-1 ];
1427
*iter = (TidyIterator) ( val && option->pickList[ix] ? ix + 1 : 0 );
1589
*iter = (TidyIterator) ( val && option->pickList[ix] ? ix + 1 : (size_t)0 );