C語言項目分析(一)

#include <sys/stat.h>
#include <dirent.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct {
    const char *name;
    const char *languages;
    const char *identifier;
    unsigned char gender;
    unsigned char age;
    unsigned char variant;
    unsigned char xx1;
    int score;
    void *spare;
} espeak_VOICE;

typedef struct {
    const char *mnem;
    int  value;
} MNEM_TAB;

MNEM_TAB genders [] = {
        {"unknown", 0},
        {"male", 1},
        {"female", 2},
        {NULL, 0 }
};

char path_home[160];
int n_voices_list = 0;

void strncpy0(char *to,const char *from, int size)
{//===================================================
// strcpy with limit, ensures a zero terminator
    strncpy(to,from,size);
    to[size-1] = 0;
}

static char *fgets_strip(char *buf, int size, FILE *f_in)
{//======================================================
// strip trailing spaces, and truncate lines at // comment
    int len;
    char *p;

    if(fgets(buf,size,f_in) == NULL)
        return(NULL);

    if(buf[0] == '#')
    {
        buf[0] = 0;
        return(buf);
    }

    len = strlen(buf);
    while((--len > 0) && isspace(buf[len]))
        buf[len] = 0;

    if((p = strstr(buf,"//")) != NULL)
        *p = 0;

    return(buf);
}


int LookupMnem(MNEM_TAB *table, const char *string)
{//==================================================
    while(table->mnem != NULL)
    {
        if(strcmp(string,table->mnem)==0)
            return(table->value);
        table++;
    }
    return(table->value);
}

int GetFileLength(const char *filename)
{
    struct stat statbuf;
    if(stat(filename,&statbuf) != 0)
        return(0);

    if((statbuf.st_mode & S_IFMT) == S_IFDIR)
        return(-2);  // a directory
    return(statbuf.st_size);
}

static espeak_VOICE *ReadVoiceFile(FILE *f_in, const char *fname, const char*leafname)
{

    char linebuf[120];
    char vname[80];
    char vgender[80];
    char vlanguage[80];
    char languages[300];


    unsigned int len;
    int langix = 0;
    int n_languages = 0;
    char *p;
    espeak_VOICE *voice_data;
    int priority;
    int age;
    int n_variants = 4;
    int gender;

    vname[0] = 0;
    vgender[0] = 0;
    age = 0;

    while(fgets_strip(linebuf,sizeof(linebuf),f_in) != NULL)
    {
        if(memcmp(linebuf,"name",4)==0)
        {
            p = &linebuf[4];
            while(isspace(*p)) p++;
            strncpy0(vname,p,sizeof(vname));
        }
        else if(memcmp(linebuf,"language",8)==0)
        {
            priority = 5;
            vlanguage[0] = 0;

            sscanf(&linebuf[8],"%s %d",vlanguage,&priority);
            len = strlen(vlanguage) + 2;
            // check for space in languages[]
            if(len < (sizeof(languages)-langix-1))
            {
                languages[langix] = priority;

                strcpy(&languages[langix+1],vlanguage);
                langix += len;
                n_languages++;
            }
        }
        else if(memcmp(linebuf,"gender",6)==0)
        {
            sscanf(&linebuf[6],"%s %d",vgender,&age);
        }
        else if(memcmp(linebuf,"variants",8)==0)
        {
            sscanf(&linebuf[8],"%d",&n_variants);
        }
    }
    languages[langix++] = 0;

    gender = LookupMnem(genders,vgender);

    if(n_languages == 0)
    {
        return(NULL);    // no language lines in the voice file
    }

    p = (char *)calloc(sizeof(espeak_VOICE) + langix + strlen(fname) + strlen(vname) + 3, 1);
    voice_data = (espeak_VOICE *)p;
    p = &p[sizeof(espeak_VOICE)];

    memcpy(p,languages,langix);
    voice_data->languages = p;

    strcpy(&p[langix],fname);
    voice_data->identifier = &p[langix];
    voice_data->name = &p[langix];

    if(vname[0] != 0)
    {
        langix += strlen(fname)+1;
        strcpy(&p[langix],vname);
        voice_data->name = &p[langix];
    }

    voice_data->age = age;
    voice_data->gender = gender;
    voice_data->variant = 0;
    voice_data->xx1 = n_variants;
    return(voice_data);
}


static void GetVoices(const char *path) {
    static espeak_VOICE *voices_list[250];
    FILE *f_voice;
    espeak_VOICE *voice_data;
    int ftype;
    char fname[sizeof(path_home) + 100];

    DIR *dir;
    struct dirent *ent;

    if ((dir = opendir((char *) path)) == NULL)
        return;

    while ((ent = readdir(dir)) != NULL) {
        if (n_voices_list >= (250 - 2))
            break;

        if (ent->d_name[0] == '.')
            continue;

        sprintf(fname, "%s%s%s", path, "/", ent->d_name);
        printf("%d %s\t\t%s\n",n_voices_list,ent->d_name,fname);

        ftype = GetFileLength(fname);
        printf("%d======\n",ftype);
        if (ftype == -2) {
            // a sub-sirectory
            GetVoices(fname);
        } else if (ftype > 0) {
            // a regular line, add it to the voices list
            if ((f_voice = fopen(fname, "r")) == NULL)
                continue;

            // pass voice file name within the voices directory
            voice_data = ReadVoiceFile(f_voice, fname + 62, ent->d_name);
            fclose(f_voice);

            if (voice_data != NULL) {
                voices_list[n_voices_list++] = voice_data;
            }
        }
    }
    closedir(dir);
}

int main(){
    char *filepath = "espeak-data";
    GetVoices(filepath);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章