/* * Routine to handle Volume start/end Block */ static BSR *store_volblock(LEX *lc, BSR *bsr) { int token; BSR_VOLBLOCK *volblock; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } volblock = (BSR_VOLBLOCK *)malloc(sizeof(BSR_VOLBLOCK)); memset(volblock, 0, sizeof(BSR_VOLBLOCK)); volblock->sblock = lc->pint32_val; volblock->eblock = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->volblock) { bsr->volblock = volblock; } else { /* Add to end of chain */ BSR_VOLBLOCK *bs = bsr->volblock; for ( ;bs->next; bs=bs->next) { } bs->next = volblock; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
/* * Routine to handle Volume start/end address */ static BSR *store_voladdr(LEX *lc, BSR *bsr) { int token; BSR_VOLADDR *voladdr; for (;;) { token = lex_get_token(lc, T_PINT64_RANGE); if (token == T_ERROR) { return NULL; } voladdr = (BSR_VOLADDR *)malloc(sizeof(BSR_VOLADDR)); memset(voladdr, 0, sizeof(BSR_VOLADDR)); voladdr->saddr = lc->pint64_val; voladdr->eaddr = lc->pint64_val2; /* Add it to the end of the chain */ if (!bsr->voladdr) { bsr->voladdr = voladdr; } else { /* Add to end of chain */ BSR_VOLADDR *bs = bsr->voladdr; for ( ;bs->next; bs=bs->next) { } bs->next = voladdr; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
static BSR *store_job(LEX *lc, BSR *bsr) { int token; BSR_JOB *job; for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { return NULL; } job = (BSR_JOB *)malloc(sizeof(BSR_JOB)); memset(job, 0, sizeof(BSR_JOB)); bstrncpy(job->Job, lc->str, sizeof(job->Job)); /* Add it to the end of the client chain */ if (!bsr->job) { bsr->job = job; } else { /* Add to end of chain */ BSR_JOB *bc = bsr->job; for ( ;bc->next; bc=bc->next) { } bc->next = job; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
static BSR *store_findex(LEX *lc, BSR *bsr) { int token; BSR_FINDEX *findex; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } findex = (BSR_FINDEX *)malloc(sizeof(BSR_FINDEX)); memset(findex, 0, sizeof(BSR_FINDEX)); findex->findex = lc->pint32_val; findex->findex2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->FileIndex) { bsr->FileIndex = findex; } else { /* Add to end of chain */ BSR_FINDEX *bs = bsr->FileIndex; for ( ;bs->next; bs=bs->next) { } bs->next = findex; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
static BSR *store_sesstime(LEX *lc, BSR *bsr) { int token; BSR_SESSTIME *stime; for (;;) { token = lex_get_token(lc, T_PINT32); if (token == T_ERROR) { return NULL; } stime = (BSR_SESSTIME *)malloc(sizeof(BSR_SESSTIME)); memset(stime, 0, sizeof(BSR_SESSTIME)); stime->sesstime = lc->pint32_val; /* Add it to the end of the chain */ if (!bsr->sesstime) { bsr->sesstime = stime; } else { /* Add to end of chain */ BSR_SESSTIME *bs = bsr->sesstime; for ( ;bs->next; bs=bs->next) { } bs->next = stime; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
static BSR *store_client(LEX *lc, BSR *bsr) { int token; BSR_CLIENT *client; for (;;) { token = lex_get_token(lc, T_NAME); if (token == T_ERROR) { return NULL; } client = (BSR_CLIENT *)malloc(sizeof(BSR_CLIENT)); memset(client, 0, sizeof(BSR_CLIENT)); bstrncpy(client->ClientName, lc->str, sizeof(client->ClientName)); /* Add it to the end of the client chain */ if (!bsr->client) { bsr->client = client; } else { BSR_CLIENT *bc = bsr->client; for ( ;bc->next; bc=bc->next) { } bc->next = client; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
/* Parse a config file used by Plugin/Director */ bool ConfigFile::parse(const char *fname) { int token, i; bool ret=false; if (!items) { return false; } if ((lc = lex_open_file(lc, fname, s_err, s_warn)) == NULL) { berrno be; Emsg2(M_ERROR, 0, _("Cannot open config file %s: %s\n"), fname, be.bstrerror()); return false; } lc->options |= LOPT_NO_EXTERN; lc->caller_ctx = (void *)this; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(dbglevel, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } for (i = 0; items[i].name; i++) { if (strcasecmp(items[i].name, lc->str) == 0) { if ((token = lex_get_token(lc, T_EQUALS)) == T_ERROR) { Dmsg1(dbglevel, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); break; } Dmsg1(dbglevel, "calling handler for %s\n", items[i].name); /* Call item handler */ ret = items[i].found = items[i].handler(lc, this, &items[i]); i = -1; break; } } if (i >= 0) { Dmsg1(dbglevel, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); /* We can raise an error here */ break; } if (!ret) { break; } } for (i = 0; items[i].name; i++) { if (items[i].required && !items[i].found) { scan_err1(lc, "%s required but not found", items[i].name); ret = false; } } lc = lex_close_file(lc); return ret; }
static BSR *store_stream(LEX *lc, BSR *bsr) { int token; BSR_STREAM *stream; for (;;) { token = lex_get_token(lc, T_INT32); if (token == T_ERROR) { return NULL; } stream = (BSR_STREAM *)malloc(sizeof(BSR_STREAM)); memset(stream, 0, sizeof(BSR_STREAM)); stream->stream = lc->int32_val; /* Add it to the end of the chain */ if (!bsr->stream) { bsr->stream = stream; } else { /* Add to end of chain */ BSR_STREAM *bs = bsr->stream; for ( ;bs->next; bs=bs->next) { } bs->next = stream; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
/********************************************************************* * * Parse Bootstrap file * */ BSR *parse_bsr(JCR *jcr, char *fname) { LEX *lc = NULL; int token, i; BSR *root_bsr = new_bsr(); BSR *bsr = root_bsr; Dmsg1(300, "Enter parse_bsf %s\n", fname); if ((lc = lex_open_file(lc, fname, s_err)) == NULL) { berrno be; Emsg2(M_ERROR_TERM, 0, _("Cannot open bootstrap file %s: %s\n"), fname, be.bstrerror()); } lc->caller_ctx = (void *)jcr; while ((token=lex_get_token(lc, T_ALL)) != T_EOF) { Dmsg1(300, "parse got token=%s\n", lex_tok_to_str(token)); if (token == T_EOL) { continue; } for (i=0; items[i].name; i++) { if (strcasecmp(items[i].name, lc->str) == 0) { token = lex_get_token(lc, T_ALL); Dmsg1 (300, "in T_IDENT got token=%s\n", lex_tok_to_str(token)); if (token != T_EQUALS) { scan_err1(lc, "expected an equals, got: %s", lc->str); bsr = NULL; break; } Dmsg1(300, "calling handler for %s\n", items[i].name); /* Call item handler */ bsr = items[i].handler(lc, bsr); i = -1; break; } } if (i >= 0) { Dmsg1(300, "Keyword = %s\n", lc->str); scan_err1(lc, "Keyword %s not found", lc->str); bsr = NULL; break; } if (!bsr) { break; } } lc = lex_close_file(lc); Dmsg0(300, "Leave parse_bsf()\n"); if (!bsr) { free_bsr(root_bsr); root_bsr = NULL; } if (root_bsr) { root_bsr->use_fast_rejection = is_fast_rejection_ok(root_bsr); root_bsr->use_positioning = is_positioning_ok(root_bsr); } for (bsr=root_bsr; bsr; bsr=bsr->next) { bsr->root = root_bsr; } return root_bsr; }
static BSR *store_sessid(LEX *lc, BSR *bsr) { int token; BSR_SESSID *sid; for (;;) { token = lex_get_token(lc, T_PINT32_RANGE); if (token == T_ERROR) { return NULL; } sid = (BSR_SESSID *)malloc(sizeof(BSR_SESSID)); memset(sid, 0, sizeof(BSR_SESSID)); sid->sessid = lc->pint32_val; sid->sessid2 = lc->pint32_val2; /* Add it to the end of the chain */ if (!bsr->sessid) { bsr->sessid = sid; } else { /* Add to end of chain */ BSR_SESSID *bs = bsr->sessid; for ( ;bs->next; bs=bs->next) { } bs->next = sid; } token = lex_get_token(lc, T_ALL); if (token != T_COMMA) { break; } } return bsr; }
/* * Store a resource pointer in an alist. default_value indicates how many * times this routine can be called -- i.e. how many alists * there are. * * If we are in pass 2, do a lookup of the resource. */ static void store_alist_res(LEX *lc, RES_ITEM *item, int index, int pass) { RES *res; int i = 0; alist *list; URES *res_all = (URES *)my_config->m_res_all; int count = str_to_int32(item->default_value); if (pass == 2) { if (count == 0) { /* always store in item->value */ i = 0; if ((item->value)[i] == NULL) { list = New(alist(10, not_owned_by_alist)); } else { list = (alist *)(item->value)[i]; } } else { /* * Find empty place to store this directive */ while ((item->value)[i] != NULL && i++ < count) { } if (i >= count) { scan_err4(lc, _("Too many %s directives. Max. is %d. line %d: %s\n"), lc->str, count, lc->line_no, lc->line); return; } list = New(alist(10, not_owned_by_alist)); } for (;;) { lex_get_token(lc, T_NAME); /* scan next item */ res = GetResWithName(item->code, lc->str); if (res == NULL) { scan_err3(lc, _("Could not find config Resource \"%s\" referenced on line %d : %s\n"), item->name, lc->line_no, lc->line); return; } Dmsg5(900, "Append %p to alist %p size=%d i=%d %s\n", res, list, list->size(), i, item->name); list->append(res); (item->value)[i] = (char *)list; if (lc->ch != ',') { /* if no other item follows */ break; /* get out */ } lex_get_token(lc, T_ALL); /* eat comma */ } } scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); }
int main(int argc, char *argv[]){ FILE *fp; Token token; fp = fopen(argv[1], "r"); lex_initialize(fp); do{ token = lex_get_token(); if(token.kind == INT_VALUE_TOKEN){ printf("%d 整数\n", token.u.int_value); }else if(token.kind == IDENTIFIER_TOKEN){ printf("%s 識別子\n", token.u.identifier); }else if(token.kind == STRING_LITERAL_TOKEN){ printf("%s 文字列リテラル\n", token.u.string); }else if(token.kind >= EQ_TOKEN && token.kind <= SEMICOLON_TOKEN){ printf("%s 演算子または区切り子\n", st_operator_table[token.kind - EQ_TOKEN].token); }else if(token.kind != END_OF_FILE_TOKEN && token.kind >= IF_TOKEN){ printf("%s 予約語\n", st_keyword_table[token.kind - IF_TOKEN].token); } }while(token.kind != END_OF_FILE_TOKEN); fclose(fp); return 0; }
/* * Store Filename info. Note, for minor efficiency reasons, we * always increase the name buffer by 10 items because we expect * to add more entries. */ static void store_fname(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude) { int token; INCEXE *incexe; token = lex_get_token(lc, T_SKIP_EOL); if (pass == 1) { /* Pickup Filename string */ switch (token) { case T_IDENTIFIER: case T_UNQUOTED_STRING: if (strchr(lc->str, '\\')) { scan_err1(lc, _("Backslash found. Use forward slashes or quote the string.: %s\n"), lc->str); /* NOT REACHED */ } case T_QUOTED_STRING: if (res_all.res_fs.have_MD5) { MD5Update(&res_all.res_fs.md5c, (unsigned char *)lc->str, lc->str_len); } incexe = &res_incexe; if (incexe->name_list.size() == 0) { incexe->name_list.init(10, true); } incexe->name_list.append(bstrdup(lc->str)); Dmsg1(900, "Add to name_list %s\n", lc->str); break; default: scan_err1(lc, _("Expected a filename, got: %s"), lc->str); } } scan_to_eol(lc); }
/* Store an 64 bit integer at specified address */ void store_int64(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_INT64); *(int64_t *)(item->value) = lc->int64_val; scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); }
static BSR *store_fileregex(LEX *lc, BSR *bsr) { int token; int rc; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } if (bsr->fileregex) free(bsr->fileregex); bsr->fileregex = bstrdup(lc->str); if (bsr->fileregex_re == NULL) bsr->fileregex_re = (regex_t *)bmalloc(sizeof(regex_t)); rc = regcomp(bsr->fileregex_re, bsr->fileregex, REG_EXTENDED|REG_NOSUB); if (rc != 0) { char prbuf[500]; regerror(rc, bsr->fileregex_re, prbuf, sizeof(prbuf)); Emsg2(M_ERROR, 0, _("REGEX '%s' compile error. ERR=%s\n"), bsr->fileregex, prbuf); return NULL; } return bsr; }
static bool ini_store_alist_str(LEX *lc, ConfigFile *inifile, ini_items *item) { alist *list; if (!lc) { /* * TODO, write back the alist to edit buffer */ return true; } if (lex_get_token(lc, T_STRING) == T_ERROR) { return false; } if (item->val.alistval == NULL) { list = New(alist(10, owned_by_alist)); } else { list = item->val.alistval; } Dmsg4(900, "Append %s to alist %p size=%d %s\n", lc->str, list, list->size(), item->name); list->append(bstrdup(lc->str)); item->val.alistval = list; scan_to_eol(lc); return true; }
/* Store a positive integer at specified address */ void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_PINT32); *(uint32_t *)(item->value) = lc->pint32_val; scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); }
/* * Scan for message types and add them to the message * destination. The basic job here is to connect message types * (WARNING, ERROR, FATAL, INFO, ...) with an appropriate * destination (MAIL, FILE, OPERATOR, ...) */ static void scan_types(LEX *lc, MSGS *msg, int dest_code, char *where, char *cmd) { int i; bool found, is_not; int msg_type = 0; char *str; for ( ;; ) { lex_get_token(lc, T_NAME); /* expect at least one type */ found = false; if (lc->str[0] == '!') { is_not = true; str = &lc->str[1]; } else { is_not = false; str = &lc->str[0]; } for (i=0; msg_types[i].name; i++) { if (strcasecmp(str, msg_types[i].name) == 0) { msg_type = msg_types[i].token; found = true; break; } } if (!found) { scan_err1(lc, _("message type: %s not found"), str); return; } if (msg_type == M_MAX+1) { /* all? */ for (i=1; i<=M_MAX; i++) { /* yes set all types */ add_msg_dest(msg, dest_code, i, where, cmd); } } else if (is_not) { rem_msg_dest(msg, dest_code, msg_type, where); } else { add_msg_dest(msg, dest_code, msg_type, where, cmd); } if (lc->ch != ',') { break; } Dmsg0(900, "call lex_get_token() to eat comma\n"); lex_get_token(lc, T_ALL); /* eat comma */ } Dmsg0(900, "Done scan_types()\n"); }
/* * Store a positive integer at specified address */ static void store_pint32(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_PINT32); *(item->ui32value) = lc->pint32_val; scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); }
/* * Store an 64 bit integer at specified address */ static void store_int64(LEX *lc, RES_ITEM *item, int index, int pass) { URES *res_all = (URES *)my_config->m_res_all; lex_get_token(lc, T_INT64); *(item->i64value) = lc->int64_val; scan_to_eol(lc); set_bit(index, res_all->hdr.item_present); }
/* Store a string at specified address */ void store_str(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_STRING); if (pass == 1) { *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); }
/* * Come here when Options seen in Include/Exclude */ static void options_res(LEX *lc, RES_ITEM2 *item, int index, int pass, bool exclude) { int token, i; if (exclude) { scan_err0(lc, _("Options section not permitted in Exclude\n")); /* NOT REACHED */ } token = lex_get_token(lc, T_SKIP_EOL); if (token != T_BOB) { scan_err1(lc, _("Expecting open brace. Got %s"), lc->str); } if (pass == 1) { setup_current_opts(); } while ((token = lex_get_token(lc, T_ALL)) != T_EOF) { if (token == T_EOL) { continue; } if (token == T_EOB) { break; } if (token != T_IDENTIFIER) { scan_err1(lc, _("Expecting keyword, got: %s\n"), lc->str); } for (i=0; options_items[i].name; i++) { if (bstrcasecmp(options_items[i].name, lc->str)) { token = lex_get_token(lc, T_SKIP_EOL); if (token != T_EQUALS) { scan_err1(lc, _("expected an equals, got: %s"), lc->str); } /* Call item handler */ options_items[i].handler(lc, &options_items[i], i, pass); i = -1; break; } } if (i >=0) { scan_err1(lc, _("Keyword %s not permitted in this resource"), lc->str); } } }
/* * Get next token, but skip EOL */ int scan_to_next_not_eol(LEX *lc) { int token; do { token = lex_get_token(lc, T_ALL); } while (token == T_EOL); return token; }
/* * Store a name string at specified address * A name string is limited to MAX_RES_NAME_LENGTH */ void store_strname(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); /* Store the name */ if (pass == 1) { *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); }
static BSR *store_nothing(LEX *lc, BSR *bsr) { int token; token = lex_get_token(lc, T_STRING); if (token == T_ERROR) { return NULL; } return bsr; }
/* * Store a time period in seconds */ static void store_time(LEX *lc, RES_ITEM *item, int index, int pass) { int token; utime_t utime; char period[500]; URES *res_all = (URES *)my_config->m_res_all; token = lex_get_token(lc, T_SKIP_EOL); errno = 0; switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncpy(period, lc->str, sizeof(period)); /* get first part */ /* * If terminated by space, scan and get modifier */ while (lc->ch == ' ') { token = lex_get_token(lc, T_ALL); switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncat(period, lc->str, sizeof(period)); break; } } if (!duration_to_utime(period, &utime)) { scan_err1(lc, _("expected a time period, got: %s"), period); return; } *(item->utimevalue) = utime; break; default: scan_err1(lc, _("expected a time period, got: %s"), lc->str); return; } if (token != T_EOL) { scan_to_eol(lc); } set_bit(index, res_all->hdr.item_present); }
/* Store a size in bytes */ void store_size(LEX *lc, RES_ITEM *item, int index, int pass) { int token; uint64_t uvalue; char bsize[500]; Dmsg0(900, "Enter store_size\n"); token = lex_get_token(lc, T_SKIP_EOL); errno = 0; switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncpy(bsize, lc->str, sizeof(bsize)); /* save first part */ /* if terminated by space, scan and get modifier */ while (lc->ch == ' ') { token = lex_get_token(lc, T_ALL); switch (token) { case T_NUMBER: case T_IDENTIFIER: case T_UNQUOTED_STRING: bstrncat(bsize, lc->str, sizeof(bsize)); break; } } if (!size_to_uint64(bsize, strlen(bsize), &uvalue)) { scan_err1(lc, _("expected a size number, got: %s"), lc->str); return; } *(uint64_t *)(item->value) = uvalue; break; default: scan_err1(lc, _("expected a size, got: %s"), lc->str); return; } if (token != T_EOL) { scan_to_eol(lc); } set_bit(index, res_all.hdr.item_present); Dmsg0(900, "Leave store_size\n"); }
/* Store reader info */ static void store_plugin(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup plugin command */ res_incexe.current_opts->plugin = bstrdup(lc->str); } scan_to_eol(lc); }
/* Store Base info */ static void store_base(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_NAME); if (pass == 1) { /* * Pickup Base Job Name */ res_incexe.current_opts->base.append(bstrdup(lc->str)); } scan_to_eol(lc); }
/* * Store a directory name at specified address. Note, we do * shell expansion except if the string begins with a vertical * bar (i.e. it will likely be passed to the shell later). */ void store_dir(LEX *lc, RES_ITEM *item, int index, int pass) { lex_get_token(lc, T_STRING); if (pass == 1) { if (lc->str[0] != '|') { do_shell_expansion(lc->str, sizeof(lc->str)); } *(item->value) = bstrdup(lc->str); } scan_to_eol(lc); set_bit(index, res_all.hdr.item_present); }