static int skip_code(parser_ctx_t *ctx, BOOL exec_else) { int if_depth = 1; const WCHAR *ptr; while(1) { ptr = strchrW(ctx->ptr, '@'); if(!ptr) { WARN("No @end\n"); return lex_error(ctx, JS_E_EXPECTED_CCEND); } ctx->ptr = ptr+1; if(!check_keyword(ctx, endW, NULL)) { if(--if_depth) continue; return 0; } if(exec_else && !check_keyword(ctx, elifW, NULL)) { if(if_depth > 1) continue; if(!skip_spaces(ctx) || *ctx->ptr != '(') return lex_error(ctx, JS_E_MISSING_LBRACKET); if(!parse_cc_expr(ctx)) return -1; if(!get_ccbool(ctx->ccval)) continue; /* skip block of code */ /* continue parsing */ ctx->cc_if_depth++; return 0; } if(exec_else && !check_keyword(ctx, elseW, NULL)) { if(if_depth > 1) continue; /* parse else block */ ctx->cc_if_depth++; return 0; } if(!check_keyword(ctx, ifW, NULL)) { if_depth++; continue; } ctx->ptr++; } }
static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval) { int min = 0, max = ARRAY_SIZE(keywords)-1, r, i; while(min <= max) { i = (min+max)/2; r = check_keyword(ctx, keywords[i].word, lval); if(!r) { if(ctx->script->version < keywords[i].min_version) { TRACE("ignoring keyword %s in incompatible mode\n", debugstr_w(keywords[i].word)); ctx->ptr -= strlenW(keywords[i].word); return 0; } ctx->implicit_nl_semicolon = keywords[i].no_nl; return keywords[i].token; } if(r > 0) min = i+1; else max = i-1; } return 0; }
int jdfits_write_header_double (JDFits_Type *ft, char *name, double val, char *comment) { char buf[JDFITS_CARD_SIZE + 1]; char numbuf[64]; int prec; if ((-1 == check_keyword (name)) || (-1 == check_ascii(comment, 1))) return -1; /* According to the FITS NOST document, the resulting value should be right * justified in columns 11-30. It must contain a decimal point and E must * be used if with in exponential form. */ prec = 16; do { if (-1 == format_double (val, prec, numbuf)) { strcpy (numbuf, "Floating point exception"); jdfits_warning ("jdfits_write_header_double: unable to convert value\n"); prec = 0; } prec--; sprintf (buf, "%-8s= %20s", name, numbuf); } while ((prec > 5) && (strlen (buf) > 30)); jdfits_append_comment (buf, comment); return jdfits_write (ft, (unsigned char *) buf, JDFITS_CARD_SIZE); }
void shell() { char put_ch[2]={'0','\0'}; char *p = NULL; char *str ="\rShell:~$"; for (;; cur_his = (cur_his + 1) % HISTORY_COUNT) { /* need use & that p can work correct, idk why p = cmd[cur_his] can't work */ p = &cmd[cur_his][0]; printf("%s",str); while (1) { //put_ch = receive_byte(); read(open("/dev/tty0/in", 0), put_ch, 1); if (put_ch[0] == '\r' || put_ch[0] == '\n') { *p = '\0'; printf("%s",next_line); break; } else if (put_ch[0]== 127 || put_ch[0] == '\b') { if (p > &cmd[cur_his][0]) { p--; printf("\b \b"); } } else if (p - &cmd[cur_his][0] < CMDBUF_SIZE - 1) { *(p++) = put_ch[0]; printf("%c",put_ch[0]); } } check_keyword(); } }
int main(int argc, char *argv[]) { // Check the number of input parameters if (argc != 2) { printf("Incorrect number of command-line arguments specified.\n"); return 1; } // Check the correctness of the keyword if (!check_keyword(argv[1])) { printf("Incorrect command-line argument specified.\n"); return 1; } // Input a plaintext string char *str = GetString(); // Encode the text with the Viginere cipher encode_viginere(str, argv[1]); //Output the string printf("%s\n", str); // Free the memory free(str); return 0; }
void GenPropertyVisitor::operator()(const Property &p) { std::string kd = check_keyword(keywords_double, p.name); std::string ki = check_keyword(keywords_int, p.name); std::string ks = check_keyword(keywords_string, p.name); if (kd != "") { if (d_values.find(kd) != d_values.end()) THROW_EXC(ValueAlreadySet, "value already set"); else d_values[kd] = p.get_double(); } if (ki != "") { if (i_values.find(ki) != i_values.end()) THROW_EXC(ValueAlreadySet, "value already set"); else i_values[ki] = p.get_int(); } if (ks != "") { if (s_values.find(ks) != s_values.end()) THROW_EXC(ValueAlreadySet, "value already set"); else s_values[ks] = p.get_value(); } }
int try_parse_ccval(parser_ctx_t *ctx, ccval_t *r) { if(!skip_spaces(ctx)) return -1; if(isdigitW(*ctx->ptr)) { double n; if(!parse_numeric_literal(ctx, &n)) return -1; *r = ccval_num(n); return 1; } if(*ctx->ptr == '@') { const WCHAR *ident; unsigned ident_len; cc_var_t *cc_var; if(!parse_cc_identifier(ctx, &ident, &ident_len)) return -1; cc_var = find_cc_var(ctx->script->cc, ident, ident_len); *r = cc_var ? cc_var->val : ccval_num(NAN); return 1; } if(!check_keyword(ctx, trueW, NULL)) { *r = ccval_bool(TRUE); return 1; } if(!check_keyword(ctx, falseW, NULL)) { *r = ccval_bool(FALSE); return 1; } return 0; }
static int cc_token(parser_ctx_t *ctx, void *lval) { unsigned id_len = 0; cc_var_t *var; static const WCHAR cc_onW[] = {'c','c','_','o','n',0}; static const WCHAR setW[] = {'s','e','t',0}; static const WCHAR elifW[] = {'e','l','i','f',0}; static const WCHAR endW[] = {'e','n','d',0}; ctx->ptr++; if(!check_keyword(ctx, cc_onW, NULL)) return init_cc(ctx); if(!check_keyword(ctx, setW, NULL)) { FIXME("@set not implemented\n"); return lex_error(ctx, E_NOTIMPL); } if(!check_keyword(ctx, ifW, NULL)) { FIXME("@if not implemented\n"); return lex_error(ctx, E_NOTIMPL); } if(!check_keyword(ctx, elifW, NULL)) { FIXME("@elif not implemented\n"); return lex_error(ctx, E_NOTIMPL); } if(!check_keyword(ctx, elseW, NULL)) { FIXME("@else not implemented\n"); return lex_error(ctx, E_NOTIMPL); } if(!check_keyword(ctx, endW, NULL)) { FIXME("@end not implemented\n"); return lex_error(ctx, E_NOTIMPL); } if(!ctx->script->cc) return lex_error(ctx, JS_E_DISABLED_CC); while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len])) id_len++; if(!id_len) return '@'; TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len)); var = find_cc_var(ctx->script->cc, ctx->ptr, id_len); ctx->ptr += id_len; if(!var || var->is_num) { *(literal_t**)lval = new_double_literal(ctx, var ? var->u.n : ret_nan()); return tNumericLiteral; } *(literal_t**)lval = new_boolean_literal(ctx, var->u.b); return tBooleanLiteral; }
int jdfits_write_header_integer (JDFits_Type *ft, char *name, int val, char *comment) { char buf[JDFITS_CARD_SIZE + 1]; if ((-1 == check_keyword (name)) || (-1 == check_ascii(comment, 1))) return -1; sprintf (buf, "%-8s= %20d", name, val); jdfits_append_comment (buf, comment); return jdfits_write (ft, (unsigned char *) buf, JDFITS_CARD_SIZE); }
void serial_test_task(void* arg) { char put_ch[2]={'0','\0'}; char hint[] = USER_NAME "@" USER_NAME "-STM32:~$ "; int hint_length = sizeof(hint); char *p = NULL; fdout = mq_open("/tmp/mqueue/out", O_CREAT); fdin = open("/dev/tty0/in", 0); for (;; cur_his = (cur_his + 1) % HISTORY_COUNT) { p = cmd[cur_his]; write(fdout, hint, hint_length); while (1) { read(fdin, put_ch, 1); key_count++; if (put_ch[0] == '\r' || put_ch[0] == '\n') { *p = '\0'; write(fdout, next_line, 3); break; } else if (put_ch[0] == 127 || put_ch[0] == '\b') { if (p > cmd[cur_his] && key_count) { p--; write(fdout, "\b \b", 4); key_count--; } } else if (p - cmd[cur_his] < CMDBUF_SIZE - 1) { *p++ = put_ch[0]; write(fdout, put_ch, 2); /* press keyboard 'up' show last history */ if(key_count > 2 && !strncmp(p-3, keyup, 3)){ write(fdout, keydown, 4); key_count -= 3; show_keyup(); p = cmd[cur_his] + key_count; continue; } } } key_count = 0; check_keyword(); } }
void lexA(){ f.open(file, ifstream::in); skip_blanks(); char peek = f.peek(); if( is_number(peek) ){ get_number(peek); }else if( is_char(peek) ){ check_keyword(peek); }else if( is_special(peek) ){ handle_special(peek); }else{ get_identifier(); } }
static int check_keywords(parser_ctx_t *ctx, const WCHAR **lval) { int min = 0, max = sizeof(keywords)/sizeof(keywords[0])-1, r, i; while(min <= max) { i = (min+max)/2; r = check_keyword(ctx, keywords[i].word, lval); if(!r) return keywords[i].token; if(r > 0) min = i+1; else max = i-1; } return 0; }
int jdfits_write_header_string (JDFits_Type *ft, char *name, char *s, char *comment) { char buf[JDFITS_CARD_SIZE + 1]; char *b, *bmax, *bsave, ch; if ((-1 == check_keyword (name)) || (-1 == check_ascii (s, 0)) || (-1 == check_ascii (comment, 1))) return -1; /* Strings must begin with a ' character in column 11 and have a closing one * before the end of the card. Actually the closing one must be at column * 20 or beyond. */ sprintf (buf, "%-8s= '", name); bsave = b = buf + strlen(buf); bmax = buf + JDFITS_CARD_SIZE; while (b < bmax) { ch = *s++; if (ch == 0) { /* Now pad it with blanks */ bmax = bsave + 8; while (b < bmax) *b++ = ' '; *b = '\''; *(b + 1) = 0; jdfits_append_comment (buf, comment); return jdfits_write (ft, (unsigned char *) buf, JDFITS_CARD_SIZE); } if (ch == '\'') { *b++ = ch; if (b == bmax) break; } *b++ = ch; } jdfits_error ("String is too long for keyword %s", name); return -1; }
void serial_test_task() { char put_ch[2]={'0','\0'}; char hint[] = USER_NAME "@" USER_NAME "-STM32:~$ "; int hint_length = sizeof(hint); char *p = NULL; int cmd_count = 0; fdout = mq_open("/tmp/mqueue/out", 0); fdin = open("/dev/tty0/in", 0); for (;; cur_his = (cur_his + 1) % HISTORY_COUNT) { p = cmd[cur_his]; write(fdout, hint, hint_length); while (1) { read(fdin, put_ch, 1); if (put_ch[0] == '\r' || put_ch[0] == '\n') { *p = '\0'; write(fdout, next_line, 3); break; } else if (put_ch[0] == 127 || put_ch[0] == '\b') { if (p > cmd[cur_his]) { p--; write(fdout, "\b \b", 4); } } else if (p - cmd[cur_his] < CMDBUF_SIZE - 1) { *p++ = put_ch[0]; write(fdout, put_ch, 2); } } check_keyword(); } }
int check_keyword(char loglist[HISTORY_LIMIT][MAX_LINE],char *args[ARGNUM],int *history_mode,int *next_replace_index,int *history_count,char *input,int *runbkg,char *input_buffer){ int i; i=0; while(args[i]!=NULL){ if(strcmp(args[i],"exit")==0){ return 1; } if(strcmp(args[0],"history")==0){ *history_mode=1; printf("history detected\n"); show_history_proper(loglist,next_replace_index,history_count); } if(strcmp(args[0],"!!")==0){ // *history_mode=1; // get input value of previous, ptrtok that again, search for keywords again, then fork & execute get_prev_cmd(loglist,next_replace_index,input); strcpy(input_buffer,input); strip_input(input,args); check_keyword(loglist,args,history_mode,next_replace_index,history_count,input,runbkg,input_buffer); } if(strcmp(args[i],"&")==0){ // if & is included, run it in background args[i]=NULL; *runbkg=1; } i++; } return 0; }
int main(void){ char *args[ARGNUM]; int should_run=1; char input[MAX_LINE]; char input_buffer[MAX_LINE]; int i,j; int runbkg; int history_mode=0; int next_replace_index=0; int history_count=0; char loglist[HISTORY_LIMIT][MAX_LINE]; for(i=0;i<HISTORY_LIMIT;i++){ // reseting loglist sprintf(loglist[i],""); } while(should_run){ runbkg=0; // reset args array for(i=0;i<ARGNUM;i++){ args[i]=NULL; } printf("osh>"); //fflush(stdout); fgets(input,MAX_LINE,stdin); // get input. enter(\n) value will be included. // removing last newline and replace it with null for(i=0;i<ARGNUM;i++){ if(input[i]=='\n'){ input[i]='\0'; break; } } strcpy(input_buffer,input); // make copy of input for later use with history //save input in history log // update_history(input,loglist,&next_replace_index,&history_count); // printf("next_replace_index: %d, history_count: %d\n",next_replace_index,history_count); // show_history(loglist); // // printf("before input: %s\n",input); strip_input(input,args); printf("split complete\n"); if(check_keyword(loglist,args,&history_mode,&next_replace_index,&history_count,input,&runbkg,input_buffer)){ return 0; } printf("input buffer: %s\n",input_buffer); if(history_mode==1){ // used just for skipping remainder history_mode=0; continue; // skip the executing part below since history command is not a proper command } // history mode will not increment next_replace_index, history_count. update_history(input_buffer,loglist,&next_replace_index,&history_count); // printf("next_replace_index: %d, history_count: %d\n",next_replace_index,history_count); // show_history(loglist); i=0; // printf("args listing with null ending\n"); // while(args[i]!=NULL){ // print all args values // printf("%d %s\n",i,args[i]); // i++; // } // pid_t pid; pid=fork(); // forking if(pid<0){ printf("error\n"); } else if(pid==0){ //child process // printf("child-args: %s\n",args[0]); execvp(args[0],args); return 0; } else{ // parent process // printf("runbkg: %d\n",runbkg); // printf("child pid:%d \n",pid); int status; if(runbkg==0){ waitpid(pid,&status,0); // printf("wait executed\n"); } } } // end of should run return 0; }
uint8_t comentario_parser(uint8_t * cadena, uint16_t index, uint8_t token_t) { index++; uint16_t len = strlen(cadena); uint8_t temp[len+1]; memset(temp, 0, sizeof(temp)); uint16_t i=0; uint16_t indice = 0; uint8_t chars = 0; uint8_t espacios = 0; for(i=index;i<len;i++) { if(isspace(cadena[i])) { if(chars == 1 && espacios == 0) espacios++; } else if(!isalpha(cadena[i]) && !isdigit(cadena[i]) && cadena[i] != '_') { debug("\nError en linea %d: el compilador encontro un intento de definir una variable en un comentario. Sin embargo, el valor %c no es permitido\n", linea,cadena[i]); return 0; } else { if(chars == 0 && espacios == 0) chars++; else if(espacios == 1) { debug("\nError en linea %d: el compilador encontro un intento de definir una variable en un comentario. Sin embargo, el nombre de la variable no debe contener espacios\n", linea); return 0; } temp[indice++] = cadena[i]; } } if(!check_keyword(temp)) return 0; else if(indice == 0) { debug("\nError en linea %d: debes ingresar el nombre de una variable\n", linea); return 0; } uint8_t token = ht_get(temp); if(token != 0) { if(token == NUMERO && token_t == CHAR) debug("\nError en linea %d: la variable \"%s\" ya fue declarada como entero. Por lo tanto, no puedes declarla como \"char\"\n",linea,temp); else if((token == CADENA || token == FLOAT) && token_t == CHAR) debug("\nError en linea %d: la variable \"%s\" ya fue declarada. No puedes redefinirla como \"char\"\n",linea,temp); else if(token == NUMERO && token_t == FLOAT) debug("\nError en linea %d: la variable \"%s\" ya fue declarada como entero. Por lo tanto, no puedes redefinirla como \"float\"",linea,temp); else if(token == FLOAT && token_t == FLOAT) debug("\nError en linea %d: la variable \"%s\" ya fue declarada. No puedes redefinirla como \"float\"\n",linea,temp); return 0; } else if(token == 0) { if(var_get(temp) != 0) debug("\nAviso en la linea %d: has repetido la misma declaracion, por lo cual se ha omitido. No causa conflictos, pero se recomienda que se elimine\n", linea); else { uint8_t id = var_put(temp, token_t); if(id == 0 || id == 2) return 0; } } return 1; }
int main(int argc, char **argv) { char ruby_code[1024] = { 0 }; char last_code_line[1024] = { 0 }; #ifndef ENABLE_READLINE int last_char; int char_index; #else char *home = NULL; #endif mrbc_context *cxt; struct mrb_parser_state *parser; mrb_state *mrb; mrb_value result; struct _args args; int n; mrb_bool code_block_open = FALSE; int ai; unsigned int stack_keep = 0; /* new interpreter instance */ mrb = mrb_open(); if (mrb == NULL) { fputs("Invalid mrb interpreter, exiting mirb\n", stderr); return EXIT_FAILURE; } mrb_define_global_const(mrb, "ARGV", mrb_ary_new_capa(mrb, 0)); n = parse_args(mrb, argc, argv, &args); if (n == EXIT_FAILURE) { cleanup(mrb, &args); usage(argv[0]); return n; } print_hint(); cxt = mrbc_context_new(mrb); cxt->capture_errors = 1; cxt->lineno = 1; mrbc_filename(mrb, cxt, "(mirb)"); if (args.verbose) cxt->dump_result = 1; ai = mrb_gc_arena_save(mrb); #ifdef ENABLE_READLINE MIRB_USING_HISTORY(); home = getenv("HOME"); #ifdef _WIN32 if (!home) home = getenv("USERPROFILE"); #endif if (home) { strcpy(history_path, home); strcat(history_path, "/"); strcat(history_path, history_file_name); MIRB_READ_HISTORY(history_path); } #endif while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); char_index = 0; while ((last_char = getchar()) != '\n') { if (last_char == EOF) break; if (char_index > sizeof(last_code_line)-2) { fputs("input string too long\n", stderr); continue; } last_code_line[char_index++] = last_char; } if (last_char == EOF) { fputs("\n", stdout); break; } last_code_line[char_index++] = '\n'; last_code_line[char_index] = '\0'; #else char* line = MIRB_READLINE(code_block_open ? "* " : "> "); if (line == NULL) { printf("\n"); break; } if (strlen(line) > sizeof(last_code_line)-2) { fputs("input string too long\n", stderr); continue; } strcpy(last_code_line, line); strcat(last_code_line, "\n"); MIRB_ADD_HISTORY(line); free(line); #endif if (code_block_open) { if (strlen(ruby_code)+strlen(last_code_line) > sizeof(ruby_code)-1) { fputs("concatenated input string too long\n", stderr); continue; } strcat(ruby_code, last_code_line); } else { if (check_keyword(last_code_line, "quit") || check_keyword(last_code_line, "exit")) { break; } strcpy(ruby_code, last_code_line); } /* parse code */ parser = mrb_parser_new(mrb); parser->s = ruby_code; parser->send = ruby_code + strlen(ruby_code); parser->lineno = cxt->lineno; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); if (code_block_open) { /* no evaluation of code */ } else { if (0 < parser->nerr) { /* syntax error */ printf("line %d: %s\n", parser->error_buffer[0].lineno, parser->error_buffer[0].message); } else { /* generate bytecode */ struct RProc *proc = mrb_generate_code(mrb, parser); if (args.verbose) { mrb_codedump_all(mrb, proc); } /* pass a proc for evaulation */ /* evaluate the bytecode */ result = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep); stack_keep = proc->body.irep->nlocals; /* did an exception occur? */ if (mrb->exc) { p(mrb, mrb_obj_value(mrb->exc), 0); mrb->exc = 0; } else { /* no */ if (!mrb_respond_to(mrb, result, mrb_intern_lit(mrb, "inspect"))){ result = mrb_any_to_s(mrb,result); } p(mrb, result, 1); } } ruby_code[0] = '\0'; last_code_line[0] = '\0'; mrb_gc_arena_restore(mrb, ai); } mrb_parser_free(parser); cxt->lineno++; } mrbc_context_free(mrb, cxt); mrb_close(mrb); #ifdef ENABLE_READLINE MIRB_WRITE_HISTORY(history_path); #endif return 0; }
int push_val(int type) { unsigned int mul, val; int op; char c; val = 0; c = *expr; switch (type) { /* program counter */ case T_PC: if (data_loccnt == -1) val = (loccnt + (page << 13)); else val = (data_loccnt + (page << 13)); expr++; break; /* char ascii value */ case T_CHAR: expr++; val = *expr++; if ((*expr != c) || (val == 0)) { error("Syntax Error!"); return (0); } expr++; break; /* symbol */ case T_SYMBOL: /* extract it */ if (!getsym()) return (0); /* an user function? */ if (func_look()) { if (!func_getargs()) return (0); expr_stack[func_idx++] = expr; expr = func_ptr->line; return (1); } /* a predefined function? */ op = check_keyword(); if (op) { if (!push_op(op)) return (0); else return (1); } /* search the symbol */ expr_lablptr = stlook(1); /* check if undefined, if not get its value */ if (expr_lablptr == NULL) return (0); else if (expr_lablptr->type == UNDEF) undef++; else if (expr_lablptr->type == IFUNDEF) undef++; else val = expr_lablptr->value; /* remember we have seen a symbol in the expression */ expr_lablcnt++; break; /* binary number %1100_0011 */ case T_BINARY: mul = 2; goto extract; /* hexa number $15AF */ case T_HEXA: mul = 16; goto extract; /* decimal number 48 (or hexa 0x5F) */ case T_DECIMAL: if ((c == '0') && (toupper(expr[1]) == 'X')) { mul = 16; expr++; } else { mul = 10; val = c - '0'; } /* extract a number */ extract: for (;;) { expr++; c = *expr; if (isdigit(c)) c -= '0'; else if (isalpha(c)) { c = toupper(c); if (c < 'A' && c > 'F') break; else { c -= 'A'; c += 10; } } else if (c == '_' && mul == 2) continue; else break; if (c >= mul) break; val = (val * mul) + c; } break; } /* check for too big expression */ if (val_idx == 63) { error("Expression too complex!"); return (0); } /* push the result on the value stack */ val_idx++; val_stack[val_idx] = val; /* next must be an operator */ need_operator = 1; /* ok */ return (1); }
static int cc_token(parser_ctx_t *ctx, void *lval) { unsigned id_len = 0; cc_var_t *var; static const WCHAR cc_onW[] = {'c','c','_','o','n',0}; static const WCHAR setW[] = {'s','e','t',0}; ctx->ptr++; if(!check_keyword(ctx, cc_onW, NULL)) return init_cc(ctx) ? 0 : -1; if(!check_keyword(ctx, setW, NULL)) { const WCHAR *ident; unsigned ident_len; cc_var_t *var; if(!init_cc(ctx)) return -1; if(!skip_spaces(ctx)) return lex_error(ctx, JS_E_EXPECTED_AT); if(!parse_cc_identifier(ctx, &ident, &ident_len)) return -1; if(!skip_spaces(ctx) || *ctx->ptr != '=') return lex_error(ctx, JS_E_EXPECTED_ASSIGN); ctx->ptr++; if(!parse_cc_expr(ctx)) { WARN("parsing CC expression failed\n"); return -1; } var = find_cc_var(ctx->script->cc, ident, ident_len); if(var) { var->val = ctx->ccval; }else { if(!new_cc_var(ctx->script->cc, ident, ident_len, ctx->ccval)) return lex_error(ctx, E_OUTOFMEMORY); } return 0; } if(!check_keyword(ctx, ifW, NULL)) { if(!init_cc(ctx)) return -1; if(!skip_spaces(ctx) || *ctx->ptr != '(') return lex_error(ctx, JS_E_MISSING_LBRACKET); if(!parse_cc_expr(ctx)) return -1; if(get_ccbool(ctx->ccval)) { /* continue parsing block inside if */ ctx->cc_if_depth++; return 0; } return skip_code(ctx, TRUE); } if(!check_keyword(ctx, elifW, NULL) || !check_keyword(ctx, elseW, NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX); return skip_code(ctx, FALSE); } if(!check_keyword(ctx, endW, NULL)) { if(!ctx->cc_if_depth) return lex_error(ctx, JS_E_SYNTAX); ctx->cc_if_depth--; return 0; } if(!ctx->script->cc) return lex_error(ctx, JS_E_DISABLED_CC); while(ctx->ptr+id_len < ctx->end && is_identifier_char(ctx->ptr[id_len])) id_len++; if(!id_len) return '@'; TRACE("var %s\n", debugstr_wn(ctx->ptr, id_len)); var = find_cc_var(ctx->script->cc, ctx->ptr, id_len); ctx->ptr += id_len; if(!var || var->val.is_num) { *(literal_t**)lval = new_double_literal(ctx, var ? var->val.u.n : NAN); return tNumericLiteral; } *(literal_t**)lval = new_boolean_literal(ctx, var->val.u.b); return tBooleanLiteral; }
int jdfits_write_header_comment (JDFits_Type *ft, char *name, char *comment) { char buf[JDFITS_CARD_SIZE + 1]; char *bmin, *bmax, *b, ch; if (name == NULL) name = ""; /* Check for all blanks which is ok for comments */ b = name; while (((ch = *b++) != 0) && (ch == ' ')) ; if (ch == 0) { if (strlen (name) > 8) { jdfits_error ("A keyword must be less than 9 characters long."); return -1; } } else if (-1 == check_keyword (name)) return -1; if (comment == NULL) comment = ""; if (-1 == check_ascii (comment, 1)) return -1; sprintf (buf, "%-8s ", name); bmin = buf + 9; bmax = buf + JDFITS_CARD_SIZE; while (1) { b = bmin; while (((ch = *comment) != 0) && (b < bmax)) { comment++; if (ch == '\n') break; *b++ = ch; } if ((b == bmax) && (ch != 0)) { char *bmin_2; unsigned int diff; diff = bmax - bmin; bmin_2 = bmin + (diff / 2); /* Try to break it at a space. */ b--; while ((b > bmin_2) && (*b != ' ')) b--; if (b > bmin_2) { comment -= (bmax - b); comment++; /* +1 to avoid the space */ ch = ' '; } else { comment--; b = bmax; *(b - 1) = '\\'; } } while (b < bmax) *b++ = ' '; *b = 0; if (-1 == jdfits_write (ft, (unsigned char *) buf, JDFITS_CARD_SIZE)) return -1; if ((ch == '\n') && (*comment == 0)) break; if (ch == 0) break; } return 0; }
/* Funkcia spusti konecny automat na spracovanie lexemu */ tToken get_Token(){ tState state = sStart; int i = 0; // pocitadlo nacitanych znakov int c; // prave nacitany znak int escap; //pomocna premenna na urcenie escape sekvencii int escap2; // -||- bool cont = true; char hexa[3]; //spracovanie hexadecimalneho cisla. /* inicializacia tokenu */ token.id = sStart; init_string(&i); /* Cyklus while ktory reprezentuje DKA */ while((c = getc(file)) && (cont)){ switch(state){ case sStart:{ if((isalpha(c)) || (c == '_')) state = sIdent; else if((c > '0') && (c <= '9')) state = sInteger; else if(c == '=') state = sAssign; else if(c == '/') state = sDivide; else if(c == '!') state = sExclam; else if(c == '>') state = sGreater; else if(c == '<') state = sLess; else if(c == ';') state = sSemicolon; else if(c == '(') state = sLParenth; else if(c == ')') state = sRParenth; else if(c == '{') state = sLSetPar; else if(c == '}') state = sRSetPar; else if(c == '+') state = sPlus; else if(c == '-') state = sMinus; else if(c == '*') state = sMult; else if(c == ',') state = sComma; else if(c == EOF) state = sEndofFile; else if(c == '"'){ state = sString; break; } else if(c == '0'){ state = sNull; break; } //Ak sa jedna o biely znak else if(isspace(c)){ state = sStart; break; } //Nejedna sa o lexem jazyka IFJ15 else{ state = sError; break; } //rozsir token o prve nacitany znak expand_token(c, &i); break; } //prvy nacitany znak bol 0 case sNull:{ if(c == '0'){ state = sNull; } else if((c > '0') && (c <= '9')){ state = sInteger; expand_token(c, &i); //rozsirime token o jeden znak } else if(c == '.'){ state = sIsDouble; expand_token('0', &i); expand_token(c, &i); } else{ state = sInteger; expand_token('0', &i); fill_token(state); //prepiseme id tokenu state = sEnd; undo_c(c); //posledny nacitany znak vratime spat } break; } //prvy nacitany znak bol '_' alebo pismeno case sIdent:{ if((isdigit(c)) || (isalpha(c)) || c == '_'){ state = sIdent; expand_token(c, &i); } else{ /* * kedze sa jedna o identifikator, musime sa * uistit, ci nejde o klucove alebo o rezervovane slovo */ token.id = check_keyword(token.attribute); state = sEnd; undo_c(c); } break; } //Prvy nacitany znak bol numericky. case sInteger:{ if(isdigit(c)){ state = sInteger; expand_token(c, &i); } else if(c == '.'){ //desatinne cislo state = sIsDouble; expand_token(c, &i); } else if((c == 'e') || (c == 'E')){ //cele cislo s exp. state = sIsExpo; expand_token(c, &i); } else{ //Nacitali sme ine ako cislo, posielame token int. fill_token(state); state = sEnd; undo_c(c); } break; } //skontrolujem ci po desatinnej bodke nasleduje cislo case sIsDouble:{ if(isdigit(c)){ state = sDouble; expand_token(c, &i); } else { state = sError; undo_c(c); } break; } //desatinne cislo case sDouble:{ if(isdigit(c)){ state = sDouble; expand_token(c, &i); } else if((c == 'e') || (c == 'E')){ //desatinne cislo s exponentom state = sIsExpo; expand_token(c, &i); } else{ fill_token(state); state = sEnd; undo_c(c); } break; } /* skontrolujeme ci je zadane znamienko pre exponent * alebo hned nasleduje cislo, v opacnom pripade sa jedna * o chybu. */ case sIsExpo:{ if((c == '+') || (c == '-')){ state = sIsExpo2; expand_token(c, &i); } else if(isdigit(c)){ state = sExpo; expand_token(c, &i); } else{ state = sError; undo_c(c); } break; } //skontrolujeme ci po znamienku je cislo case sIsExpo2:{ if(isdigit(c)){ state = sExpo; expand_token(c, &i); } else{ //Chyba, po znamienku nasleduje iny znak ako cislo. state = sError; undo_c(c); } } //nacitavanie cislic pre exponent. case sExpo:{ if(isdigit(c)){ state = sExpo; expand_token(c, &i); } else{ state = sDouble; fill_token(state); state = sEnd; undo_c(c); } break; } //Ak bola nacitana uvodzovka, jedna sa o retazec. case sString:{ if(c == '"'){ fill_token(state); state = sEnd; } else if((c == '\n') || (c == EOF)){ state = sError; } else if(c == 92){ state = sEscSeq; } else{ expand_token(c, &i); state = sString; } break; } //Escape sekvencia v retazci. case sEscSeq:{ if(c == '"'){ state = sString; expand_token(c, &i); } else if(c == 'n'){ escap = '\n'; state = sString; expand_token(escap, &i); } else if(c == 't'){ escap = '\t'; state = sString; expand_token(escap, &i); } else if(c == 92){ state = sString; expand_token(c, &i); } else if(c == 'x'){ escap = 'x'; state = sEscHex; } else{ state = sError; undo_c(c); } break; } /* * Zadavanie znakov pomocou escape * sekvencie vramci retazcoveho literalu */ case sEscHex:{ if(isxdigit(c)){ state = sEscHex2; escap2 = c; hexa[0] = (char)c; } else{ state = sError; undo_c(c); } break; } /* * Pokracovanie hex. v escape sekvecii */ case sEscHex2:{ if(isxdigit(c)){ state = sString; hexa[1] = (char)c; hexa[2] = '\0'; escap2 = HextoDec(hexa); if(escap2 == 0){ state = sError; } else{ expand_token(escap2, &i); } } else{ state = sError; undo_c(c); } break; } //prvy znak bol '=' case sAssign:{ if(c == '='){ state = sEqual; expand_token(c, &i); } else{ fill_token(state); state = sEnd; undo_c(c); } break; } //prvy znak bol '/' case sDivide:{ if(c == '/'){ state = sLComment; } else if(c == '*'){ state = sBComment; } else{ fill_token(state); state = sEnd; undo_c(c); } break; } //jedna sa o riadkovy komentar case sLComment:{ if(c == '\n'){ state = sStart; i = 0; } else if (c == EOF){ state = sEndofFile; } else{ state = sLComment; } break; } //Blokovy komenta /* case sBComment:{ if(c == '*'){ state = sBlockEnd; } else if(c == EOF){ state = sError; } else{ state = sBComment; } break; } //Zisti ci sa blokovy komentar spravny dokoncil case sBlockEnd:{ if(c == '/'){ state = sStart; i = 0; } else if(c == EOF){ state = sError; } else{ state = sBComment; } break; } //prvy nacitany znak bol ! case sExclam:{ if(c == '='){ state = sNotEq; expand_token(c, &i); } else{ // ! samotny nie je lexem jazyka IFJ15 state = sError; undo_c(c); } break; } // prvy nacitany znak je > case sGreater:{ if(c == '='){ // >= state = sGrorEq; expand_token(c, &i); } else if(c == '>'){ // >> state = sCin; expand_token(c, &i); } else{ // >> fill_token(state); state = sEnd; undo_c(c); } break; } //Prvy nacitany znak bol < case sLess:{ if(c == '='){ //<= state = sLeorEq; expand_token(c, &i); } else if(c == '<'){ // << state = sCout; expand_token(c, &i); } else{ // < fill_token(state); state = sEnd; undo_c(c); } break; } case sEqual: // == case sNotEq: // != case sGrorEq: // >= case sLeorEq: // <= case sSemicolon: // ; case sLParenth: // ( case sRParenth: // ) case sLSetPar: // { case sRSetPar: // } case sPlus: // + case sMinus: // - case sMult: // * case sEndofFile: // EOF case sComma: // , case sCout: // << case sCin: // >> case sKeyWord: case sResWord:{ fill_token(state); state = sEnd; undo_c(c); break; } //Nastala lexikalna chyba case sError:{ scaner_error = LEX_ERR; fill_token(state); cont = false; break; } //Koncovy stav DKA case sEnd:{ undo_c(c); undo_c(c); cont = false; break; } } //Nastala lexikalna chyba if(scaner_error){ break; } /* Ak bol precitany znak noveho riadku * inkrementujeme pocitadlo riadkov. */ if(c == '\n'){ row++; } } PomUk = token.attribute; /* Vratime token parseru */ return token; }
//hlavni funkce struct lexeme read_lexeme(void) { struct lexeme tmpData; tmpData.type = NO_TYPE; read_input(); q0: //default state if(PRINT) printf("q0 default\n"); switch(input_char_type) { case UNDERSCORE: case LETTER: temp_length = 0; save_temp(input_char); read_input(); goto q1; //identifier case DIGIT: tmpData.type = INTEGER; temp_length = 0; save_temp(input_char); read_input(); goto q4; //integer or double break; case WHITE_SPACE: read_input(); goto q0; //default state /* case UNDERSCORE: temp_length = 0; save_temp(input_char); read_input(); goto q1; //underscored identifier */ case END: tmpData.type = END_OF_FILE; return tmpData; case OTHERS: switch(input_char) { case '+': tmpData.type = PLUS; return tmpData; case '-': tmpData.type = MINUS; return tmpData; case '*': tmpData.type = MULT; return tmpData; case '/': read_input(); goto q3; //comments or divide case '=': read_input(); if(input_char == '=') { tmpData.type = EQ; return tmpData; } return_input(); tmpData.type = EQUALS; return tmpData; case '<': read_input(); if(input_char == '=') { tmpData.type = LTE; return tmpData; } else if(input_char == '<') { tmpData.type = INSOP; return tmpData; } return_input(); tmpData.type = LT; return tmpData; case '>': read_input(); if(input_char == '=') { tmpData.type = GTE; return tmpData; } else if(input_char == '>') { tmpData.type = EXTOP; return tmpData; } return_input(); tmpData.type = GT; return tmpData; case '!': read_input(); if(input_char == '=') { tmpData.type = NEQ; return tmpData; } throw_error(CODE_ERROR_LEX, "invalid input"); break; case ';': tmpData.type = SEMICOLON; return tmpData; case '(': tmpData.type = LPAR; return tmpData; case ')': tmpData.type = RPAR; return tmpData; case '{': tmpData.type = LBR; return tmpData; case '}': tmpData.type = RBR; return tmpData; case ',': tmpData.type = COLON; return tmpData; case '"': tmpData.type = STRING; temp_length = 0; chunks = 0; length = 0; read_input(); goto q8; //string default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } break; default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } q1: //identifier OK if(PRINT) printf("q1 identifier\n"); switch(input_char_type) { case LETTER: case DIGIT: save_temp(input_char); read_input(); goto q1; //identifier case UNDERSCORE: save_temp(input_char); read_input(); goto q1; //underscored identifier default: return_input(); save_temp(0); if((tmpData.type = check_keyword(temp)) == IDENTIFIER) { if((tmpData.value.string = (char *)malloc(temp_length)) == NULL) throw_error(CODE_ERROR_INTERNAL, "malloc error"); memcpy((void *)tmpData.value.string, (void *)temp, temp_length); } return tmpData; } /* q2: //underscored identifier OK if(PRINT) printf("q2 underscored identifier\n"); switch(input_char_type) { case LETTER: case DIGIT: save_temp(input_char); read_input(); goto q1; //identifier case UNDERSCORE: save_temp(input_char); read_input(); goto q2; //underscored identifier default: return_input(); return tmpData; } */ q3: //comments or divide OK if(PRINT) printf("q3 comments or divide\n"); switch(input_char_type) { case LETTER: case DIGIT: case WHITE_SPACE: return_input(); tmpData.type = DIVIDE; return tmpData; default: switch(input_char) { case '/': //q11 do { read_input(); } while(input_char != '\n' && input_char_type != END); if(input_char_type == END) { tmpData.type = END_OF_FILE; return tmpData; } read_input(); goto q0; //default state case '*': //q12 do { do { read_input(); } while(input_char != '*' && input_char_type != END); if(input_char_type == END) { throw_error(CODE_ERROR_LEX, "invalid input"); break; } read_input(); if(input_char == '/') { read_input(); goto q0; //default state } else if(input_char == '*') { return_input(); } else if(input_char_type == END) { throw_error(CODE_ERROR_LEX, "invalid input"); break; } } while(1); default: return_input(); tmpData.type = DIVIDE; return tmpData; } break; } q4: //integer or double OK if(PRINT) printf("q4 integer or double\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q4; //integer or double /* case WHITE_SPACE: save_temp(0); tmpData.value.integer = atoi((const char *)temp); return tmpData; */ case LETTER: if(input_char == 'e' || input_char == 'E') { save_temp(input_char); read_input(); tmpData.type = DOUBLE; goto q5; //double e } else { throw_error(CODE_ERROR_LEX, "invalid input"); break; } case END: /* throw_error(CODE_ERROR_LEX, "invalid input"); break; */ return_input(); save_temp(0); tmpData.value.integer = atoi((const char *)temp); return tmpData; case UNDERSCORE: throw_error(CODE_ERROR_LEX, "invalid input"); break; case OTHERS: if(input_char == '.') { save_temp(input_char); read_input(); tmpData.type = DOUBLE; goto q13; //double } return_input(); save_temp(0); tmpData.value.integer = atoi((const char *)temp); return tmpData; default: return_input(); save_temp(0); tmpData.value.integer = atoi((const char *)temp); return tmpData; } q5: //double e OK if(PRINT) printf("q5 double e\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q7; //double e case OTHERS: if(input_char == '+' || input_char == '-') { save_temp(input_char); read_input(); goto q14; //double e +- }/* else { return_input(); save_temp(0); tmpData.value.real = strtod((const char *)temp, &e_strtod); return tmpData; }*/ default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } q13: //potential double if(PRINT) printf("q13 potential double\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q6; //double default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } q14: //potential double e +- if(PRINT) printf("q14 potential double e +-\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q7; //double e +- default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } q6: //double OK if(PRINT) printf("q6 double\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q6; //double case LETTER: if(input_char == 'e' || input_char == 'E') { save_temp(input_char); read_input(); goto q5; //double e } else { throw_error(CODE_ERROR_LEX, "invalid input"); break; } /* case WHITE_SPACE: save_temp(0); tmpData.value.real = strtod((const char *)temp, &e_strtod); return tmpData; case END: throw_error(CODE_ERROR_LEX, "invalid input"); break; */ default: return_input(); save_temp(0); tmpData.value.real = strtod((const char *)temp, &e_strtod); return tmpData; } q7: //double e +- OK if(PRINT) printf("q7 double e +-\n"); switch(input_char_type) { case DIGIT: save_temp(input_char); read_input(); goto q7; //double e +- /* case WHITE_SPACE: save_temp(0); tmpData.value.real = strtod((const char *)temp, &e_strtod); return tmpData; case END: throw_error(CODE_ERROR_LEX, "invalid input"); break; */ default: return_input(); save_temp(0); tmpData.value.real = strtod((const char *)temp, &e_strtod); return tmpData; } q8: //string OK if(PRINT) printf("q8 string\n"); switch(input_char_type) { case OTHERS: if(input_char == '\\') { //save(&tmpData, input_char); read_input(); goto q9; //escaped string } else if(input_char == '"') { //q10 save(&tmpData, 0); //UZAVRENI RETEZCE NULOVYM ZNAKEM return tmpData; } save(&tmpData, input_char); read_input(); goto q8; //string case WHITE_SPACE: if(input_char == 32) { save(&tmpData, input_char); read_input(); goto q8; //string } printf("%d\n",input_char); throw_error(CODE_ERROR_LEX, "invalid input"); break; case END: throw_error(CODE_ERROR_LEX, "invalid input"); break; default: save(&tmpData, input_char); read_input(); goto q8; //string } q9: //escaped string OK if(PRINT) printf("q9 escaped string\n"); switch(input_char_type) { case END: if(PRINT) printf("vypis 1\n"); throw_error(CODE_ERROR_LEX, "invalid input"); break; default: if(PRINT) printf("vypis 2\n"); // n -> \n t -> \t /* LOMITKA DOPLNENA */ if(input_char == 'n' || input_char == 't' || input_char == '\\' || input_char == '"') { if(PRINT) printf("vypis 3\n"); // save(&tmpData, '\\'); NENMA TU BYT if(input_char == 'n') save(&tmpData, '\n'); else if (input_char == 't') save(&tmpData, '\t'); else save(&tmpData, input_char); if(PRINT) printf("vypis 5\n"); read_input(); if(PRINT) printf("vypis 6\n"); goto q8; //string if(PRINT) printf("vypis 7\n"); } else if(input_char == 'x') if(PRINT) printf("vypis 8\n"); { read_input(); if(PRINT) printf("vypis 9\n"); goto q16; } throw_error(CODE_ERROR_LEX, "invalid input"); if(PRINT) printf("\n"); break; } q16: //escaped string x tmpx = 0; switch(input_char_type) { case LETTER: if(PRINT) printf("vypis 10\n"); if(input_char >= 'A' && input_char <= 'F') { tmpx += (input_char - 'A'+10)*16; break; if(PRINT) printf("vypis 11\n"); } else if(input_char >= 'a' && input_char <= 'f') { tmpx += (input_char - 'a'+10)*16; if(PRINT) printf("vypis 12\n"); break; } throw_error(CODE_ERROR_LEX, "invalid input"); case DIGIT: tmpx += (input_char - '0')*16; //ulozit do tmp promenne ....prevod na cislo dokoncit z hexadec. na cislo //neznamekovy char, nasobeni 16 // tmp_esc_val[0] = '2'; DELETE //printf("** %i\n", tmp_esc_val); //printf("** %c\n", tmp_esc_val); //tmp_esc_val = input_char * 16; if(PRINT) printf("vypis 14\n"); break; default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } read_input(); goto q17; q17: //escaped string xH switch(input_char_type) { case LETTER: if(input_char >= 'A' && input_char <= 'F') { tmpx += (input_char - 'A'+10); break; } else if(input_char >= 'a' && input_char <= 'f') { tmpx += (input_char - 'a'+10); break; } throw_error(CODE_ERROR_LEX, "invalid input"); case DIGIT: tmpx += (input_char - '0'); break; //tmp_esc_val[1] = '1'; //const char *frmtChar = hexToInt(tmp_esc_val); //unsigned char *resChar; //sscanf(&frmtChar, "%c", &resChar); default: throw_error(CODE_ERROR_LEX, "invalid input"); break; } save(&tmpData,tmpx); read_input(); goto q8; }
void serial_test_task() { char put_ch[2]={'0','\0'}; char hint[] = USER_NAME "@" USER_NAME "-STM32:~$ "; int hint_length = sizeof(hint); char *p = NULL; size_t i = cur_his; fdout = mq_open("/tmp/mqueue/out", 0); fdin = open("/dev/tty0/in", 0); for (;; i = cur_his = (cur_his + 1) % HISTORY_COUNT) { p = cmd[cur_his]; write(fdout, hint, hint_length); while (1) { read(fdin, put_ch, 1); if (put_ch[0] == '\r' || put_ch[0] == '\n') { *p = '\0'; write(fdout, next_line, 3); break; } else if (put_ch[0] == 127 || put_ch[0] == '\b') { if (p > cmd[cur_his]) { p--; write(fdout, "\b \b", 4); } } else if (p - cmd[cur_his] < CMDBUF_SIZE - 1) { if(put_ch[0] == '\033'){ //arrow key detection read(fdin, put_ch, 1); if(put_ch[0] == '['){ read(fdin, put_ch, 1); if(put_ch[0] == 'A' || put_ch[0] == 'B'){ //up/down arrow key if(put_ch[0] == 'A'? i : i < cur_his){ //browse history while(p > cmd[cur_his]){ //delete current text p--; write(fdout, "\b \b", 4); } i += put_ch[0] == 'A'? -1 : 1; if(put_ch[0] == 'A' || i != cur_his){ write(fdout, cmd[i], strlen(cmd[i])+1); memcpy(cmd[cur_his],cmd[i], strlen(cmd[i])+1); p = cmd[cur_his]+strlen(cmd[i]); }else p = cmd[cur_his]; } }else if(put_ch[0] == 'C'){ //right arrow key }else if(put_ch[0] == 'D'){ //left arrow key }else{ *p++ = '['; *p++ = put_ch[0]; *p = '\0'; write(fdout, p-2, 3); } }else{ *p++ = put_ch[0]; write(fdout, put_ch, 2); } }else{ *p++ = put_ch[0]; write(fdout, put_ch, 2); } } } check_keyword(); } }
/** Lexikalni analyzator * * @param string slozi k navratu identifikatoru a cisel * vraci ciselnou reprezentaci tokenu */ static inline int get_token__(void) { static int c; static int state = FSM_READ; int num = 0; // buffer se musi vyprazdnit str_clean(&str); for(;;) { switch(state) { // nacitani znaku case FSM_READ: c = fgetc(input); // nekdy byva potreba nacteni znaku preskocit case FSM_START: if(isspace(c)) { state = FSM_READ; if(c == '\n') ++line; } else if(isalpha(c) || c == '_') state = FSM_IDENTIFIER; else if(isdigit(c)) state = FSM_NUMBER; else if(c == '+') { state = FSM_READ; return PLUS; } else if(c == '*') { state = FSM_READ; return MUL; } else if(c == '/') { state = FSM_READ; return DIV; } else if(c == '.') state = FSM_DOT; else if(c == '<') state = FSM_LESS; else if(c == '>') state = FSM_GREAT; else if(c == '~') state = FSM_NOT_EQUALS; else if(c == '^') { state = FSM_READ; return POWER; } else if(c == '(') { state = FSM_READ; return LBRAC; } else if(c == ')') { state = FSM_READ; return RBRAC; } else if(c == ',') { state = FSM_READ; return COMMA; } else if(c == '-') state = FSM_DASH; else if(c == '=') state = FSM_EQUALS; else if(c == '"') state = FSM_STRING; else if(c == ';') { state = FSM_READ; return SEMICOLON; } else if(c == EOF) return NOTHING; else { state = FSM_READ; return ERROR_LEX_UX_CHAR; } break; case FSM_IDENTIFIER: str_push(&str, c); c = fgetc(input); if(! (isalnum(c) || c == '_')) { state = FSM_START; return check_keyword(&str); // kontrola klicovych slov } break; case FSM_NUMBER: str_push(&str, c); c = fgetc(input); if(isdigit(c)) ; else if(c == '.') state = FSM_FLOAT0; else if(c == 'E' || c == 'e') state = FSM_EXP_E; else { state = FSM_START; return NUMBER; } break; case FSM_FLOAT0: str_push(&str, c); c = fgetc(input); if(isdigit(c)) state = FSM_FLOAT; else { state = FSM_START; return ERROR_LEX_NUMBER; } break; case FSM_FLOAT: str_push(&str, c); c = fgetc(input); if(isdigit(c)) ; else if(c == 'E' || c == 'e') state = FSM_EXP_E; else { state = FSM_START; return NUMBER; } break; case FSM_EXP_E: str_push(&str, c); c = fgetc(input); if(c == '+' || c == '-') state = FSM_EXP0; else if (isdigit(c)) state = FSM_EXP; else { state = FSM_START; return ERROR_LEX_NUMBER; } break; case FSM_EXP0: str_push(&str, c); c = fgetc(input); if(isdigit(c)) state = FSM_EXP; else { state = FSM_START; return ERROR_LEX_NUMBER; } break; case FSM_EXP: str_push(&str, c); c = fgetc(input); if(! isdigit(c)) { state = FSM_START; return NUMBER; } break; // NOTE: Zminit v dokumentaci, ze jsme zakazali primo vkladat ridici znaky ASCII do retezcu case FSM_STRING: c = fgetc(input); if(c < ASCII_CONTROLL) { state = FSM_START; return ERROR_LEX_UX_CHAR; } else if(c == '\\') state = FSM_ESCAPE; else if(c == '"') { state = FSM_READ; return STRING; } else str_push(&str, c); break; case FSM_ESCAPE: c = fgetc(input); if(c == 'n') { state = FSM_STRING; str_push(&str, '\n'); } else if(c == 't') { state = FSM_STRING; str_push(&str, '\t'); } else if(c == '\\' || c == '"') { state = FSM_STRING; str_push(&str, c); } else if(isdigit(c)) state = FSM_ESCAPE_NUM; else { state = FSM_START; return ERROR_LEX_ESC_SEC; } break; case FSM_ESCAPE_NUM: num = c - '0'; c = fgetc(input); if(isdigit(c)) { num = num * 10 + c - '0'; state = FSM_ESCAPE_NUM2; } else { state = FSM_START; return ERROR_LEX_ESC_SEC; } break; case FSM_ESCAPE_NUM2: c = fgetc(input); if(isdigit(c)) { num = num * 10 + c - '0'; if(num > 0 && num < 256) { str_push(&str, num); state = FSM_STRING; } else { state = FSM_START; return ERROR_LEX_ESC_SEC; } } else { state = FSM_START; return ERROR_LEX_ESC_SEC; } break; case FSM_DASH: c = fgetc(input); if(c == '-') state = FSM_DASH2; else { state = FSM_START; return MINUS; } break; case FSM_DASH2: c = fgetc(input); if(c == '[') state = FSM_DASH2B; else if(c == '\n') state = FSM_READ; else state = FSM_COMMENT_LINE; break; case FSM_DASH2B: c = fgetc(input); if(c == '[') state = FSM_COMMENT_BLOCK; else state = FSM_COMMENT_LINE; break; case FSM_COMMENT_LINE: c = fgetc(input); if(c == '\n') { state = FSM_READ; ++line; } else if(c == EOF) return NOTHING; break; case FSM_COMMENT_BLOCK: c = fgetc(input); if(c == ']') state = FSM_COMMENT_BLOCK_END; else if(c == '\n') ++line; else if(c == EOF) return ERROR_LEX_X_CMNT_END; break; case FSM_COMMENT_BLOCK_END: c = fgetc(input); if(c == ']') state = FSM_READ; else { state = FSM_COMMENT_BLOCK; if(c == '\n') ++line; } break; case FSM_EQUALS: c = fgetc(input); if(c == '=') { state = FSM_READ; return EQUAL; } else { state = FSM_START; return ASSIGN; } break; case FSM_DOT: c = fgetc(input); if(c == '.') { state = FSM_READ; return STRCONCAT; } else { state = FSM_START; return ERROR_LEX_UX_CHAR; } break; case FSM_LESS: c = fgetc(input); if(c == '=') { state = FSM_READ; return LESS_EQ; } else { state = FSM_START; return LESS; } break; case FSM_GREAT: c = fgetc(input); if(c == '=') { state = FSM_READ; return GREAT_EQ; } else { state = FSM_START; return GREAT; } break; case FSM_NOT_EQUALS: c = fgetc(input); if(c == '=') { state = FSM_READ; return NOT_EQUAL; } else { state = FSM_START; return ERROR_LEX_UX_CHAR; } break; #ifdef DEBUG // konecny automat by nemel vypadnout do jineho stavu default: assert(0); break; #endif } /* switch */ } /* for */ }
/* insert new node into config tree and return a pointer to it * if *tree is NULL, it will be set to point to the root node */ conf_node *add_keyword(conf_node **tree, const char *keyword, const void *data, ssize_t size) { conf_node *new_node, *cur_node; char *key, *subkey; cur_node = *tree; new_node = NULL; key = NULL; subkey = NULL; if (!keyword) { logmsg(LOG_WARN, 1, "Warning - Unable to extend configuration tree: No keyword given.\n"); return(*tree); } // check whether a prefix does already exist and if not, add it recursively if ((key = strdup(keyword)) == NULL) { logmsg(LOG_ERR, 1, "Error - Unable to allocate memory: %m.\n"); return(NULL); } /* add recursively */ if ((cur_node = check_keyword(*tree, key)) == NULL) { if ((subkey = strrchr(key, '.')) != NULL) { subkey[0] = 0; // zero-terminate first half subkey++; // pointer to second half if (isdigit(subkey[0])) { if ((cur_node = check_keyword(*tree, key)) == NULL) if ((cur_node = add_keyword(tree, key, NULL, 0)) == NULL) return(NULL); if (add_list_item(cur_node, data, size) == NULL) { fprintf(stderr, " Error - Unable to add list item for %s.\n", key); return(NULL); } return(cur_node); } if ((cur_node = add_keyword(tree, key, NULL, 0)) == NULL) return(NULL); } } else return(cur_node); // create new node and insert it into tree if ((new_node = malloc(sizeof(conf_node))) == NULL) { logmsg(LOG_ERR, 1, "Error - Unable to allocate memory: %m.\n"); free(key); return(NULL); } memset(new_node, 0, sizeof(conf_node)); // if keyword is a toplevel key, add it, else add subkey if ((new_node->keyword = strdup(subkey ? subkey : key)) == NULL) { logmsg(LOG_ERR, 1, "Error - Unable to allocate memory: %m.\n"); free(key); return(NULL); } free(key); if (size) { if (add_list_item(new_node, data, size) == NULL) { fprintf(stderr, " Error - Unable to add list item for %s.\n", keyword); return(NULL); } } /* insert new node into tree */ if (cur_node) { /* it's an internal node */ if (cur_node->first_leaf) { cur_node = cur_node->first_leaf; while (cur_node->next) cur_node = cur_node->next; cur_node->next = new_node; } else cur_node->first_leaf = new_node; } else { /* it's a top level node */ if (!(*tree)) (*tree) = new_node; /* it's a root's neighbor */ else { cur_node = *tree; while (cur_node->next) cur_node = cur_node->next; cur_node->next = new_node; } } if (*tree == NULL) *tree = cur_node; return(new_node); }
/* return first leaf node of subtree for given keyword */ conf_node *conf_subtree(conf_node *tree, const char *keyword) { conf_node *subtree; if ((subtree = check_keyword(tree, keyword)) == NULL) return(NULL); return(subtree->first_leaf); }