File: localize.c

package info (click to toggle)
virtuoso-opensource 6.1.6%2Bdfsg2-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 260,060 kB
  • ctags: 123,765
  • sloc: ansic: 652,532; sql: 458,419; xml: 282,834; java: 61,031; sh: 40,031; cpp: 36,890; cs: 25,240; php: 12,692; yacc: 9,523; lex: 7,018; makefile: 6,157; jsp: 4,484; awk: 1,643; perl: 1,013; ruby: 1,003; python: 326
file content (887 lines) | stat: -rw-r--r-- 33,083 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
/*
 *  $Id$
 *
 *  localize.c
 *
 *  Copyright (c) 1998-2000 World Wide Web Consortium
 *  (Massachusetts Institute of Technology, Institut National de
 *  Recherche en Informatique et en Automatique, Keio University).
 *  All Rights Reserved.
 *
 *  Contributing Author(s):
 *
 *  Dave Raggett <dsr@w3.org>
 *
 *  The contributing author(s) would like to thank all those who
 *  helped with testing, bug fixes, and patience.  This wouldn't
 *  have been possible without all of you.
 *
 *  COPYRIGHT NOTICE:
 *
 *  This software and documentation is provided "as is," and
 *  the copyright holders and contributing author(s) make no
 *  representations or warranties, express or implied, including
 *  but not limited to, warranties of merchantability or fitness
 *  for any particular purpose or that the use of the software or
 *  documentation will not infringe any third party patents,
 *  copyrights, trademarks or other rights.
 *
 *  The copyright holders and contributing author(s) will not be
 *  liable for any direct, indirect, special or consequential damages
 *  arising out of any use of the software or documentation, even if
 *  advised of the possibility of such damage.
 *
 *  Permission is hereby granted to use, copy, modify, and distribute
 *  this source code, or portions hereof, documentation and executables,
 *  for any purpose, without fee, subject to the following restrictions:
 *
 *  1. The origin of this source code must not be misrepresented.
 *  2. Altered versions must be plainly marked as such and must
 *     not be misrepresented as being the original source.
 *  3. This Copyright notice may not be removed or altered from any
 *     source or altered source distribution.
 *
 *  The copyright holders and contributing author(s) specifically
 *  permit, without fee, and encourage the use of this source code
 *  as a component for supporting the Hypertext Markup Language in
 *  commercial products. If you use this source code in a product,
 *  acknowledgment is not required but would be appreciated.
 */

/*
  You should only need to edit this file and tidy.c
  to localize HTML tidy.
*/

#include "platform.h"
#include "html.h"

/* used to point to Web Accessibility Guidelines */
#define ACCESS_URL  "http://www.w3.org/WAI/GL"

char *release_date = "4th August 2000";

#ifndef BIF_TIDY
static char *currentFile; /* sasdjb 01May00 for GNU Emacs error parsing */
#endif

extern uint optionerrors;

#ifdef BIF_TIDY
void tidy_out_tio(tidy_io_t *tio, int maxlength, const char* msg, ...)
{
    va_list args;
    int newlen;
    int vsprintf_len;
    maxlength += 0x100;
    newlen = tio->tio_pos+maxlength;
    if (newlen >= tio->tio_data.lm_length)
      {
	caddr_t new_buf;
	newlen *= 2;
        new_buf = dk_alloc (newlen);
	if (0 != tio->tio_pos)
	  memcpy (new_buf, tio->tio_data.lm_memblock, tio->tio_pos);
        if (NULL != tio->tio_data.lm_memblock)
	  dk_free (tio->tio_data.lm_memblock, tio->tio_data.lm_length);
        tio->tio_data.lm_memblock = new_buf;
        tio->tio_data.lm_length = newlen;
      }
    va_start(args, msg);
    vsprintf_len = vsprintf (tio->tio_data.lm_memblock + tio->tio_pos, msg, args);
    va_end(args);
    if (vsprintf_len > 0)
      {
#ifdef DEBUG
	if (vsprintf_len > maxlength)
	  GPF_T;
#endif
        tio->tio_pos += vsprintf_len;
	tio->tio_data.lm_memblock[tio->tio_pos] = '\0';
      }
}
#else
/*
 This routine is the single point via which
 all output is written and as such is a good
 way to interface Tidy to other code when
 embedding Tidy in a GUI application.
*/
void tidy_out_file(FILE *fp, int maxlength, const char* msg, ...)
{
    va_list args;
    va_start(args, msg);
    vfprintf(fp, msg, args);
    va_end(args);
}
#endif

void ReadingFromStdin(void)
{
    fprintf(stderr, "Reading markup from standard input ...\n");
}

#ifndef BIF_TIDY
void ShowVersion(FILE *fp)
{
    tidy_out(fp, 0, "HTML Tidy release date: %s\n"
            "See http://www.w3.org/People/Raggett for details\n", release_date);
}
#endif

#ifdef BIF_TIDY
/* Bif have no file i/o, and no such errors */
#else
void FileError(FILE *fp, const char *file)
{
    tidy_out(fp, strlen(file), "Can't open \"%s\"\n", file);
}
#endif

static void ReportTag(Lexer *lexer, Node *tag)
{
    if (tag)
    {
        if (tag->type == StartTag)
            tidy_out(lexer->errout, strlen(tag->element), "<%s>", tag->element);
        else if (tag->type == EndTag)
            tidy_out(lexer->errout, strlen(tag->element), "</%s>", tag->element);
        else if (tag->type == DocTypeTag)
            tidy_out(lexer->errout, 0, "<!DOCTYPE>");
        else if (tag->type == TextNode)
            tidy_out(lexer->errout, 0, "plain text");
        else
            tidy_out(lexer->errout, strlen(tag->element), "%s", tag->element);
    }
}

/* lexer is not defined when this is called */
void ReportUnknownOption(char *option)
{
    optionerrors++;
    fprintf(stderr, "Warning - unknown option: %s\n", option);
}

/* lexer is not defined when this is called */
void ReportBadArgument(char *option)
{
    optionerrors++;
    fprintf(stderr, "Warning - missing or malformed argument for option: %s\n", option);
}

static void NtoS(int n, char *str)
{
    char buf[40];
    int i;

    for (i = 0;; ++i)
    {
        buf[i] = (n % 10) + '0';

        n = n /10;

        if (n == 0)
            break;
    }

    n = i;

    while (i >= 0)
    {
        str[n-i] = buf[i];
        --i;
    }

    str[n+1] = '\0';
}

static void ReportPosition(Lexer *lexer)
{
    /* Change formatting to be parsable by GNU Emacs */
    if (Emacs)
    {
#ifndef BIF_TIDY
        tidy_out(lexer->errout, strlen(currentFile), "%s", currentFile);
#endif
        tidy_out(lexer->errout, 0, ":%d:", lexer->lines);
        tidy_out(lexer->errout, 0, "%d: ", lexer->columns);
    }
    else /* traditional format */
    {
        tidy_out(lexer->errout, 0, "line %d", lexer->lines);
        tidy_out(lexer->errout, 0, " column %d - ", lexer->columns);
    }
}

void ReportEncodingError(Lexer *lexer, uint code, uint c)
{
    char buf[32];

    lexer->warnings++;

    if (ShowWarnings)
    {
        ReportPosition(lexer);

        if (code == WINDOWS_CHARS)
        {
            NtoS(c, buf);
            lexer->badChars |= WINDOWS_CHARS;
            tidy_out(lexer->errout, strlen(buf), "Warning: replacing illegal character code %s", buf);
        }

        tidy_out(lexer->errout, 0, "\n");
    }
}

void ReportEntityError(Lexer *lexer, uint code, char *entity, int c)
{
    lexer->warnings++;

    if (ShowWarnings)
    {
        ReportPosition(lexer);

        if (code == MISSING_SEMICOLON)
        {
            tidy_out(lexer->errout, strlen(entity), "Warning: entity \"%s\" doesn't end in ';'", entity);
        }
        else if (code == UNKNOWN_ENTITY)
        {
            tidy_out(lexer->errout, strlen(entity), "Warning: unescaped & or unknown entity \"%s\"", entity);
        }
        else if (code == UNESCAPED_AMPERSAND)
        {
            tidy_out(lexer->errout, 0, "Warning: unescaped & which should be written as &amp;");
        }

        tidy_out(lexer->errout, 0, "\n");
    }
}

void ReportAttrError(Lexer *lexer, Node *node, char *attr, uint code)
{
    lexer->warnings++;

    /* keep quiet after 6 errors */
    if (lexer->errors > 6)
        return;

    if (NULL == attr)
      attr = "";

    if (ShowWarnings)
    {
        /* on end of file adjust reported position to end of input */
        if (code == UNEXPECTED_END_OF_FILE)
        {
            lexer->lines = lexer->in->curline;
            lexer->columns = lexer->in->curcol;
        }

        ReportPosition(lexer);

        if (code == UNKNOWN_ATTRIBUTE)
            tidy_out(lexer->errout, strlen(attr), "Warning: unknown attribute \"%s\"", attr);
        else if (code == MISSING_ATTRIBUTE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " lacks \"%s\" attribute", attr);
        }
        else if (code == MISSING_ATTR_VALUE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " attribute \"%s\" lacks value", attr);
        }
        else if (code == MISSING_IMAGEMAP)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " should use client-side image map");
            lexer->badAccess |= MISSING_IMAGE_MAP;
        }
        else if (code == BAD_ATTRIBUTE_VALUE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " unknown attribute value \"%s\"", attr);
        }
        else if (code == XML_ATTRIBUTE_VALUE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " has XML attribute \"%s\"", attr);
        }
        else if (code == UNEXPECTED_GT)
        {
            tidy_out(lexer->errout, 0, "Error: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " missing '>' for end of tag");
            lexer->errors++;;
        }
        else if (code == UNEXPECTED_QUOTEMARK)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " unexpected or duplicate quote mark");
        }
        else if (code == REPEATED_ATTRIBUTE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " repeated attribute \"%s\"", attr);
        }
        else if (code == PROPRIETARY_ATTR_VALUE)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(attr), " proprietary attribute value \"%s\"", attr);
        }
        else if (code == UNEXPECTED_END_OF_FILE)
        {
            tidy_out(lexer->errout, 0, "Warning: end of file while parsing attributes");
        }
        else if (code == ID_NAME_MISMATCH)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " id and name attribute value mismatch");
        }

        tidy_out(lexer->errout, 0, "\n");
    }
    else if (code == UNEXPECTED_GT)
    {
        ReportPosition(lexer);
        tidy_out(lexer->errout, 0, "Error: ");
        ReportTag(lexer, node);
        tidy_out(lexer->errout, 0, " missing '>' for end of tag\n");
        lexer->errors++;;
    }
}

void ReportWarning(Lexer *lexer, Node *element, Node *node, uint code)
{
    lexer->warnings++;

    /* keep quiet after 6 errors */
    if (lexer->errors > 6)
        return;

    if (ShowWarnings)
    {
        /* on end of file adjust reported position to end of input */
        if (code == UNEXPECTED_END_OF_FILE)
        {
            lexer->lines = lexer->in->curline;
            lexer->columns = lexer->in->curcol;
        }

        ReportPosition(lexer);

        if (code == MISSING_ENDTAG_FOR)
            tidy_out(lexer->errout, strlen(element->element), "Warning: missing </%s>", element->element);
        else if (code == MISSING_ENDTAG_BEFORE)
        {
            tidy_out(lexer->errout, strlen(element->element), "Warning: missing </%s> before ", element->element);
            ReportTag(lexer, node);
        }
        else if (code == DISCARDING_UNEXPECTED)
        {
            tidy_out(lexer->errout, 0, "Warning: discarding unexpected ");
            ReportTag(lexer, node);
        }
        else if (code == NESTED_EMPHASIS)
        {
            tidy_out(lexer->errout, 0, "Warning: nested emphasis ");
            ReportTag(lexer, node);
        }
        else if (code == COERCE_TO_ENDTAG)
        {
            tidy_out(lexer->errout, 2 * strlen(node->element), "Warning: <%s> is probably intended as </%s>",
                node->element, node->element);
        }
        else if (code == NON_MATCHING_ENDTAG)
        {
            tidy_out(lexer->errout, 0, "Warning: replacing unexpected ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(element->element), " by </%s>", element->element);
        }
        else if (code == TAG_NOT_ALLOWED_IN)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, strlen(element->element), " isn't allowed in <%s> elements", element->element);
        }
        else if (code == DOCTYPE_AFTER_TAGS)
        {
            tidy_out(lexer->errout, 0, "Warning: <!DOCTYPE> isn't allowed after elements");
        }
        else if (code == MISSING_STARTTAG)
            tidy_out(lexer->errout, strlen(node->element), "Warning: missing <%s>", node->element);
        else if (code == UNEXPECTED_ENDTAG)
        {
            tidy_out(lexer->errout, strlen(node->element), "Warning: unexpected </%s>", node->element);

            if (element)
                tidy_out(lexer->errout, strlen(element->element), " in <%s>", element->element);
        }
        else if (code == TOO_MANY_ELEMENTS)
        {
            tidy_out(lexer->errout, strlen(node->element), "Warning: too many %s elements", node->element);

            if (element)
                tidy_out(lexer->errout, strlen(element->element), " in <%s>", element->element);
        }
        else if (code == USING_BR_INPLACE_OF)
        {
            tidy_out(lexer->errout, 0, "Warning: using <br> in place of ");
            ReportTag(lexer, node);
        }
        else if (code == INSERTING_TAG)
            tidy_out(lexer->errout, strlen(node->element), "Warning: inserting implicit <%s>", node->element);
        else if (code == CANT_BE_NESTED)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " can't be nested");
        }
        else if (code == PROPRIETARY_ELEMENT)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " is not approved by W3C");

            if (node->tag == tag_layer)
                lexer->badLayout |= USING_LAYER;
            else if (node->tag == tag_spacer)
                lexer->badLayout |= USING_SPACER;
            else if (node->tag == tag_nobr)
                lexer->badLayout |= USING_NOBR;
        }
        else if (code == OBSOLETE_ELEMENT)
        {
            if (element->tag && (element->tag->model & CM_OBSOLETE))
                tidy_out(lexer->errout, 0, "Warning: replacing obsolete element ");
            else
                tidy_out(lexer->errout, 0, "Warning: replacing element ");

            ReportTag(lexer, element);
            tidy_out(lexer->errout, 0, " by ");
            ReportTag(lexer, node);
        }
        else if (code == TRIM_EMPTY_ELEMENT)
        {
            tidy_out(lexer->errout, 0, "Warning: trimming empty ");
            ReportTag(lexer, element);
        }
        else if (code == MISSING_TITLE_ELEMENT)
            tidy_out(lexer->errout, 0, "Warning: inserting missing 'title' element");
        else if (code == ILLEGAL_NESTING)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, element);
            tidy_out(lexer->errout, 0, " shouldn't be nested");
        }
        else if (code == NOFRAMES_CONTENT)
        {
            tidy_out(lexer->errout, 0, "Warning: ");
            ReportTag(lexer, node);
            tidy_out(lexer->errout, 0, " not inside 'noframes' element");
        }
        else if (code == INCONSISTENT_VERSION)
        {
            tidy_out(lexer->errout, 0, "Warning: html doctype doesn't match content");
        }
        else if (code == MALFORMED_DOCTYPE)
        {
            tidy_out(lexer->errout, 0, "Warning: expected \"html PUBLIC\" or \"html SYSTEM\"");
        }
        else if (code == CONTENT_AFTER_BODY)
        {
            tidy_out(lexer->errout, 0, "Warning: content occurs after end of body");
        }
        else if (code == MALFORMED_COMMENT)
        {
            tidy_out(lexer->errout, 0, "Warning: adjacent hyphens within comment");
        }
        else if (code == BAD_COMMENT_CHARS)
        {
            tidy_out(lexer->errout, 0, "Warning: expecting -- or >");
        }
        else if (code == BAD_XML_COMMENT)
        {
            tidy_out(lexer->errout, 0, "Warning: XML comments can't contain --");
        }
        else if (code == BAD_CDATA_CONTENT)
        {
            tidy_out(lexer->errout, 0, "Warning: '<' + '/' + letter not allowed here");
        }
        else if (code == INCONSISTENT_NAMESPACE)
        {
            tidy_out(lexer->errout, 0, "Warning: html namespace doesn't match content");
        }
        else if (code == DTYPE_NOT_UPPER_CASE)
        {
            tidy_out(lexer->errout, 0, "Warning: SYSTEM, PUBLIC, W3C, DTD, EN must be upper case");
        }
        else if (code == UNEXPECTED_END_OF_FILE)
        {
            tidy_out(lexer->errout, 0, "Warning: unexpected end of file");
            ReportTag(lexer, element);
        }

        tidy_out(lexer->errout, 0, "\n");
    }
}

void ReportError(Lexer *lexer, Node *element, Node *node, uint code)
{
    lexer->warnings++;

    /* keep quiet after 6 errors */
    if (lexer->errors > 6)
        return;

    lexer->errors++;

    ReportPosition(lexer);

    if (code == SUSPECTED_MISSING_QUOTE)
    {
        tidy_out(lexer->errout, 0, "Error: missing quotemark for attribute value");
    }
    else if (code == DUPLICATE_FRAMESET)
    {
        tidy_out(lexer->errout, 0, "Error: repeated FRAMESET element");
    }
    else if (code == UNKNOWN_ELEMENT)
    {
        tidy_out(lexer->errout, 0, "Error: ");
        ReportTag(lexer, node);
        tidy_out(lexer->errout, 0, " is not recognized!");
    }
    else if (code == UNEXPECTED_ENDTAG)  /* generated by XML docs */
    {
        tidy_out(lexer->errout, strlen(node->element), "Warning: unexpected </%s>", node->element);

        if (element)
            tidy_out(lexer->errout, strlen(element->element), " in <%s>", element->element);
    }

    tidy_out(lexer->errout, 0, "\n");
}

void ErrorSummary(Lexer *lexer)
{
    /* adjust badAccess to that its null if frames are ok */
    if (lexer->badAccess & (USING_FRAMES | USING_NOFRAMES))
    {
        if (!((lexer->badAccess & USING_FRAMES) && !(lexer->badAccess & USING_NOFRAMES)))
            lexer->badAccess &= ~(USING_FRAMES | USING_NOFRAMES);
    }

    if (lexer->badChars)
    {
        if (lexer->badChars & WINDOWS_CHARS)
        {
            tidy_out(lexer->errout, 0, "Characters codes for the Microsoft Windows fonts in the range\n");
            tidy_out(lexer->errout, 0, "128 - 159 may not be recognized on other platforms. You are\n");
            tidy_out(lexer->errout, 0, "instead recommended to use named entities, e.g. &trade; rather\n");
            tidy_out(lexer->errout, 0, "than Windows character code 153 (0x2122 in Unicode). Note that\n");
            tidy_out(lexer->errout, 0, "as of February 1998 few browsers support the new entities.\n\n");
        }
    }

    if (lexer->badForm)
    {
        tidy_out(lexer->errout, 0, "You may need to move one or both of the <form> and </form>\n");
        tidy_out(lexer->errout, 0, "tags. HTML elements should be properly nested and form elements\n");
        tidy_out(lexer->errout, 0, "are no exception. For instance you should not place the <form>\n");
        tidy_out(lexer->errout, 0, "in one table cell and the </form> in another. If the <form> is\n");
        tidy_out(lexer->errout, 0, "placed before a table, the </form> cannot be placed inside the\n");
        tidy_out(lexer->errout, 0, "table! Note that one form can't be nested inside another!\n\n");
    }

    if (lexer->badAccess)
    {
        if (lexer->badAccess & MISSING_SUMMARY)
        {
            tidy_out(lexer->errout, 0, "The table summary attribute should be used to describe\n");
            tidy_out(lexer->errout, 0, "the table structure. It is very helpful for people using\n");
            tidy_out(lexer->errout, 0, "non-visual browsers. The scope and headers attributes for\n");
            tidy_out(lexer->errout, 0, "table cells are useful for specifying which headers apply\n");
            tidy_out(lexer->errout, 0, "to each table cell, enabling non-visual browsers to provide\n");
            tidy_out(lexer->errout, 0, "a meaningful context for each cell.\n\n");
        }

        if (lexer->badAccess & MISSING_IMAGE_ALT)
        {
            tidy_out(lexer->errout, 0, "The alt attribute should be used to give a short description\n");
            tidy_out(lexer->errout, 0, "of an image; longer descriptions should be given with the\n");
            tidy_out(lexer->errout, 0, "longdesc attribute which takes a URL linked to the description.\n");
            tidy_out(lexer->errout, 0, "These measures are needed for people using non-graphical browsers.\n\n");
        }

        if (lexer->badAccess & MISSING_IMAGE_MAP)
        {
            tidy_out(lexer->errout, 0, "Use client-side image maps in preference to server-side image\n");
            tidy_out(lexer->errout, 0, "maps as the latter are inaccessible to people using non-\n");
            tidy_out(lexer->errout, 0, "graphical browsers. In addition, client-side maps are easier\n");
            tidy_out(lexer->errout, 0, "to set up and provide immediate feedback to users.\n\n");
        }

        if (lexer->badAccess & MISSING_LINK_ALT)
        {
            tidy_out(lexer->errout, 0, "For hypertext links defined using a client-side image map, you\n");
            tidy_out(lexer->errout, 0, "need to use the alt attribute to provide a textual description\n");
            tidy_out(lexer->errout, 0, "of the link for people using non-graphical browsers.\n\n");
        }

        if ((lexer->badAccess & USING_FRAMES) && !(lexer->badAccess & USING_NOFRAMES))
        {
            tidy_out(lexer->errout, 0, "Pages designed using frames presents problems for\n");
            tidy_out(lexer->errout, 0, "people who are either blind or using a browser that\n");
            tidy_out(lexer->errout, 0, "doesn't support frames. A frames-based page should always\n");
            tidy_out(lexer->errout, 0, "include an alternative layout inside a NOFRAMES element.\n\n");
        }

        tidy_out(lexer->errout, 0, "For further advice on how to make your pages accessible\n");
        tidy_out(lexer->errout, 0, "see \"%s\". You may also want to try\n", ACCESS_URL);
        tidy_out(lexer->errout, 0, "\"http://www.cast.org/bobby/\" which is a free Web-based\n");
        tidy_out(lexer->errout, 0, "service for checking URLs for accessibility.\n\n");
    }

    if (lexer->badLayout)
    {
        if (lexer->badLayout & USING_LAYER)
        {
            tidy_out(lexer->errout, 0, "The Cascading Style Sheets (CSS) Positioning mechanism\n");
            tidy_out(lexer->errout, 0, "is recommended in preference to the proprietary <LAYER>\n");
            tidy_out(lexer->errout, 0, "element due to limited vendor support for LAYER.\n\n");
        }

        if (lexer->badLayout & USING_SPACER)
        {
            tidy_out(lexer->errout, 0, "You are recommended to use CSS for controlling white\n");
            tidy_out(lexer->errout, 0, "space (e.g. for indentation, margins and line spacing).\n");
            tidy_out(lexer->errout, 0, "The proprietary <SPACER> element has limited vendor support.\n\n");
        }

        if (lexer->badLayout & USING_FONT)
        {
            tidy_out(lexer->errout, 0, "You are recommended to use CSS to specify the font and\n");
            tidy_out(lexer->errout, 0, "properties such as its size and color. This will reduce\n");
            tidy_out(lexer->errout, 0, "the size of HTML files and make them easier maintain\n");
            tidy_out(lexer->errout, 0, "compared with using <FONT> elements.\n\n");
        }

        if (lexer->badLayout & USING_NOBR)
        {
            tidy_out(lexer->errout, 0, "You are recommended to use CSS to control line wrapping.\n");
            tidy_out(lexer->errout, 0, "Use \"white-space: nowrap\" to inhibit wrapping in place\n");
            tidy_out(lexer->errout, 0, "of inserting <NOBR>...</NOBR> into the markup.\n\n");
        }

        if (lexer->badLayout & USING_BODY)
        {
            tidy_out(lexer->errout, 0, "You are recommended to use CSS to specify page and link colors\n");
        }
    }
}

#ifndef BIF_TIDY
void UnknownOption(FILE *errout, char c)
{
    tidy_out(errout, 0, "unrecognized option -%c use -help to list options\n", c);
}
#endif

#ifndef BIF_TIDY
void UnknownFile(FILE *errout, char *program, char *file)
{
    tidy_out(errout, strlen(program)+strlen(file), "%s: can't open file \"%s\"\n", program, file);
}
#endif

void NeedsAuthorIntervention(errout_t *errout)
{
    tidy_out(errout, 0, "This document has errors that must be fixed before\n");
    tidy_out(errout, 0, "using HTML Tidy to generate a tidied up version.\n\n");
}

void MissingBody(errout_t *errout)
{
    tidy_out(errout, 0, "Can't create slides - document is missing a body element.\n");
}

void ReportNumberOfSlides(errout_t *errout, int count)
{
    tidy_out(errout, 0, "%d Slides found\n", count);
}

void GeneralInfo(errout_t *errout)
{
    tidy_out(errout, 0, "HTML & CSS specifications are available from http://www.w3.org/\n");
    tidy_out(errout, 0, "To learn more about Tidy see http://www.w3.org/People/Raggett/tidy/\n");
    tidy_out(errout, 0, "Please send bug reports to Dave Raggett care of <html-tidy@w3.org>\n");
    tidy_out(errout, 0, "Lobby your company to join W3C, see http://www.w3.org/Consortium\n");
}

#ifndef BIF_TIDY
void HelloMessage(FILE *errout, char *date, char *filename)
{
    currentFile = filename;  /* for use with Gnu Emacs */

    if (wstrcmp(filename, "stdin") == 0)
        tidy_out(errout, 0, "\nTidy (vers %s) Parsing console input (stdin)\n", date);
    else
        tidy_out(errout, strlen(filename), "\nTidy (vers %s) Parsing \"%s\"\n", date, filename);
}
#endif

#ifdef BIF_TIDY
void ReportVersion4bif(errout_t *errout, Lexer *lexer, Node *doctype)
#else
void ReportVersion(FILE *errout, Lexer *lexer, char *filename, Node *doctype)
#endif
{
    unsigned int i, c;
    int state = 0;
    char *vers = HTMLVersionName(lexer);

    if (doctype)
    {
#ifdef BIF_TIDY
        tidy_out(errout, 0, "\nDoctype given is \"");
#else
        tidy_out(errout, strlen(filename), "\n%s: Doctype given is \"", filename);
#endif
        for (i = doctype->start; i < doctype->end; ++i)
        {
            c = (unsigned char)lexer->lexbuf[i];

            /* look for UTF-8 multibyte character */
            if (c > 0x7F)
                 i += GetUTF8((unsigned char *)lexer->lexbuf + i, &c);

            if (c == '"')
                ++state;
            else if (state == 1)
                tidy_out(errout, 0, "%c", c);
        }

        tidy_out(errout, 0, "\"");
    }
#ifdef BIF_TIDY
    tidy_out(errout, (vers ? strlen(vers) : 0),
        "\nDocument content looks like %s\n",
        (vers ? vers : "HTML proprietary"));
#else
    tidy_out(errout, strlen (filename) + (vers ? strlen(vers) : 0),
        "\n%s: Document content looks like %s\n",
        filename, (vers ? vers : "HTML proprietary"));
#endif
}



void ReportNumWarnings(errout_t *errout, Lexer *lexer)
{
    if (lexer->warnings > 0)
        tidy_out(errout, 0, "%d warnings/errors were found!\n\n", lexer->warnings);
    else
        tidy_out(errout, 0, "no warnings or errors were found\n\n");
}

#ifndef BIF_TIDY
void HelpText(FILE *out, char *prog)
{
#if 0  /* old style help text */
    tidy_out(out, "%s: file1 file2 ...\n", prog);
    tidy_out(out, "Utility to clean up & pretty print html files\n");
    tidy_out(out, "see http://www.w3.org/People/Raggett/tidy/\n");
    tidy_out(out, "options for tidy released on %s\n", release_date);
    tidy_out(out, "  -config <file>  set options from config file\n");
    tidy_out(out, "  -indent or -i   indent element content\n");
    tidy_out(out, "  -omit   or -o   omit optional endtags\n");
    tidy_out(out, "  -wrap 72        wrap text at column 72 (default is 68)\n");
    tidy_out(out, "  -upper  or -u   force tags to upper case (default is lower)\n");
    tidy_out(out, "  -clean  or -c   replace font, nobr & center tags by CSS\n");
    tidy_out(out, "  -raw            leave chars > 128 unchanged upon output\n");
    tidy_out(out, "  -ascii          use ASCII for output, Latin-1 for input\n");
    tidy_out(out, "  -latin1         use Latin-1 for both input and output\n");
    tidy_out(out, "  -iso2022        use ISO2022 for both input and output\n");
    tidy_out(out, "  -utf8           use UTF-8 for both input and output\n");
    tidy_out(out, "  -mac            use the Apple MacRoman character set\n");
    tidy_out(out, "  -numeric or -n  output numeric rather than named entities\n");
    tidy_out(out, "  -modify or -m   to modify original files\n");
    tidy_out(out, "  -errors or -e   only show errors\n");
    tidy_out(out, "  -quiet or -q    suppress nonessential output\n");
    tidy_out(out, "  -f <file>       write errors to named <file>\n");
    tidy_out(out, "  -xml            use this when input is wellformed xml\n");
    tidy_out(out, "  -asxml          to convert html to wellformed xml\n");
    tidy_out(out, "  -slides         to burst into slides on h2 elements\n");
    tidy_out(out, "  -version or -v  show version\n");
    tidy_out(out, "  -help   or -h   list command line options\n");
    tidy_out(out, "Input/Output default to stdin/stdout respectively\n");
    tidy_out(out, "Single letter options apart from -f may be combined\n");
    tidy_out(out, "as in:  tidy -f errs.txt -imu foo.html\n");
    tidy_out(out, "You can also use --blah for any config file option blah\n");
    tidy_out(out, "For further info on HTML see http://www.w3.org/MarkUp\n");
#endif
    tidy_out(out, 0, "%s: file1 file2 ...\n", prog);
    tidy_out(out, 0, "Utility to clean up & pretty print html files\n");
    tidy_out(out, 0, "see http://www.w3.org/People/Raggett/tidy/\n");
    tidy_out(out, 0, "options for tidy released on %s\n", release_date);
    tidy_out(out, 0, "\n");

    tidy_out(out, 0, "Processing directives\n");
    tidy_out(out, 0, "--------------------\n");
    tidy_out(out, 0, "  -indent or -i   indent element content\n");
    tidy_out(out, 0, "  -omit   or -o   omit optional endtags\n");
    tidy_out(out, 0, "  -wrap 72        wrap text at column 72 (default is 68)\n");
    tidy_out(out, 0, "  -upper  or -u   force tags to upper case (default is lower)\n");
    tidy_out(out, 0, "  -clean  or -c   replace font, nobr & center tags by CSS\n");
    tidy_out(out, 0, "  -numeric or -n  output numeric rather than named entities\n");
    tidy_out(out, 0, "  -errors or -e   only show errors\n");
    tidy_out(out, 0, "  -quiet or -q    suppress nonessential output\n");
    tidy_out(out, 0, "  -xml            use this when input is wellformed xml\n");
    tidy_out(out, 0, "  -asxml          to convert html to wellformed xml\n");
    tidy_out(out, 0, "  -slides         to burst into slides on h2 elements\n");
    tidy_out(out, 0, "\n");

    tidy_out(out, 0, "Character encodings\n");
    tidy_out(out, 0, "------------------\n");
    tidy_out(out, 0, "  -raw            leave chars > 128 unchanged upon output\n");
    tidy_out(out, 0, "  -ascii          use ASCII for output, Latin-1 for input\n");
    tidy_out(out, 0, "  -latin1         use Latin-1 for both input and output\n");
    tidy_out(out, 0, "  -iso2022        use ISO2022 for both input and output\n");
    tidy_out(out, 0, "  -utf8           use UTF-8 for both input and output\n");
    tidy_out(out, 0, "  -mac            use the Apple MacRoman character set\n");
    tidy_out(out, 0, "\n");
    tidy_out(out, 0, "\n");

    tidy_out(out, 0, "File manipulation\n");
    tidy_out(out, 0, "---------------\n");
    tidy_out(out, 0, "  -config <file>  set options from config file\n");
    tidy_out(out, 0, "  -f <file>       write errors to named <file>\n");
    tidy_out(out, 0, "  -modify or -m   to modify original files\n");
    tidy_out(out, 0, "\n");

    tidy_out(out, 0, "Miscellaneous\n");
    tidy_out(out, 0, "------------\n");
    tidy_out(out, 0, "  -version or -v  show version\n");
    tidy_out(out, 0, "  -help   or -h   list command line options\n");
    tidy_out(out, 0, "You can also use --blah for any config file option blah\n");
    tidy_out(out, 0, "\n");

    tidy_out(out, 0, "Input/Output default to stdin/stdout respectively\n");
    tidy_out(out, 0, "Single letter options apart from -f may be combined\n");
    tidy_out(out, 0, "as in:  tidy -f errs.txt -imu foo.html\n");
    tidy_out(out, 0, "For further info on HTML see http://www.w3.org/MarkUp\n");
    tidy_out(out, 0, "\n");
}
#endif