SQLite cominbed source file splitter

来源:互联网 发布:linux上snmp配置 编辑:程序博客网 时间:2024/05/18 17:57



This program splits the combined version of SQLite source code. See http://www.sqlite.org/ or http://www.sqlite.org/download.html for more of SQLite.


#include <stdio.h>

typedef enum
{
    Error = -1,
    None = 0,
    Common,
    BeginInc,
    EndInc,
    BeginFile,
    EndFile,
} LineType;

typedef int Bool;

typedef struct
{
    FILE    *file;
    char    *fname;
} Writer;

void writeToCur (Writer *cur, char *line)
{
    fprintf(cur->file, "%s", line);
}

void writeIncToCur (Writer *cur, char *chbuf)
{
    fprintf(cur->file, "#include /"%s/"", chbuf);
}

Bool nextEq (char **s, const char *t)
{
    Bool res = strncmp((*s), (t), strlen(t))==0;
    if (res)
    {
        *s += strlen(t);
    }
    return res;
}

void getFileName (char *fname, const char *p)
{
    while (*p != '*' && *p != ' ' && *p != 0)
    {
        *fname++ = *p++;
    }
    *fname = 0;
}

#define LineBufSize 1024

LineType readLine (FILE *file, char *line, char *fname)
{
    int lenLine;
    LineType type;
    if (!fgets(line, LineBufSize - 1, file))
    {
        return None;
    }
    if (strlen(line) == LineBufSize - 1)
    {   // possibly error
        return Error;
    }
    lenLine = strlen(line);
    if (lenLine > 20 && line[0] == '/' && line[1] == '*')
    {
        char *pEnd = line + lenLine;
        char *p = line + 2;
        for ( ; (*p == '*' || *p == ' ') && *p != 0; p++);
        if (p - line < 10)
        {
            return Common;
        }
        if (nextEq(&p, "Begin file "))
        {
            getFileName(fname, p);
            return BeginFile;
        }
        else if (nextEq(&p, "End of "))
        {
            getFileName(fname, p);
            return EndFile;
        }
        else if (nextEq(&p, "Include pager.h in the middle of "))
        {
            getFileName(fname, p);
            return BeginInc;
        }
        else if (nextEq(&p, "Continuing where we left off in "))
        {
            getFileName(fname, p);
            return EndInc;
        }
    }
    return Common;
}

void parse (char *sfname)
{
#define StackSize   32
    char    chbuf[128];
    char    fnbuf[256];
    char    line[LineBufSize];
    Writer  stack[StackSize];
    Writer  *cur;
    int     depth = 0;
    FILE    *srcFile = fopen(sfname, "r");

    cur = stack + depth;
    sprintf(fnbuf, "out/%s", sfname);
    cur->file = fopen(fnbuf, "w");

    while (1)
    {
        LineType type = readLine(srcFile, line, chbuf);
        if (type == Error)
        {
            printf("An error has occurred during parsing./n");
            break;
        }
        else if (type == None)
        {
            break;
        }
        switch (type)
        {
        case Common:
            writeToCur(cur, line);
            break;
        case BeginInc:
            writeIncToCur(cur, chbuf);
            break;
        case EndInc:
            break;
        case BeginFile:
            printf("Found file embedded %s/n", chbuf);
            depth++;
            cur = stack + depth;
            sprintf(fnbuf, "out/%s", chbuf);
            cur->file = fopen(fnbuf, "w");
            writeToCur(cur, line);
            break;
        case EndFile:
            writeToCur(cur, line);
            fclose(cur->file);
            depth--;
            cur = stack + depth;
            break;
        }
        if (depth < 0)
        {
            break;
        }
    }
    for ( ; depth >= 0; depth--)
    {
        cur = stack + depth;
        fclose(cur->file);
    }
}

int main (void)
{
    parse("sqlite3.c");
    return 0;
}