/*****  名前ジェネレータ namegen    *****/
/*****  rdfile.c                    *****/



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "namegen.h"
#include "nestfile.h"
#include "put.h"


static int      def_prob_f = FALSE;             /* 確率テーブルは未定義     */


void read_namefile(char     *namefile,          /* .namファイル名へのptr    */
                   Ptrbuf   *ptrbuf_base[],     /* 各フィールドの           */
                                                /* ptrbufベース             */
                   int      wordix_max[],       /* 各ワードのワードix最大   */
                   int      gen_prob[],         /* 各フィールドの出現確率   */
                   int      *field_max,         /* フィールド数             */
                   int      verbose_level       /* 冗長モードレベル         */
                  ){

    FILE            *fp;                        /* .namファイルへのFP       */
    int             nestfile_stat;              /* nestfileからのステータス */
    char            *linetop;                   /* 入力行へのprt            */
    char            *numtok;                    /* 数値トークン切りだし用   */
    int             i;
    int             field;                      /* フィールド番号           */
    Ptrbuf          *ptrbuf_top[FIELD_MAX];     /* 現在のptrbuf             */
    int             wordix[FIELD_MAX];          /* ptrbuf内でのワードix     */
    int             setword_f[FIELD_MAX];       /* 読み込みワードをその     */
                                                /* フィールドにセットするか */


                                                /* .namファイルオープン     */
    if ((fp = fopen_nest(namefile, &nestfile_stat, (verbose_level > 0)))
        == NULL){
        error(ERR_NAMEFILE_NOT_FOUND,NULL);
    }

    while (fp != NULL){
        if (def_prob_f == FALSE){
            def_prob_f = TRUE;
                                                /* フィールド数読込         */
            linetop = read_nameline(fp, DISCARD_LINE);
            *field_max = atoi(linetop);
            if (*field_max < 1 || FIELD_MAX <= *field_max){
                error(ERR_ILLEGAL_FIELDMAX, linetop);
            }

                                                /* 各フィールドの初期化     */
            for (i = 1 ; i <= *field_max ; i ++){
                ptrbuf_base[i] = ptrbuf_top[i] = get_ptrbuf(NULL);
                wordix_max[i] = wordix[i] = 0;
            }

                                          /* 各フィールドの確率テーブル定義 */
            for (field = 1 ; field <= *field_max ; ){
                linetop = read_nameline(fp, DISCARD_LINE);
                if (linetop != NULL && field <= *field_max){
                    numtok = (char*)strtok(linetop, " ");
                    while (numtok != NULL && *numtok != '\n'){
                        gen_prob[field]  = atoi(numtok);
                        if (gen_prob[field] < 0 || 100 < gen_prob[field]){
                            error(ERR_ILLEGAL_PROB, linetop);
                        }
                        numtok = (char*)strtok(NULL, " ");
                        field ++;
                    }
                }
                else{
                    error (ERR_UNDEF_PROB, linetop);
                }
            }
        }
        linetop = read_nameline(fp, DISCARD_LINE);

                                            /*  各制御コマンドの読込実行    */
        while (linetop != NULL){
            switch (*(linetop + 1)){
                case 'f' :                          /* フィールド番号       */
                    if (verbose_level == 2){
                    putstr("\\f\n", stderr);
                    }
                    for (i = 1 ;  i <= *field_max ; i ++){
                        setword_f[i] = FALSE;
                    }
                    while ((linetop = read_nameline(fp, DISCARD_LINE)) != NULL
                           && *linetop != '\\' ){
                        numtok = (char*)strtok(linetop, " ");
                        while (numtok != NULL && *numtok != '\n'){
                            i = atoi(numtok);
                            if (i < 1 || *field_max < i){
                                error(ERR_ILLEGAL_FIELDNUM, linetop);
                            }
                            setword_f[i] = TRUE;
                            numtok = (char*)strtok(NULL, " ");
                        }
                    }
                    break;
                case 'w' :                          /* ワード               */
                    if (verbose_level == 2){
                    putstr("\\w\n", stderr);
                    }
                    while ((linetop = read_nameline(fp, RESERVE_LINE)) != NULL
                           && *linetop != '\\' ){
                        for (i = 1 ; i <= *field_max ; i ++){
                            if (setword_f[i] == TRUE){
                                ptrbuf_top[i] = set_ptr(ptrbuf_top[i],
                                                        &wordix[i],
                                                        linetop);
                                wordix_max[i]++;
                            }
                        }
                    }
                    break;
                case 'i' :                      /* ファイル挿入             */
                    if (verbose_level == 2){
                    putstr("\\i\n", stderr);
                    }
                    if ((linetop = read_nameline(fp, RESERVE_LINE)) != NULL){
                        fp = fopen_nest(linetop,
                                        &nestfile_stat,
                                        (verbose_level > 0));
                        if (nestfile_stat == STACK_OVERFLOW){
                            error(ERR_ILLEGAL_NEST, linetop);
                        }
                        else if (fp == NULL){
                            error(ERR_NAMEFILE_NOT_FOUND, NULL);
                        }
                        linetop = read_nameline(fp, DISCARD_LINE);
                    }
                    else{
                        error(ERR_ILLEGAL_INSERT, linetop);
                    }
                    break;
                    default  :
                      error (ERR_ILLEGAL_CTRL, linetop);
                    break;
            }
        }
        fp = fclose_nest(&nestfile_stat);
    }
}



char *read_nameline(FILE    *fp,                /* 読込ファイルのfp         */
                    int     mode                /*   DISCARD_LINE or        */
                                                /*   RESERVE_LINE           */
                    ){ 

    static char         *wordbuf_base  = 0;     /* wordbuf の先頭           */
    static char         *wordbuf_top            /* wordbuf の空き領域先頭   */
                        = (char *)WORDBUF_SIZE; /* 最初にget_wordbufさせる  */
    char                *ret;                   /* 今回読込んだ行へのptr  */

                                                /* 今回の読込で溢れる危険が */
                                                /* あるなら                 */
    if (wordbuf_top + READLINE_MAX > wordbuf_base + WORDBUF_SIZE){
        wordbuf_base = get_wordbuf();           /* 新しい wordbuf を確保    */
        wordbuf_top  = wordbuf_base;
    }

    do {                                        /* 一行読込                 */
        ret = fgets(wordbuf_top, READLINE_MAX, fp);
    } while (ret != NULL
             && (  *wordbuf_top == '#'          /*   コメント行は読み飛ばし */
                 ||*wordbuf_top == '\n'));      /*   空行も読み飛ばし       */

                                                /* 保存モードで非制御行なら */
    if (mode == RESERVE_LINE && *wordbuf_top != '\\'){
        wordbuf_top += strlen(wordbuf_top);     /*   ポインタを進めて       */
        *(wordbuf_top-1) =  '\0';               /*   '\n' 削除              */
    }
    return ret;
}


