⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htp.c

📁 htp是一个HTML预处理器。页面可以用htp扩展的类HTML的宏编写。这可以简化维护一个一致外观的Web页面集.
💻 C
📖 第 1 页 / 共 5 页
字号:
        HtpMsg(MSG_INFO, task->infile, "dereferencing block macro \"%s\"", name);        /* build a new task structure */        newTask.infile = &incfile;        newTask.outfile = task->outfile;        newTask.sourceFilename = task->sourceFilename;        /* re-use current variable store if no local variable store was */        /* allocated, otherwise use the new one */        newTask.varstore = topVarstore;        /* process the new input file */        result = ProcessTask(&newTask);        /* remove the new context (and make sure it is, in fact, the block's */        /* context) */        if(topVarstore == &varstore)        {            assert(PeekVariableStoreContext(topVarstore) == topVarstore);            PopVariableStoreContext(topVarstore);            DestroyVariableStore(&varstore);        }        CloseFile(&incfile);        FreeMemory(name);        /* if the new file did not process, return an error, otherwise discard */        /* the markup */        return (result == TRUE) ? DISCARD_MARKUP : MARKUP_ERROR;    }    else    {        /* fatal error */        printf("%s: fatal internal error (USE)\n", PROGRAM_NAME);        FreeMemory(name);        exit(1);        /* to prevent compiler warning */        return MARKUP_ERROR;    }}   /*// Block macro destructor callback ... used whenever a block macro is// destroyed with a RemoveVariable() or ClearVariableList()*/void BlockDestructor(const char *name, const char *value, uint type, uint flags,    void *param){    UNREF_PARAM(name);    UNREF_PARAM(type);    UNREF_PARAM(flags);    /* in debug versions of htp, a special "secret" option can be set to */    /* keep BLOCK temporary files around, for later inspection ... */    /* not real useful in release versions */#if DEBUG    if(KEEPTEMP == FALSE)    {        remove(value);    }    else    {        HtpMsg(MSG_INFO, NULL, "DEBUG: keeping temporary file %s", value);    }#else    /* simply delete the temporary file holding the block macro text */    DEBUG_PRINT(("deleting file %s for block macro %s\n", value, name));    remove(value);#endif    /* DEF macros use param */    if(param != NULL)    {        FreeMemory(param);    }}uint BlockProcessor(TASK *task, HTML_MARKUP *htmlMarkup, char **newPlaintext){    char *name;    char *plaintext;    char newfile[MAX_PATHNAME_LEN];    HTML_MARKUP newHtml;    TEXTFILE blockFile;    BOOL result;    static uint blockDepth = 0;    uint markupType;    BOOL blockMacro;    uint macroType;    const char *macroTypeName;    const char *openTag;    const char *closeTag;    const char *defName;    char *param;    UNREF_PARAM(newPlaintext);    /* first: is this a BLOCK macro or a DEF macro?  This function is */    /* overloaded to handle both types, and must internally change its */    /* functionality for each type */    /* if this is false, this is a DEF macro */    if(stricmp(htmlMarkup->tag, "BLOCK") == 0)    {        blockMacro = TRUE;        macroType = VAR_TYPE_BLOCK_MACRO;        macroTypeName = "BLOCK";        openTag = "BLOCK";        closeTag = "/BLOCK";    }    else    {        assert(stricmp(htmlMarkup->tag, "DEF") == 0);        blockMacro = FALSE;        macroType = VAR_TYPE_DEF_MACRO;        macroTypeName = "DEF";        openTag = "DEF";        closeTag = "/DEF";    }    /* check markup */    if(blockMacro == TRUE)    {        /* is a name specified? (only one name can be specified) */        if(htmlMarkup->attribCount != 1)        {            HtpMsg(MSG_ERROR, task->infile, "bad BLOCK markup specified");            return MARKUP_ERROR;        }        /* no extra varstore parameter for a block macro */        param = NULL;    }    else    {        /* DEF requires at least one parameter */        if(htmlMarkup->attribCount == 0)        {            HtpMsg(MSG_ERROR, task->infile, "bad DEF markup specified");            return MARKUP_ERROR;        }        /* check that the NAME attribute is present */        if(IsAttributeInMarkup(htmlMarkup, "NAME") == FALSE)        {            HtpMsg(MSG_ERROR, task->infile, "DEF requires NAME attribute");            return MARKUP_ERROR;        }        if(MarkupAttributeValue(htmlMarkup, "NAME") == NULL)        {            HtpMsg(MSG_ERROR, task->infile, "DEF requires a NAME attribute to have a value");            return MARKUP_ERROR;        }        /* if OPTION is specified, squirrel it away with the macro */        if(IsAttributeInMarkup(htmlMarkup, "OPTION") == TRUE)        {            if((param = DuplicateString(MarkupAttributeValue(htmlMarkup, "OPTION")))                == NULL)            {                HtpMsg(MSG_ERROR, task->infile, "unable to create OPTION copy for DEF macro");                return MARKUP_ERROR;            }        }        else        {            param = NULL;        }    }    /* create a temporary filename to save the text block into */    if(CreateTempFilename(newfile, MAX_PATHNAME_LEN) == FALSE)    {        HtpMsg(MSG_ERROR, task->infile, "unable to generate temporary filename for %s macro",            macroTypeName);        FreeMemory(param);        return MARKUP_ERROR;    }    /* try and create the temporary file */    if(OpenFile(newfile, newfile, "w", &blockFile) == FALSE)    {        HtpMsg(MSG_ERROR, task->infile,            "unable to create temporary file \"%s\" for %s macro", newfile,            macroTypeName);        FreeMemory(param);        return MARKUP_ERROR;    }    /* need a private copy of the macro name */    if(blockMacro == TRUE)    {        if((name = DuplicateString(htmlMarkup->attrib[0].name)) == NULL)        {            HtpMsg(MSG_ERROR, task->infile, "unable to allocate memory for %s macro",                macroTypeName);            FreeMemory(param);            CloseFile(&blockFile);            return MARKUP_ERROR;        }    }    else    {        defName = MarkupAttributeValue(htmlMarkup, "NAME");        assert(defName != NULL);        if((name = DuplicateString(defName)) == NULL)        {            HtpMsg(MSG_ERROR, task->infile, "unable to allocate memory for %s macro",                macroTypeName);            FreeMemory(param);            CloseFile(&blockFile);            return MARKUP_ERROR;        }    }    /* store the block file name and the block macro name as a variable */    if(StoreVariable(task->varstore, name, newfile, macroType, VAR_FLAG_NONE,        param, BlockDestructor) == FALSE)    {        HtpMsg(MSG_ERROR, task->infile, "unable to store macro information (out of memory?)");        FreeMemory(name);        FreeMemory(param);        CloseFile(&blockFile);        return MARKUP_ERROR;    }    /* the name is no longer used, dont free param it will be freed in */    /* the block destructor */    FreeMemory(name);    name = NULL;    /* start copying the file into the temporary file, looking for the */    /* BLOCK or /BLOCK tag if block macro, DEF or /DEF otherwise ... */    /* just squirrel away all other tags and text */    for(;;)    {        result = ReadHtmlFile(task->infile, &blockFile, &plaintext, &markupType);        if(result == ERROR)        {            CloseFile(&blockFile);            return MARKUP_ERROR;        }        else if(result == FALSE)        {            /* end-of-file encountered before end-of-block */            HtpMsg(MSG_ERROR, task->infile, "EOF encountered before %s macro declaration closed",                macroTypeName);            CloseFile(&blockFile);            return MARKUP_ERROR;        }        /* turn the plain text into HTML structure, but don't destroy */        /* the plaintext, this will be used to copy into output file if */        /* necessary */        if(PlaintextToMarkup(plaintext, &newHtml) == FALSE)        {            /* memory alloc failed, most likely */            HtpMsg(MSG_ERROR, task->infile, "could not process markup (out of memory?)");            CloseFile(&blockFile);            FreeMemory(plaintext);            return MARKUP_ERROR;        }        if(markupType & MARKUP_TYPE_HTP)        {            /* check for embedded block declarations */            if(IsMarkupTag(&newHtml, openTag))            {                /* add to the block macro depth and continue */                blockDepth++;            }            else if(IsMarkupTag(&newHtml, closeTag) == TRUE)            {                if(blockDepth > 0)                {                    /* depth has decreased one */                    blockDepth--;                }                else                {                    /* found the end of the macro block */                    DestroyMarkupStruct(&newHtml);                    FreeMemory(plaintext);                    break;                }            }        }        /* if continuing, then the plaintext is put into the output stream */        /* as-is ... there is no case where the processor continues scanning */        /* but discards a markup */        PutFileString(&blockFile, "%c%s%c", MARKUP_OPEN_DELIM(markupType),            plaintext, MARKUP_CLOSE_DELIM(markupType));        /* destroy the HTML markup, not needed any longer */        DestroyMarkupStruct(&newHtml);        /* destroy the plaintext buffer */        FreeMemory(plaintext);        plaintext = NULL;    }    CloseFile(&blockFile);    return DISCARD_MARKUP;}   BOOL DiscardConditionalBlock(TEXTFILE *infile){    char *plaintext;    HTML_MARKUP htmlMarkup;    BOOL result;    uint embeddedConditionals;    uint markupType;    /* discard the block, looking for the matching ELSE or /IF statement */    embeddedConditionals = 0;    for(;;)    {        result = ReadHtmlFile(infile, NULL, &plaintext, &markupType);        if(result == ERROR)        {            return FALSE;        }        else if(result == FALSE)        {            /* end-of-file before end-of-conditional ... error */            HtpMsg(MSG_ERROR, infile, "EOF encountered before conditional closed");            return FALSE;        }        if(PlaintextToMarkup(plaintext, &htmlMarkup) == FALSE)        {            /* memory alloc error */            HtpMsg(MSG_ERROR, infile, "could not parse markup tag (out of memory?)");            FreeMemory(plaintext);            return FALSE;        }        /* FreeMemory the plaintext buffer, not needed any longer */        FreeMemory(plaintext);        plaintext = NULL;        /* another conditional started? */        if(IsMarkupTag(&htmlMarkup, "IF"))        {            embeddedConditionals++;        }        else if(IsMarkupTag(&htmlMarkup, "/IF"))        {            /* end of the conditional? */            if(embeddedConditionals == 0)            {                DestroyMarkupStruct(&htmlMarkup);                break;            }            embeddedConditionals--;        }        else if(IsMarkupTag(&htmlMarkup, "ELSE"))        {            /* start of TRUE block? */            if(embeddedConditionals == 0)            {                DestroyMarkupStruct(&htmlMarkup);                break;            }        }        /* destroy and continue */        DestroyMarkupStruct(&htmlMarkup);    }    return TRUE;}   uint BooleanProcessor(TASK *task, HTML_MARKUP *htmlMarkup, char **newPlaintext){    static uint conditionalLevel = 0;    const char *value;    uint type;    BOOL condTrue;    HTML_ATTRIBUTE *attrib;    BOOL notTagFound;    UNREF_PARAM(newPlaintext);    condTrue = FALSE;    /* conditionalLevel keeps track of boolean depth */    if(conditionalLevel == 0)    {        if((IsMarkupTag(htmlMarkup, "/IF")) || (IsMarkupTag(htmlMarkup, "ELSE")))        {            HtpMsg(MSG_ERROR, task->infile, "conditional block must start with IF tag");            return MARKUP_ERROR;        }    }    if(IsMarkupTag(htmlMarkup, "IF"))    {        conditionalLevel++;        /* this is an ugly way to handle the IF-IF NOT test, but will need */        /* be cleaned up in the future */        /* should either be one or two attributes in markup */        if(htmlMarkup->attribCount == 0)        {            HtpMsg(MSG_ERROR, task->infile, "no conditional to test");            return MARKUP_ERROR;        }        if(htmlMarkup->attribCount > 2)        {            HtpMsg(MSG_ERROR, task->infile, "too many items in conditional expression");            return MARKUP_ERROR;        }        /* find the attribute to evaluate and search for NOT attribute */        notTagFound = FALSE;        attrib = NULL;        if(stricmp(htmlMarkup->attrib[0].name, "NOT") == 0)        {            /* check to make sure the second attribute is present */            if(htmlMarkup->attribCount == 1)            {                HtpMsg(MSG_ERROR, task->infile, "NOT listed, no conditional to test");                return MARKUP_ERROR;            }            notTagFound = TRUE;            attrib = &htmlMarkup->attrib[1];        }        else if(htmlMarkup->attribCount == 2)        {            if(stricmp(htmlMarkup->attrib[1].name, "NOT") == 0)            {                notTagFound = TRUE;                attrib = &htmlMarkup->attrib[0];            }            else            {                /* this should have been the NOT expression */                HtpMsg(MSG_ERROR, task->infile, "too many conditionals to test");                return MARKUP_ERROR;            }        }        else        {            attrib = &htmlMarkup->attrib[0];        }        /* get the macros asso

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -