/** * @file useropt.c * * * @brief ユーザ定義オプション * * * * @brief User-defined option handling * * * @author Akinobu Lee * @date Sun Sep 02 19:44:37 2007 * * $Revision: 1.5 $ * */ /* * Copyright (c) 1991-2012 Kawahara Lab., Kyoto University * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology * Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology * All rights reserved */ #include /** * List of user option data * */ static USEROPT *useropt_root = NULL; /** * * Generate a new option data. * * * 新たなユーザオプションデータを生成. * * * @return a new user option data. * */ static USEROPT * useropt_new() { USEROPT *new; new = (USEROPT *)mymalloc(sizeof(USEROPT)); new->optstr = NULL; new->desc = NULL; new->argnum = 0; new->reqargnum = 0; new->next = NULL; return new; } /** * * ユーザオプションデータを解放. * * * Release a user option data. * * * @param x [in] a user option data to release * */ static void useropt_free(USEROPT *x) { if (x->optstr) free(x->optstr); if (x->desc) free(x->desc); free(x); } /** * * Release all user option data. * * * 全てのユーザオプションデータを解放する. * * * @callgraph * @callergraph */ void useropt_free_all() { USEROPT *x, *tmp; x = useropt_root; while(x) { tmp = x->next; useropt_free(x); x = tmp; } useropt_root = NULL; } /** * * Add a user-defined option to Julius. * When reqargnum is lower than argnum, the first (reqargnum) arguments * are required and the rest (argnum - reqargnum) options are optional. * * * Julius にユーザ定義オプションを追加する. * argnum には引数の最大数,reqargnum はそのうち必須である引数の数を * 指定する. argnum > reqargnum の場合,先頭から reqargnum 個が必須で, * それ以降が optional として扱われる. * * * @param fmt [in] option string (should begin with '-') * @param argnum [in] total number of argument for this option (including optional) * @param reqargnum [in] number of required argument * @param desc [in] description string for help * @param func [in] option handling function * * @return TRUE on success, FALSE on failure * * @callgraph * @callergraph * @ingroup engine */ boolean j_add_option(char *fmt, int argnum, int reqargnum, char *desc, boolean (*func)(Jconf *jconf, char *arg[], int argnum)) { USEROPT *new; if (fmt[0] != '-') { jlog("ERROR: j_add_option: option string must start with \'-\': %s\n", fmt); return FALSE; } if (argnum < reqargnum) { /* error */ jlog("ERROR: j_add_option: number of required argument (%d) larger than total (%d)\n", reqargnum, argnum); return FALSE; } /* if this is first time, register free function at app exit */ if (useropt_root == NULL) atexit(useropt_free_all); /* allocate new */ new = useropt_new(); /* set option string */ new->optstr = strcpy((char *)mymalloc(strlen(fmt)+1), fmt); /* set number of arguments */ new->argnum = argnum; /* set number of required arguments. If less than argnum, the latter options should be optional */ new->reqargnum = reqargnum; /* set description string */ new->desc = strcpy((char*)mymalloc(strlen(desc)+1),desc); /* set user-given function to process this option */ new->func = func; /* add to list */ new->next = useropt_root; useropt_root = new; return TRUE; } /** * * Inspect for the user-specified options at option parsing * * * オプション設定においてユーザ定義オプション処理を行う. * * * * @param jconf [in] global configuration variables * @param argv [in] argument array * @param argc [in] number of arguments in argv * @param n [i/o] current position in argv * * @return 1 when the current argument was processed successfully * by one of the user options, 0 when no user option matched for the * current argument, or -1 on error. * * @callgraph * @callergraph */ int useropt_exec(Jconf *jconf, char *argv[], int argc, int *n) { USEROPT *x; int narg, i; for(x=useropt_root;x;x=x->next) { if (strmatch(argv[*n], x->optstr)) { i = *n + 1; while(i < argc && (argv[i][0] != '-' || (argv[i][1] >= '0' && argv[i][1] <= '9'))) i++; narg = i - *n - 1; if (narg > x->argnum || narg < x->reqargnum) { if (x->reqargnum != x->argnum) { jlog("ERROR: useropt_exec: \"%s\" should have at least %d argument(s)\n", x->optstr, x->reqargnum); } else { jlog("ERROR: useropt_exec: \"%s\" should have %d argument(s)\n", x->optstr, x->argnum); } return -1; /* error */ } if ((*(x->func))(jconf, &(argv[(*n)+1]), narg) == FALSE) { jlog("ERROR: useropt_exec: \"%s\" function returns FALSE\n", x->optstr); return -1; /* error */ } *n += narg; return 1; /* processed */ } } return 0; /* nothing processed */ } /** * * Output description of all the registered user options. * * * 登録されている全てのユーザ定義オプションの説明を出力する. * * * @param fp [in] file pointer to output for * * @callgraph * @callergraph */ void useropt_show_desc(FILE *fp) { USEROPT *x; int i; if (! useropt_root) return; fprintf(fp, "\n Additional options for application:\n"); for(x=useropt_root;x;x=x->next) { fprintf(fp, " [%s", x->optstr); for(i=0;ireqargnum;i++) fprintf(fp, " arg"); for(i=x->reqargnum;iargnum;i++) fprintf(fp, " (arg)"); fprintf(fp, "]\t%s\n", x->desc); } } /* end of file */