void tidyDocRelease( TidyDocImpl* doc ) { /* doc in/out opened and closed by parse/print routines */ if ( doc ) { assert( doc->docIn == NULL ); assert( doc->docOut == NULL ); TY_(ReleaseStreamOut)( doc, doc->errout ); doc->errout = NULL; TY_(FreePrintBuf)( doc ); TY_(FreeLexer)( doc ); TY_(FreeNode)(doc, &doc->root); TidyClearMemory(&doc->root, sizeof(Node)); if (doc->givenDoctype) TidyDocFree(doc, doc->givenDoctype); TY_(FreeConfig)( doc ); TY_(FreeAttrTable)( doc ); TY_(FreeTags)( doc ); TidyDocFree( doc, doc ); } }
Bool TIDY_CALL tidyNodeGetText( TidyDoc tdoc, TidyNode tnod, TidyBuffer* outbuf ) { TidyDocImpl* doc = tidyDocToImpl( tdoc ); Node* nimp = tidyNodeToImpl( tnod ); if ( doc && nimp && outbuf ) { uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); StreamOut* out = TY_(BufferOutput)( doc, outbuf, outenc, nl ); Bool xmlOut = cfgBool( doc, TidyXmlOut ); Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut ); doc->docOut = out; if ( xmlOut && !xhtmlOut ) TY_(PPrintXMLTree)( doc, NORMAL, 0, nimp ); else TY_(PPrintTree)( doc, NORMAL, 0, nimp ); TY_(PFlushLine)( doc, 0 ); doc->docOut = NULL; TidyDocFree( doc, out ); return yes; } return no; }
void tidy_out( TidyDocImpl* doc, ctmbstr msg, ... ) { if ( !cfgBool(doc, TidyQuiet) ) { TidyOutputSink *outp = &doc->errout->sink; ctmbstr cp; enum { sizeBuf=2048 }; char *buf = (char *)TidyDocAlloc(doc,sizeBuf); byte b; va_list args; va_start( args, msg ); TY_(tmbvsnprintf)(buf, sizeBuf, msg, args); va_end( args ); for ( cp=buf; *cp; ++cp ) { b = (*cp & 0xff); if (b == (byte)'\n') TY_(WriteChar)( b, doc->errout ); /* for EOL translation */ else outp->putByte( outp->sinkData, b ); /* #383 - no encoding */ } TidyDocFree(doc, buf); } }
int tidyDocSaveSink( TidyDocImpl* doc, TidyOutputSink* sink ) { uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); StreamOut* out = TY_(UserOutput)( doc, sink, outenc, nl ); int status = tidyDocSaveStream( doc, out ); TidyDocFree( doc, out ); return status; }
int tidyDocSaveBuffer( TidyDocImpl* doc, TidyBuffer* outbuf ) { int status = -EINVAL; if ( outbuf ) { uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); StreamOut* out = TY_(BufferOutput)( doc, outbuf, outenc, nl ); status = tidyDocSaveStream( doc, out ); TidyDocFree( doc, out ); } return status; }
static void PopIStack( TidyDocImpl* doc ) { Lexer* lexer = doc->lexer; IStack *istack; AttVal *av; --(lexer->istacksize); istack = &(lexer->istack[lexer->istacksize]); while (istack->attributes) { av = istack->attributes; istack->attributes = av->next; TY_(FreeAttribute)( doc, av ); } TidyDocFree(doc, istack->element); }
static void removeFromHash( TidyDocImpl* doc, TidyTagImpl* tags, ctmbstr s ) { uint h = hash(s); DictHash *p, *prev = NULL; for (p = tags->hashtab[h]; p && p->tag; p = p->next) { if (TY_(tmbstrcmp)(s, p->tag->name) == 0) { DictHash* next = p->next; if ( prev ) prev->next = next; else tags->hashtab[h] = next; TidyDocFree(doc, p); return; } prev = p; } }
int tidyDocSaveStdout( TidyDocImpl* doc ) { #if !defined(NO_SETMODE_SUPPORT) #if defined(_WIN32) || defined(OS2_OS) int oldstdoutmode = -1, oldstderrmode = -1; #endif #endif int status = 0; uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); StreamOut* out = TY_(FileOutput)( doc, stdout, outenc, nl ); #if !defined(NO_SETMODE_SUPPORT) #if defined(_WIN32) || defined(OS2_OS) oldstdoutmode = setmode( fileno(stdout), _O_BINARY ); oldstderrmode = setmode( fileno(stderr), _O_BINARY ); #endif #endif if ( 0 == status ) status = tidyDocSaveStream( doc, out ); fflush(stdout); fflush(stderr); #if !defined(NO_SETMODE_SUPPORT) #if defined(_WIN32) || defined(OS2_OS) if ( oldstdoutmode != -1 ) oldstdoutmode = setmode( fileno(stdout), oldstdoutmode ); if ( oldstderrmode != -1 ) oldstderrmode = setmode( fileno(stderr), oldstderrmode ); #endif #endif TidyDocFree( doc, out ); return status; }
static void emptyHash( TidyDocImpl* doc, TidyTagImpl* tags ) { uint i; DictHash *prev, *next; for (i = 0; i < ELEMENT_HASH_SIZE; ++i) { prev = NULL; next = tags->hashtab[i]; while(next) { prev = next->next; TidyDocFree(doc, next); next = prev; } tags->hashtab[i] = NULL; } }
int tidyDocSaveString( TidyDocImpl* doc, tmbstr buffer, uint* buflen ) { uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); TidyBuffer outbuf; StreamOut* out; int status; tidyBufInitWithAllocator( &outbuf, doc->allocator ); out = TY_(BufferOutput)( doc, &outbuf, outenc, nl ); status = tidyDocSaveStream( doc, out ); if ( outbuf.size > *buflen ) status = -ENOMEM; else memcpy( buffer, outbuf.bp, outbuf.size ); *buflen = outbuf.size; tidyBufFree( &outbuf ); TidyDocFree( doc, out ); return status; }
int tidyDocSaveFile( TidyDocImpl* doc, ctmbstr filnam ) { int status = -ENOENT; FILE* fout = NULL; /* Don't zap input file if no output */ if ( doc->errors > 0 && cfgBool(doc, TidyWriteBack) && !cfgBool(doc, TidyForceOutput) ) status = tidyDocStatus( doc ); else fout = fopen( filnam, "wb" ); if ( fout ) { uint outenc = cfg( doc, TidyOutCharEncoding ); uint nl = cfg( doc, TidyNewline ); StreamOut* out = TY_(FileOutput)( doc, fout, outenc, nl ); status = tidyDocSaveStream( doc, out ); fclose( fout ); TidyDocFree( doc, out ); #if PRESERVE_FILE_TIMES if ( doc->filetimes.actime ) { /* set file last accessed/modified times to original values */ utime( filnam, &doc->filetimes ); TidyClearMemory( &doc->filetimes, sizeof(doc->filetimes) ); } #endif /* PRESERVFILETIMES */ } if ( status < 0 ) /* Error message! */ TY_(FileError)( doc, filnam, TidyError ); return status; }
void tidy_out( TidyDocImpl* doc, ctmbstr msg, ... ) { if ( !cfgBool(doc, TidyQuiet) ) { ctmbstr cp; enum { sizeBuf=2048 }; char *buf = (char *)TidyDocAlloc(doc,sizeBuf); va_list args; va_start( args, msg ); TY_(tmbvsnprintf)(buf, sizeBuf, msg, args); va_end( args ); #if !defined(NDEBUG) && defined(_MSC_VER) add_std_out(0); #endif for ( cp=buf; *cp; ++cp ) TY_(WriteChar)( *cp, doc->errout ); #if !defined(NDEBUG) && defined(_MSC_VER) add_std_out(1); #endif TidyDocFree(doc, buf); } }
static void FreeDict( TidyDocImpl* doc, Dict *d ) { if ( d ) TidyDocFree( doc, d->name ); TidyDocFree( doc, d ); }
int TY_(DocParseStream)( TidyDocImpl* doc, StreamIn* in ) { Bool xmlIn = cfgBool( doc, TidyXmlTags ); int bomEnc; assert( doc != NULL && in != NULL ); assert( doc->docIn == NULL ); doc->docIn = in; TY_(TakeConfigSnapshot)( doc ); /* Save config state */ TY_(FreeLexer)( doc ); TY_(FreeAnchors)( doc ); TY_(FreeNode)(doc, &doc->root); TidyClearMemory(&doc->root, sizeof(Node)); if (doc->givenDoctype) TidyDocFree(doc, doc->givenDoctype); doc->givenDoctype = NULL; doc->lexer = TY_(NewLexer)( doc ); /* doc->lexer->root = &doc->root; */ doc->root.line = doc->lexer->lines; doc->root.column = doc->lexer->columns; doc->inputHadBOM = no; bomEnc = TY_(ReadBOMEncoding)(in); if (bomEnc != -1) { in->encoding = bomEnc; TY_(SetOptionInt)(doc, TidyInCharEncoding, bomEnc); } #ifdef TIDY_WIN32_MLANG_SUPPORT if (in->encoding > WIN32MLANG) TY_(Win32MLangInitInputTranscoder)(in, in->encoding); #endif /* TIDY_WIN32_MLANG_SUPPORT */ /* Tidy doesn't alter the doctype for generic XML docs */ if ( xmlIn ) { TY_(ParseXMLDocument)( doc ); if ( !TY_(CheckNodeIntegrity)( &doc->root ) ) TidyPanic( doc->allocator, integrity ); } else { doc->warnings = 0; TY_(ParseDocument)( doc ); if ( !TY_(CheckNodeIntegrity)( &doc->root ) ) TidyPanic( doc->allocator, integrity ); } #ifdef TIDY_WIN32_MLANG_SUPPORT TY_(Win32MLangUninitInputTranscoder)(in); #endif /* TIDY_WIN32_MLANG_SUPPORT */ doc->docIn = NULL; return tidyDocStatus( doc ); }
static void messagePos( TidyDocImpl* doc, TidyReportLevel level, uint code, int line, int col, ctmbstr msg, va_list args ) { enum { sizeMessageBuf=2048 }; char *messageBuf = TidyDocAlloc(doc,sizeMessageBuf); Bool go = UpdateCount( doc, level ); if ( go ) { va_list args_copy; va_copy(args_copy, args); TY_(tmbvsnprintf)(messageBuf, sizeMessageBuf, msg, args); if ( doc->mssgFilt ) { TidyDoc tdoc = tidyImplToDoc( doc ); go = doc->mssgFilt( tdoc, level, line, col, messageBuf ); } if ( doc->mssgFilt2 ) { /* mssgFilt2 is intended to allow LibTidy users to localize messages via their own means by providing a key string and the parameters to fill it. For the key string to remain consistent, we have to ensure that we only ever return the built-in English version of this string. */ TidyDoc tdoc = tidyImplToDoc( doc ); go = go | doc->mssgFilt2( tdoc, level, line, col, tidyDefaultString(code), args_copy ); } if ( doc->mssgFilt3 ) { /* mssgFilt3 is intended to allow LibTidy users to localize messages via their own means by providing a key string and the parameters to fill it. */ TidyDoc tdoc = tidyImplToDoc( doc ); go = go | doc->mssgFilt3( tdoc, level, line, col, tidyErrorCodeAsString(code), args_copy ); } } if ( go ) { enum { sizeBuf=1024 }; char *buf = TidyDocAlloc(doc,sizeBuf); const char *cp; if ( line > 0 && col > 0 ) { ReportPosition(doc, line, col, buf, sizeBuf); #if !defined(NDEBUG) && defined(_MSC_VER) SPRTF("%s",buf); #endif for ( cp = buf; *cp; ++cp ) TY_(WriteChar)( *cp, doc->errout ); } LevelPrefix( level, buf, sizeBuf ); #if !defined(NDEBUG) && defined(_MSC_VER) SPRTF("%s",buf); SPRTF("%s\n",messageBuf); #else for ( cp = buf; *cp; ++cp ) TY_(WriteChar)( *cp, doc->errout ); for ( cp = messageBuf; *cp; ++cp ) TY_(WriteChar)( *cp, doc->errout ); TY_(WriteChar)( '\n', doc->errout ); #endif TidyDocFree(doc, buf); } TidyDocFree(doc, messageBuf); }
int tidyDocCleanAndRepair( TidyDocImpl* doc ) { Bool word2K = cfgBool( doc, TidyWord2000 ); Bool logical = cfgBool( doc, TidyLogicalEmphasis ); Bool clean = cfgBool( doc, TidyMakeClean ); Bool dropFont = cfgBool( doc, TidyDropFontTags ); Bool htmlOut = cfgBool( doc, TidyHtmlOut ); Bool xmlOut = cfgBool( doc, TidyXmlOut ); Bool xhtmlOut = cfgBool( doc, TidyXhtmlOut ); Bool xmlDecl = cfgBool( doc, TidyXmlDecl ); Bool tidyMark = cfgBool( doc, TidyMark ); Bool tidyXmlTags = cfgBool( doc, TidyXmlTags ); Bool wantNameAttr = cfgBool( doc, TidyAnchorAsName ); Bool mergeEmphasis = cfgBool( doc, TidyMergeEmphasis ); Node* node; if (tidyXmlTags) return tidyDocStatus( doc ); /* simplifies <b><b> ... </b> ...</b> etc. */ if ( mergeEmphasis ) TY_(NestedEmphasis)( doc, &doc->root ); /* cleans up <dir>indented text</dir> etc. */ TY_(List2BQ)( doc, &doc->root ); TY_(BQ2Div)( doc, &doc->root ); /* replaces i by em and b by strong */ if ( logical ) TY_(EmFromI)( doc, &doc->root ); if ( word2K && TY_(IsWord2000)(doc) ) { /* prune Word2000's <![if ...]> ... <![endif]> */ TY_(DropSections)( doc, &doc->root ); /* drop style & class attributes and empty p, span elements */ TY_(CleanWord2000)( doc, &doc->root ); TY_(DropEmptyElements)(doc, &doc->root); } /* replaces presentational markup by style rules */ if ( clean || dropFont ) TY_(CleanDocument)( doc ); /* Move terminating <br /> tags from out of paragraphs */ /*! Do we want to do this for all block-level elements? */ /* This is disabled due to http://tidy.sf.net/bug/681116 */ #if 0 FixBrakes( doc, TY_(FindBody)( doc )); #endif /* Reconcile http-equiv meta element with output encoding */ if (cfg( doc, TidyOutCharEncoding) != RAW #ifndef NO_NATIVE_ISO2022_SUPPORT && cfg( doc, TidyOutCharEncoding) != ISO2022 #endif ) TY_(VerifyHTTPEquiv)( doc, TY_(FindHEAD)( doc )); if ( !TY_(CheckNodeIntegrity)( &doc->root ) ) TidyPanic( doc->allocator, integrity ); /* remember given doctype for reporting */ node = TY_(FindDocType)(doc); if (node) { AttVal* fpi = TY_(GetAttrByName)(node, "PUBLIC"); if (AttrHasValue(fpi)) { if (doc->givenDoctype) TidyDocFree(doc, doc->givenDoctype); doc->givenDoctype = TY_(tmbstrdup)(doc->allocator,fpi->value); } } if ( doc->root.content ) { /* If we had XHTML input but want HTML output */ if ( htmlOut && doc->lexer->isvoyager ) { Node* node = TY_(FindDocType)(doc); /* Remove reference, but do not free */ if (node) TY_(RemoveNode)(node); } if (xhtmlOut && !htmlOut) { TY_(SetXHTMLDocType)(doc); /* TY_(FixAnchors)(doc, &doc->root, wantNameAttr, yes); */ TY_(FixXhtmlNamespace)(doc, yes); TY_(FixLanguageInformation)(doc, &doc->root, yes, yes); } else { TY_(FixDocType)(doc); TY_(FixAnchors)(doc, &doc->root, wantNameAttr, yes); TY_(FixXhtmlNamespace)(doc, no); TY_(FixLanguageInformation)(doc, &doc->root, no, yes); } if (tidyMark ) TY_(AddGenerator)(doc); } /* ensure presence of initial <?xml version="1.0"?> */ if ( xmlOut && xmlDecl ) TY_(FixXmlDecl)( doc ); return tidyDocStatus( doc ); }
static void messagePos( TidyDocImpl* doc, TidyReportLevel level, uint code, int line, int col, ctmbstr msg, va_list args ) { enum { sizeMessageBuf=2048 }; char *messageBuf = TidyDocAlloc(doc,sizeMessageBuf); Bool go = UpdateCount( doc, level ); if ( go ) { va_list args_copy; va_copy(args_copy, args); TY_(tmbvsnprintf)(messageBuf, sizeMessageBuf, msg, args_copy); if ( doc->mssgFilt ) { TidyDoc tdoc = tidyImplToDoc( doc ); go = doc->mssgFilt( tdoc, level, line, col, messageBuf ); } if ( doc->mssgFilt2 ) { /* mssgFilt2 is intended to allow LibTidy users to localize messages via their own means by providing a key string and the parameters to fill it. For the key string to remain consistent, we have to ensure that we only ever return the built-in English version of this string. */ TidyDoc tdoc = tidyImplToDoc( doc ); va_end(args_copy); va_copy(args_copy, args); go = go | doc->mssgFilt2( tdoc, level, line, col, tidyDefaultString(code), args_copy ); } if ( doc->mssgFilt3 ) { /* mssgFilt3 is intended to allow LibTidy users to localize messages via their own means by providing a key string and the parameters to fill it. */ TidyDoc tdoc = tidyImplToDoc( doc ); va_end(args_copy); va_copy(args_copy, args); go = go | doc->mssgFilt3( tdoc, level, line, col, tidyErrorCodeAsString(code), args_copy ); } va_end(args_copy); } if ( go ) { enum { sizeBuf=1024 }; TidyOutputSink *outp = &doc->errout->sink; char *buf = (char *)TidyDocAlloc(doc,sizeBuf); const char *cp; byte b; if ( line > 0 && col > 0 ) { ReportPosition(doc, line, col, buf, sizeBuf); for ( cp = buf; *cp; ++cp ) { b = (*cp & 0xff); outp->putByte( outp->sinkData, b ); } } LevelPrefix( level, buf, sizeBuf ); for ( cp = buf; *cp; ++cp ) { b = (*cp & 0xff); outp->putByte( outp->sinkData, b ); } for ( cp = messageBuf; *cp; ++cp ) { b = (*cp & 0xff); outp->putByte( outp->sinkData, b ); } TY_(WriteChar)( '\n', doc->errout ); TidyDocFree(doc, buf); } TidyDocFree(doc, messageBuf); }