示例#1
0
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 );
    }
}
示例#2
0
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;
}
示例#3
0
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);
    }
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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);
}
示例#7
0
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;
    }
}
示例#8
0
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;
}
示例#9
0
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;
    }
}
示例#10
0
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;
}
示例#11
0
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;
}
示例#12
0
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);
    }
}
示例#13
0
static void FreeDict( TidyDocImpl* doc, Dict *d )
{
    if ( d )
        TidyDocFree( doc, d->name );
    TidyDocFree( doc, d );
}
示例#14
0
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 );
}
示例#15
0
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);
}
示例#16
0
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 );
}
示例#17
0
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);
}