/* Avoid thrashing memory by doubling buffer size ** until larger than requested size. buf->allocated is bigger than allocSize+1 so that a trailing null byte is always available. */ void TIDY_CALL tidyBufCheckAlloc( TidyBuffer* buf, uint allocSize, uint chunkSize ) { assert( buf != NULL ); if ( !buf->allocator ) setDefaultAllocator( buf ); if ( 0 == chunkSize ) chunkSize = 256; if ( allocSize+1 > buf->allocated ) { byte* bp; uint allocAmt = chunkSize; if ( buf->allocated > 0 ) allocAmt = buf->allocated; while ( allocAmt < allocSize+1 ) allocAmt *= 2; bp = (byte*)TidyRealloc( buf->allocator, buf->bp, allocAmt ); if ( bp != NULL ) { TidyClearMemory( bp + buf->allocated, allocAmt - buf->allocated ); buf->bp = bp; buf->allocated = allocAmt; } } }
void TIDY_CALL tidyBufInitWithAllocator( TidyBuffer* buf, TidyAllocator *allocator ) { assert( buf != NULL ); TidyClearMemory( buf, sizeof(TidyBuffer) ); buf->allocator = allocator ? allocator : &TY_(g_default_allocator); }
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 ); } }
void TIDY_CALL tidyBufClear( TidyBuffer* buf ) { assert( buf != NULL ); if ( buf->bp ) { TidyClearMemory( buf->bp, buf->allocated ); buf->size = 0; } buf->next = 0; }
void TY_(FreeTags)( TidyDocImpl* doc ) { TidyTagImpl* tags = &doc->tags; #if ELEMENT_HASH_LOOKUP emptyHash( doc, tags ); #endif TY_(FreeDeclaredTags)( doc, tagtype_null ); FreeDict( doc, tags->xml_tags ); /* get rid of dangling tag references */ TidyClearMemory( tags, sizeof(TidyTagImpl) ); }
void TY_(InitTags)( TidyDocImpl* doc ) { Dict* xml; TidyTagImpl* tags = &doc->tags; TidyClearMemory( tags, sizeof(TidyTagImpl) ); /* create dummy entry for all xml tags */ xml = NewDict( doc, NULL ); xml->versions = VERS_XML; xml->model = CM_BLOCK; xml->parser = 0; xml->chkattrs = 0; xml->attrvers = NULL; tags->xml_tags = xml; }
TidyDocImpl* tidyDocCreate( TidyAllocator *allocator ) { TidyDocImpl* doc = (TidyDocImpl*)TidyAlloc( allocator, sizeof(TidyDocImpl) ); TidyClearMemory( doc, sizeof(*doc) ); doc->allocator = allocator; TY_(InitMap)(); TY_(InitTags)( doc ); TY_(InitAttrs)( doc ); TY_(InitConfig)( doc ); TY_(InitPrintBuf)( doc ); /* By default, wire tidy messages to standard error. ** Document input will be set by parsing routines. ** Document output will be set by pretty print routines. ** Config input will be set by config parsing routines. ** But we need to start off with a way to report errors. */ doc->errout = TY_(StdErrOutput)(); return doc; }
int tidyDocParseFile( TidyDocImpl* doc, ctmbstr filnam ) { #ifdef _WIN32 return TY_(DocParseFileWithMappedFile)( doc, filnam ); #else int status = -ENOENT; FILE* fin = fopen( filnam, "rb" ); #if PRESERVE_FILE_TIMES struct stat sbuf = {0}; /* get last modified time */ TidyClearMemory( &doc->filetimes, sizeof(doc->filetimes) ); if ( fin && cfgBool(doc,TidyKeepFileTimes) && fstat(fileno(fin), &sbuf) != -1 ) { doc->filetimes.actime = sbuf.st_atime; doc->filetimes.modtime = sbuf.st_mtime; } #endif if ( fin ) { StreamIn* in = TY_(FileInput)( doc, fin, cfg( doc, TidyInCharEncoding )); if ( !in ) { fclose( fin ); return status; } status = TY_(DocParseStream)( doc, in ); TY_(freeFileSource)(&in->source, yes); TY_(freeStreamIn)(in); } else /* Error message! */ TY_(FileError)( doc, filnam, TidyError ); return status; #endif }
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; }
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 ); }