void scan_file(char *filename) { FILE *fp = fopen(filename, "r"); if (!fp) { printf("Can't open input file %s!\n", filename); exit(1); } int current_line = 0; int more_lines = true; while (more_lines) { int line_len = get_current_line_length(fp); { char *buf = malloc(line_len); char *starting_buf = buf; more_lines = read_line(fp, buf); current_line++; while (1) { Token *token = scan_string(&buf); if (!token) { break; } if (token->type == INVALID) { printf("Error: Unrecognized token '%s' in %s (row %i, col %i)\n", token->text, filename, current_line, (int)(buf - starting_buf)); exit(1); } token_print(*token); token_free(token); } free(buf - line_len); } } }
void TranslateLinksAndPrint(char* s) { static const char *href = "href='?in="; char *e, *tmp; while (1) { e = strstr(s, href); if (e == NULL) break; tmp = strndup(s, e - s); printf("%shref='#", tmp); free(tmp); e += strlen(href); s = strstr(e, "'>"); if (s == NULL) return; // should not happen tmp = strndup(e, s - e); // workaround bison bug if (tmp[strlen(tmp) - 1] == ';') { tmp[strlen(tmp) - 1] = 0; } scan_string(tmp); yyparse(); free_scan_string(); free(tmp); } printf("%s", s); }
/* Scan /proc/devices for a blockdevice (BLOCKDEV is 1) or a character * device (BLOCKDEV is 0) with a major number matching the major number of DEV. * When there is a match, store entry data in ENTRY and return 0. Return * non-zero otherwise. */ int proc_dev_get_entry(dev_t device, int blockdev, struct proc_dev_entry* entry) { struct file_buffer file; int rc; int scan_blockdev = 0; rc = get_file_buffer(&file, proc_dev_filename); if (rc) return rc; rc = -1; while (!eof(&file)) { if (scan_string(&file, "Block") == 0) { skip_line(&file); scan_blockdev = 1; continue; } else if (scan_dev_entry(&file, entry, scan_blockdev) == 0) { if ((major(entry->device) == major(device)) && blockdev == scan_blockdev) { rc = 0; break; } proc_dev_free_entry(entry); } else skip_line(&file); } free_file_buffer(&file); return rc; }
/****************************************************************** scan() See prlex.h for return values other than characters (i.e. > 256) *******************************************************************/ int scan() { ini_scan(); getachar(); if(Ch == EOF) return(EOF); switch(Ctype[Ch]) { case DI: MY_ASSERT(isdigit(Ch)); /* double check */ case SI: MY_ASSERT(isdigit(Ch) || Ch == '-' || Ch == '+'); return(scan_number(Ch)); case QU: MY_ASSERT(Ch == '"'); scan_string(); return(TOKEN_STRING); case BR: MY_ASSERT(Ch == ')' || Ch == '('); return(Ch); #ifdef CLIPS_SYNTAX case QE: scan_identifier(?); return(TOKEN_VAR); case AL: case AU: case OT: scan_identifier(Ch); return(TOKEN_ATOM); #else case AL: MY_ASSERT(islower(Ch)); scan_identifier(Ch); return(TOKEN_ATOM); case US: MY_ASSERT(Ch == '_'); case AU: scan_identifier(Ch); return(TOKEN_VAR); #endif case CC: return(SCAN_ERR); #ifdef CHARACTER case AP: return(scan_character()); #endif default: return(Ch); } }
static PyObject * Scan_str(Scan *self) { char scanstr[100]; scan_string(self->scan, scanstr); char str[200]; sprintf(str, "Scan: %s", scanstr); return PyUnicode_FromString(str); }
void Parser::scan_value(void) { int c = read_byte(); switch (c) { case trace::TYPE_NULL: case trace::TYPE_FALSE: case trace::TYPE_TRUE: break; case trace::TYPE_SINT: scan_sint(); break; case trace::TYPE_UINT: scan_uint(); break; case trace::TYPE_FLOAT: scan_float(); break; case trace::TYPE_DOUBLE: scan_double(); break; case trace::TYPE_STRING: scan_string(); break; case trace::TYPE_ENUM: scan_enum(); break; case trace::TYPE_BITMASK: scan_bitmask(); break; case trace::TYPE_ARRAY: scan_array(); break; case trace::TYPE_STRUCT: scan_struct(); break; case trace::TYPE_BLOB: scan_blob(); break; case trace::TYPE_OPAQUE: scan_opaque(); break; case trace::TYPE_REPR: scan_repr(); break; case trace::TYPE_WSTRING: scan_wstring(); break; default: std::cerr << "error: unknown type " << c << "\n"; exit(1); case -1: break; } }
//input employee details from stdin void get_emp_details(EMP_T **pp_to_e, int n) { int i; assert(pp_to_e); for(i = 0; i < n; i++) { assert((*(pp_to_e + i))); assert((*(pp_to_e + i))->name); printf("\nEnter emp name: "); scan_string((*(pp_to_e + i))->name); printf("Enter emp id: "); scanf("%d",&(*(pp_to_e + i))->id); } }
void Scanner::scan() { char token = file.get(); while (token != EOF && error == -1) { switch (token) { case ',': scan_punctuation(token, Token::COMMA); break; case '.': scan_punctuation(token, Token::PERIOD); break; case '?': scan_punctuation(token, Token::Q_MARK); break; case '(': scan_punctuation(token, Token::LEFT_PAREN); break; case ')': scan_punctuation(token, Token::RIGHT_PAREN); break; case ':': scan_colon(); break; case '#': scan_comment(); break; case '\'': scan_string(); break; case '\n': line++; break; default: scan_id(token); break; } token = file.get(); } if (error == -1) { line++; add_token("", Token::END); } }
void scan_sty() { char spec[STRING_MAX]; int tmp; MESSAGE("Scanning style file %s", sty_fn); while (scan_spec(spec)) { sty_tc++; put_dot = TRUE; /* output pre- and post-ambles */ if (STREQ(spec, PREAMBLE)) { (void)scan_string(preamble); prelen = count_lfd(preamble); } else if (STREQ(spec, POSTAMBLE)) { (void)scan_string(postamble); postlen = count_lfd(postamble); } else if (STREQ(spec, GROUP_SKIP)) { (void)scan_string(group_skip); skiplen = count_lfd(group_skip); } else if (STREQ(spec, LETHEAD_PRE)) { (void)scan_string(lethead_pre); headprelen = count_lfd(lethead_pre); } else if (STREQ(spec, LETHEAD_SUF)) { (void)scan_string(lethead_suf); headsuflen = count_lfd(lethead_suf); } else if (STREQ(spec, LETHEAD_FLAG)) { SCAN_NO(&lethead_flag); } else if (STREQ(spec, SETPAGEOPEN)) { (void)scan_string(setpage_open); setpagelen = count_lfd(setpage_open); } else if (STREQ(spec, SETPAGECLOSE)) { (void)scan_string(setpage_close); setpagelen = count_lfd(setpage_close); /* output index item commands */ } else if (STREQ(spec, ITEM_0)) { (void)scan_string(item_r[0]); ilen_r[0] = count_lfd(item_r[0]); } else if (STREQ(spec, ITEM_1)) { (void)scan_string(item_r[1]); ilen_r[1] = count_lfd(item_r[1]); } else if (STREQ(spec, ITEM_2)) { (void)scan_string(item_r[2]); ilen_r[2] = count_lfd(item_r[2]); } else if (STREQ(spec, ITEM_01)) { (void)scan_string(item_u[1]); ilen_u[1] = count_lfd(item_u[1]); } else if (STREQ(spec, ITEM_12)) { (void)scan_string(item_u[2]); ilen_u[2] = count_lfd(item_u[2]); } else if (STREQ(spec, ITEM_x1)) { (void)scan_string(item_x[1]); ilen_x[1] = count_lfd(item_x[1]); } else if (STREQ(spec, ITEM_x2)) { (void)scan_string(item_x[2]); ilen_x[2] = count_lfd(item_x[2]); /* output encapsulators */ } else if (STREQ(spec, ENCAP_0)) (void)scan_string(encap_p); else if (STREQ(spec, ENCAP_1)) (void)scan_string(encap_i); else if (STREQ(spec, ENCAP_2)) (void)scan_string(encap_s); /* output delimiters */ else if (STREQ(spec, DELIM_0)) (void)scan_string(delim_p[0]); else if (STREQ(spec, DELIM_1)) (void)scan_string(delim_p[1]); else if (STREQ(spec, DELIM_2)) (void)scan_string(delim_p[2]); else if (STREQ(spec, DELIM_N)) (void)scan_string(delim_n); else if (STREQ(spec, DELIM_R)) (void)scan_string(delim_r); /* output line width */ else if (STREQ(spec, LINEMAX)) { SCAN_NO(&tmp); if (tmp > 0) linemax = tmp; else STY_ERROR2("%s must be positive (got %d)", LINE_MAX, tmp); /* output line indentation length*/ } else if (STREQ(spec, INDENT_LENGTH)) { SCAN_NO(&tmp); if (tmp >= 0) indent_length = tmp; else STY_ERROR2("%s must be nonnegative (got %d)", INDENT_LENGTH, tmp); /* output line indentation*/ } else if (STREQ(spec, INDENT_SPACE)) { (void)scan_string(indent_space); /* composite page delimiter */ } else if (STREQ(spec, COMPOSITOR)) { (void)scan_string(page_comp); /* page precedence */ } else if (STREQ(spec, PRECEDENCE)) { (void)scan_string(page_prec); (void)process_precedence(); /* index input format */ } else if (STREQ(spec, KEYWORD)) (void)scan_string(idx_keyword); else if (STREQ(spec, AOPEN)) (void)scan_char(&idx_aopen); else if (STREQ(spec, ACLOSE)) (void)scan_char(&idx_aclose); else if (STREQ(spec, LEVEL)) (void)scan_char(&idx_level); else if (STREQ(spec, ROPEN)) (void)scan_char(&idx_ropen); else if (STREQ(spec, RCLOSE)) (void)scan_char(&idx_rclose); else if (STREQ(spec, QUOTE)) (void)scan_char(&idx_quote); else if (STREQ(spec, ACTUAL)) (void)scan_char(&idx_actual); else if (STREQ(spec, ENCAP)) (void)scan_char(&idx_encap); else if (STREQ(spec, ESCAPE)) (void)scan_char(&idx_escape); else { (void)next_nonblank(); STY_SKIPLINE; STY_ERROR("Unknown specifier %s.\n", spec); put_dot = FALSE; } if (put_dot) { STY_DOT; } } /* check if quote and escape are distinct */ if (idx_quote == idx_escape) { STY_ERROR("Quote and escape symbols must be distinct (both `%c' now).\n", idx_quote); idx_quote = IDX_QUOTE; idx_escape = IDX_ESCAPE; } DONE(sty_tc - sty_ec, "attributes redefined", sty_ec, "ignored"); CLOSE(sty_fp); }
int main() { int d,m,y; char query[1024]; char *env; char *coord=NULL; char *search=NULL; char buf[1024]; char *tmp; time_t t; struct tm *tt; time(&t); tt = localtime(&t); d = tt->tm_mday; m = tt->tm_mon+1; y = tt->tm_year+1900; env = getenv("QUERY_STRING"); if (env) { char *s; s = strstr(env, "d="); if (s) sscanf(s, "d=%d", &d); s = strstr(env, "m="); if (s) sscanf(s, "m=%d", &m); s = strstr(env, "y="); if (s) sscanf(s, "y=%d", &y); s = strstr(env, "c="); if (s) s+=2; else { // spatna kompatibilita so znackami s = strstr(env, "in="); if (s) s+=3; } if (s) { query[0]=0; sscanf(s, "%1000[^&]", query); coord=StringDecode(query); } s = strstr(env, "search="); if (s) { query[0]=0; sscanf(s+7, "%1000[^&]", query); search = StringDecode(query); } } if (db_init()<0) return 1; printf("Content-Type: text/html; charset=UTF-8\n\n"); printf("<html><head>\n" "<link rel=\"stylesheet\" href=\"breviar.css\">\n"); Rst(&kontext); kontext_last_hb=kontext_last_he=-1; first.h=last.h=-1; if (coord) { printf("<title>%s</title>\n" "</head><body>\n" "<div class=\"nadpis\">%s</div>\n\n", coord, coord); kalendar = 0; scan_string(coord); yyparse(); printf("<p>\n" "<form action=\"pismo.cgi\" method=\"get\">\n" "<input type=\"text\" name=\"c\">\n" "<input type=\"submit\" value=\"Zobraz\">\n" "</form>\n"); { char *tmp = StringEncode(kontext.buf+1); printf(// "<p>\n" "<a href=\"pismo.cgi?c=%s\">Kontext</a>", tmp); free(tmp); } printf(" "); if (first.h!=-1) { char *b; int h; get_prev(first.k, first.h, &b, &h); if (b!=NULL) { snprintf(buf, sizeof(buf), "%s %d", b, h); tmp = StringEncode(buf); printf(// "<p>\n" "<a href=\"pismo.cgi?c=%s\">Dozadu (%s %d)</a>", tmp, b, h); free(tmp); free(b); } } printf(" "); if (last.h!=-1){ char *b; int h; get_next(last.k, last.h, &b, &h); if (b!=NULL) { snprintf(buf, sizeof(buf), "%s %d", b, h); tmp = StringEncode(buf); printf(// "<p>\n" "<a href=\"pismo.cgi?c=%s\">Dopredu (%s %d)</a>", tmp, b, h); free(tmp); free(b); } } printf("<p>\n" "<form action=\"pismo.cgi\" method=\"get\">\n" "<input type=\"text\" name=\"search\">\n" "<input type=\"submit\" value=\"Hľadaj\">\n" "</form>\n"); } else if (search) { char *b,*t; int h,v; printf("<title>Vyhľadávanie \"%s\"</title>\n" "</head><body>\n" "<div class=\"nadpis\">Vyhľadávanie \"%s\"</div>\n\n", search, search); fulltext_search(search); while (get_fulltext_result(&b, &h, &v, &t)) { int i,in,var; snprintf(buf, sizeof(buf), "%s%d", b,h); tmp = StringEncode(buf); printf("\n<p> <a href=\"pismo.cgi?c=%s\">%s%d", tmp, b, h); if (v!=-1) printf(",%d", v); printf("</a>: "); free(tmp); for (i=in=var=0; t[i]; i++) { if (t[i]=='<') { in = 1; if (!strncmp(t+i+1, "var>", 4)) var = 1; if (!strncmp(t+i+1, "/var>", 5)) var = 0; } if (!in && !var) printf("%c", t[i]); if (t[i]=='>') in = 0; } } printf("<p>\n" "<form action=\"pismo.cgi\" method=\"get\">\n" "<input type=\"text\" name=\"c\">\n" "<input type=\"submit\" value=\"Zobraz\">\n" "</form>\n"); printf("<p>\n" "<form action=\"pismo.cgi\" method=\"get\">\n" "<input type=\"text\" name=\"search\">\n" "<input type=\"submit\" value=\"Hľadaj\">\n" "</form>\n"); free_fulltext_search(); } else { char *ct; if (!get_citania(y,m,d, &zalm, &ct)) return 3; kalendar = 1; // printf("%s %s %s %s\n", row[0], row[1], row[2], row[3]); printf("<title>Čítania na %d.%d.%d</title>\n" "</head><body>\n" "<div class=\"nadpis\">Liturgické čítania na %d.%d.%d</div>\n\n", d,m,y,d,m,y); scan_string(ct); yyparse(); /* toto asi nechceme { char *tmp = StringEncode(kontext.buf+1); printf("<p>\n" "<a href=\"pismo.cgi?c=%s\">Kontext</a>", tmp); free(tmp); } */ free(zalm); free(ct); } printf("</body></html>\n"); free_scan_string(); db_close(); return 0; }
int yylex(void) { int status; #ifdef DEBUG printf("yylex is called\n" " first_line: %d\n" " first_column: %d\n" " last_line: %d\n" " last_column: %d\n", yylloc.first_line, yylloc.first_column, yylloc.last_line, yylloc.last_column); #endif skip_white_space: while(*src == ' ' || *src == '\t') { ++yylloc.last_column; ++src; } /* skip comments */ if(*src == ';') { while(*src != '\n' && *src != 0) { ++yylloc.last_column; ++src; } } /* when a newline appears, update yylloc accordingly and start to skip whitespace again */ if(*src == '\n') { ++yylloc.last_line; yylloc.last_column = 1; ++src; goto skip_white_space; } yylloc.first_line = yylloc.last_line; yylloc.first_column = yylloc.last_column; status = scan_multibyte_operator(); if(status != 0) return status; status = scan_int(); if(status != 0) return status; status = scan_string(); if(status != 0) return status; status = scan_special_identifier(); if(status != 0) return status; status = scan_identifier(); if(status != 0) return status; /* Return a single char or, when end of string, 0 */ ++yylloc.last_column; #ifdef DEBUG if(*src == 0) printf("yylex returns EOF\n"); else printf("yylex returns '%c'\n", *src); #endif return *src++; }
int scan(scan_info *info) { int err = 0; int sym_code = SVO_NONE; const char **in = &(info->scanner); char tmp[SCAN_SIZE+1]; while((**in != 0) && (isspace(**in))) (*in)++; if(isalpha(**in)){ scan_ident(in,info->token,SCAN_SIZE); sym_code = token_to_id(info->token); if(sym_code == SVO_NONE) sym_code = SVO_IDENT; } else if(isdigit(**in)){ scan_number(in,info->token,SCAN_SIZE); sym_code = SVO_NUMBER; } else{ switch(**in){ case '#': sym_code = SVO_END; break; case '>': case '<': case '=': case '!': scan_comp(in,info->token,SCAN_SIZE); break; case '"': err = scan_string(info,SCAN_SIZE); if(err != SHE_NO_ERROR){ parse_vars_in_string(info->token,tmp,SCAN_SIZE); strncpy(info->token,tmp,SCAN_SIZE); info->token[SCAN_SIZE] = 0; } sym_code = SVO_DQ_STRING; break; case '\'': sym_code = SVO_SQ_STRING; err =scan_string(info,SCAN_SIZE); break; case 0: *(info->token) = 0; sym_code = SVO_END; break; default: info->token[0] = **in; info->token[1] = 0; (*in)++; break; } if(sym_code == SVO_NONE) sym_code = token_to_id(info->token); } info->sym_code = sym_code; return err; }
int luna_scan(luna_lexer_t *self) { int c; token(ILLEGAL); // deferred outdents if (self->outdents) return outdent(self); // scan scan: switch (c = next) { case ' ': case '\t': goto scan; case '(': return token(LPAREN); case ')': return token(RPAREN); case '{': return token(LBRACE); case '}': return token(RBRACE); case '[': return token(LBRACK); case ']': return token(RBRACK); case ',': return token(COMMA); case '.': return token(OP_DOT); case '%': return token(OP_MOD); case '^': return token(OP_BIT_XOR); case '~': return token(OP_BIT_NOT); case '?': return token(QMARK); case ':': return token(COLON); case '@': self->tok.value.as_string = "self"; return token(ID); case '+': switch (next) { case '+': return token(OP_INCR); case '=': return token(OP_PLUS_ASSIGN); default: return undo, token(OP_PLUS); } case '-': switch (next) { case '-': return token(OP_DECR); case '=': return token(OP_MINUS_ASSIGN); default: return undo, token(OP_MINUS); } case '*': switch (next) { case '=': return token(OP_MUL_ASSIGN); case '*': return token(OP_POW); default: return undo, token(OP_MUL); } case '/': return '=' == next ? token(OP_DIV_ASSIGN) : (undo, token(OP_DIV)); case '!': return '=' == next ? token(OP_NEQ) : (undo, token(OP_NOT)); case '=': return '=' == next ? token(OP_EQ) : (undo, token(OP_ASSIGN)); case '&': switch (next) { case '&': return '=' == next ? token(OP_AND_ASSIGN) : (undo, token(OP_AND)); default: return undo, token(OP_BIT_AND); } case '|': switch (next) { case '|': return '=' == next ? token(OP_OR_ASSIGN) : (undo, token(OP_OR)); default: return undo, token(OP_BIT_OR); } case '<': switch (next) { case '=': return token(OP_LTE); case '<': return token(OP_BIT_SHL); default: return undo, token(OP_LT); } case '>': switch (next) { case '=': return token(OP_GTE); case '>': return token(OP_BIT_SHR); default: return undo, token(OP_GT); } case '#': while ((c = next) != '\n' && c) ; undo; goto scan; case '\n': return scan_newline(self); case '"': case '\'': return scan_string(self, c); case 0: if (self->indents) { --self->indents; return token(OUTDENT); } token(EOS); return 0; default: if (isalpha(c) || '_' == c) return scan_ident(self, c); if (isdigit(c) || '.' == c) return scan_number(self, c); error("illegal character"); return 0; } }
bool tokz_get_token(Tokenizer *tokz, Token *tok) { int c, c2, e; if (!(tokz->flags&TOKZ_READ_FROM_BUFFER)) assert(tokz->file!=NULL); tok_free(tok); if(!TOK_IS_INVALID(&(tokz->ungettok))){ *tok=tokz->ungettok; tokz->ungettok.type=TOK_INVALID; return TRUE; } while(1){ e=0; do{ c=GETCH(); }while(c!='\n' && c!=EOF && isspace(c)); tok->line=tokz->line; switch(c){ case EOF: TOK_SET_OP(tok, OP_EOF); return TRUE; case '\n': INC_LINE(); if(tokz->flags&TOKZ_IGNORE_NEXTLINE) continue; TOK_SET_OP(tok, OP_NEXTLINE); return TRUE; case '\\': do{ c=GETCH(); if(c==EOF){ TOK_SET_OP(tok, OP_EOF); return FALSE; } if(!isspace(c) && e==0){ e=E_TOKZ_EOL_EXPECTED; tokz_warn_error(tokz, tokz->line, e); if(!(tokz->flags&TOKZ_ERROR_TOLERANT)) return FALSE; } }while(c!='\n'); INC_LINE(); continue; case '#': if(tokz->flags&TOKZ_READ_COMMENTS){ e=scan_line_comment(tok, tokz); break; }else if((e=skip_line_comment(tokz))){ break; } continue; case '/': c2=GETCH(); if(c2=='='){ TOK_SET_OP(tok, OP_AS_DIV); return TRUE; } if(c2!='*'){ UNGETCH(c2); TOK_SET_OP(tok, OP_DIV); return TRUE; } if(tokz->flags&TOKZ_READ_COMMENTS){ e=scan_c_comment(tok, tokz); break; }else if((e=skip_c_comment(tokz))){ break; } continue; case '\"': e=scan_string(tok, tokz, TRUE); break; case '\'': e=scan_char(tok, tokz); break; default: if(('0'<=c && c<='9') || c=='-' || c=='+'){ e=scan_number(tok, tokz, c); break; } if(START_IDENT(c)) e=scan_identifier(tok, tokz, c); else e=scan_op(tok, tokz, c); } if(!e) return TRUE; tokz_warn_error(tokz, tokz->line, e); return FALSE; } }
StackFrame * Parser::parse_backtrace_frame(Mode mode) { size_t id = read_uint(); StackFrameState *frame = lookup(frames, id); if (!frame) { frame = new StackFrameState; int c = read_byte(); while (c != trace::BACKTRACE_END && c != -1) { switch (c) { case trace::BACKTRACE_MODULE: frame->module = read_string(); break; case trace::BACKTRACE_FUNCTION: frame->function = read_string(); break; case trace::BACKTRACE_FILENAME: frame->filename = read_string(); break; case trace::BACKTRACE_LINENUMBER: frame->linenumber = read_uint(); break; case trace::BACKTRACE_OFFSET: frame->offset = read_uint(); break; default: std::cerr << "error: unknown backtrace detail " << c << "\n"; exit(1); } c = read_byte(); } frame->fileOffset = file->currentOffset(); frames[id] = frame; } else if (file->currentOffset() < frame->fileOffset) { int c = read_byte(); while (c != trace::BACKTRACE_END && c != -1) { switch (c) { case trace::BACKTRACE_MODULE: scan_string(); break; case trace::BACKTRACE_FUNCTION: scan_string(); break; case trace::BACKTRACE_FILENAME: scan_string(); break; case trace::BACKTRACE_LINENUMBER: scan_uint(); break; case trace::BACKTRACE_OFFSET: scan_uint(); break; default: std::cerr << "error: unknown backtrace detail " << c << "\n"; exit(1); } c = read_byte(); } } return frame; }
struct skin_element* skin_parse(const char* document, skin_callback cb, void* cb_data) { callback = cb; callback_data = cb_data; #else struct skin_element* skin_parse(const char* document) { #endif struct skin_element* root = NULL; struct skin_element* last = NULL; const char* cursor = document; /*Keeps track of location in the document*/ skin_line = 1; skin_start = (char*)document; viewport_line = 0; skin_clear_errors(); while(*cursor != '\0') { struct skin_element* tree = skin_parse_viewport(&cursor); if(!root) { root = tree; last = root; } else { last->next = skin_buffer_to_offset(tree); last = tree; } if(!last) { skin_free_tree(root); /* Clearing any memory already used */ return NULL; } /* Making sure last is at the end */ while(IS_VALID_OFFSET(last->next)) last = skin_buffer_from_offset(last->next); } return root; } static struct skin_element* skin_parse_viewport(const char** document) { struct skin_element* root = NULL; struct skin_element* last = NULL; struct skin_element* retval = NULL; retval = skin_alloc_element(); if (!retval) return NULL; retval->type = VIEWPORT; retval->children_count = 1; retval->line = skin_line; viewport_line = skin_line; OFFSETTYPE(struct skin_element*)* children; const char* cursor = *document; /* Keeps track of location in the document */ const char* bookmark; /* Used when we need to look ahead */ int sublines = 0; /* Flag for parsing sublines */ /* Parsing out the viewport tag if there is one */ if(check_viewport(cursor)) { if (!skin_parse_tag(retval, &cursor)) return NULL; if(*cursor == '\n') { cursor++; skin_line++; } } #ifdef ROCKBOX else if (callback) { if (callback(retval, callback_data) == CALLBACK_ERROR) { skin_error(GOT_CALLBACK_ERROR, cursor); return NULL; } } #endif if (check_viewport(cursor)) { retval->children_count = 0; *document = cursor; return retval; } retval->children_count = 1; children = skin_alloc_children(1); if (!children) return NULL; do { /* First, we check to see if this line will contain sublines */ bookmark = cursor; sublines = 0; while(*cursor != '\n' && *cursor != '\0' && !(check_viewport(cursor) && cursor != *document)) { if(*cursor == MULTILINESYM) { sublines = 1; break; } else if(*cursor == TAGSYM) { skip_tag(&cursor); } else if(*cursor == COMMENTSYM) { skip_comment(&cursor); } else { /* Advancing the cursor as normal */ cursor++; } } cursor = bookmark; if(sublines) { struct skin_element* out = skin_parse_sublines(&cursor); if (!root) { root = out; last = root; } else { last->next = skin_buffer_to_offset(out); last = out; } if(!last) return NULL; } else { #ifdef ROCKBOX /* strip all leading comments */ while(*cursor == '#') { skip_comment(&cursor); skin_line++; } if (check_viewport(cursor)) break; #endif struct skin_element* out = skin_parse_line(&cursor); if (!root) { root = out; last = root; } else { last->next = skin_buffer_to_offset(out); last = out; } if(!last) return NULL; } /* Making sure last is at the end */ while(IS_VALID_OFFSET(last->next)) last = skin_buffer_from_offset(last->next); if(*cursor == '\n') { cursor++; skin_line++; } #ifdef ROCKBOX /* strip all comments */ while(*cursor == '#') { skip_comment(&cursor); skin_line++; } if (check_viewport(cursor)) break; #endif } while(*cursor != '\0' && !(check_viewport(cursor) && cursor != *document)); *document = cursor; children[0] = skin_buffer_to_offset(root); retval->children = skin_buffer_to_offset(children); return retval; } /* Auxiliary Parsing Functions */ static struct skin_element* skin_parse_line(const char**document) { return skin_parse_line_optional(document, 0); } /* * If conditional is set to true, then this will break upon encountering * SEPARATESYM. This should only be used when parsing a line inside a * conditional, otherwise just use the wrapper function skin_parse_line() */ static struct skin_element* skin_parse_line_optional(const char** document, int conditional) { const char* cursor = *document; struct skin_element* root = NULL; struct skin_element* current = NULL; struct skin_element* retval = NULL; OFFSETTYPE(struct skin_element*)* children = NULL; /* A wrapper for the line */ retval = skin_alloc_element(); if (!retval) return NULL; retval->type = LINE; retval->line = skin_line; while (*cursor == '\t') cursor++; if(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM && !(conditional && (*cursor == ARGLISTSEPARATESYM || *cursor == ARGLISTCLOSESYM || *cursor == ENUMLISTSEPARATESYM || *cursor == ENUMLISTCLOSESYM))) { retval->children_count = 1; } else { retval->children_count = 0; } if(retval->children_count > 0) { children = skin_alloc_children(1); if (!children) return NULL; } #ifdef ROCKBOX if (callback) { switch (callback(retval, callback_data)) { case CALLBACK_ERROR: skin_error(GOT_CALLBACK_ERROR, cursor); return NULL; default: break; } } #endif while(*cursor != '\n' && *cursor != '\0' && *cursor != MULTILINESYM && !((*cursor == ARGLISTSEPARATESYM || *cursor == ARGLISTCLOSESYM || *cursor == ENUMLISTSEPARATESYM || *cursor == ENUMLISTCLOSESYM) && conditional) && !(check_viewport(cursor) && cursor != *document)) { /* Allocating memory if necessary */ if(root) { struct skin_element *next = skin_alloc_element(); if (!next) return NULL; current->next = skin_buffer_to_offset(next); current = next; } else { current = skin_alloc_element(); if (!current) return NULL; root = current; } /* Parsing the current element */ if(*cursor == TAGSYM && cursor[1] == CONDITIONSYM) { if(!skin_parse_conditional(current, &cursor)) return NULL; } else if(*cursor == TAGSYM && !find_escape_character(cursor[1])) { if(!skin_parse_tag(current, &cursor)) return NULL; } else if(*cursor == COMMENTSYM) { if(!skin_parse_comment(current, &cursor)) return NULL; } else { if(!skin_parse_text(current, &cursor, conditional)) return NULL; } } /* Moving up the calling function's pointer */ *document = cursor; if(root) { children[0] = skin_buffer_to_offset(root); retval->children = skin_buffer_to_offset(children); } return retval; } static struct skin_element* skin_parse_sublines(const char** document) { return skin_parse_sublines_optional(document, 0); } static struct skin_element* skin_parse_sublines_optional(const char** document, int conditional) { struct skin_element* retval; OFFSETTYPE(struct skin_element*)* children; const char* cursor = *document; int sublines = 1; int i; retval = skin_alloc_element(); if (!retval) return NULL; retval->type = LINE_ALTERNATOR; retval->next = skin_buffer_to_offset(NULL); retval->line = skin_line; while (*cursor == '\t') cursor++; /* First we count the sublines */ while(*cursor != '\0' && *cursor != '\n' && !((*cursor == ARGLISTSEPARATESYM || *cursor == ARGLISTCLOSESYM || *cursor == ENUMLISTSEPARATESYM || *cursor == ENUMLISTCLOSESYM) && conditional) && !(check_viewport(cursor) && cursor != *document)) { if(*cursor == COMMENTSYM) { skip_comment(&cursor); } else if(*cursor == TAGSYM) { skip_tag(&cursor); } else if(*cursor == MULTILINESYM) { sublines++; cursor++; } else { cursor++; } } /* ...and then we parse them */ retval->children_count = sublines; children = skin_alloc_children(sublines); if (!children) return NULL; cursor = *document; for(i = 0; i < sublines; i++) { children[i] = skin_buffer_to_offset(skin_parse_line_optional(&cursor, conditional)); if (children[i] < 0) return NULL; skip_whitespace(&cursor); if(*cursor != MULTILINESYM && i != sublines - 1) { skin_error(MULTILINE_EXPECTED, cursor); return NULL; } else if(i != sublines - 1) { cursor++; } } #ifdef ROCKBOX if (callback) { if (callback(retval, callback_data) == CALLBACK_ERROR) { skin_error(GOT_CALLBACK_ERROR, *document); return NULL; } } #endif *document = cursor; retval->children = skin_buffer_to_offset(children); return retval; } static int skin_parse_tag(struct skin_element* element, const char** document) { const char* cursor = *document + 1; const char* bookmark; char *open_square_bracket = NULL; char tag_name[MAX_TAG_LENGTH]; char* tag_args; const struct tag_info *tag; struct skin_tag_parameter* params = NULL; int num_args = 1; int i; int qmark = 0; /* Flag for the all-or-none option */ int optional = 0; /* Checking the tag name */ for (i=0; cursor[i] && i<MAX_TAG_LENGTH; i++) tag_name[i] = cursor[i]; /* First we check the two characters after the '%', then a single char */ tag = NULL; i = MAX_TAG_LENGTH; while (!tag && i > 1) { tag_name[i-1] = '\0'; tag = find_tag(tag_name); i--; } if(!tag) { skin_error(ILLEGAL_TAG, cursor); return 0; } cursor += i; /* Copying basic tag info */ if(element->type != CONDITIONAL && element->type != VIEWPORT) element->type = TAG; element->tag = tag; tag_args = tag->params; element->line = skin_line; /* Checking for the * flag */ if(tag_args[0] == '?') { qmark = 1; tag_args++; } /* If this tag has no arguments, we can bail out now */ if(strlen(tag_args) == 0 || (tag_args[0] == '|' && *cursor != ARGLISTOPENSYM) || (qmark && *cursor != ARGLISTOPENSYM)) { #ifdef ROCKBOX if (callback) { if (callback(element, callback_data) == CALLBACK_ERROR) { skin_error(GOT_CALLBACK_ERROR, cursor); return 0; } } #endif *document = cursor; return 1; } /* Checking the number of arguments and allocating args */ if(*cursor != ARGLISTOPENSYM && tag_args[0] != '|') { skin_error(ARGLIST_EXPECTED, cursor); return 0; } else { cursor++; } bookmark = cursor; while(*cursor != '\n' && *cursor != '\0' && *cursor != ARGLISTCLOSESYM) { /* Skipping over escaped characters */ if(*cursor == TAGSYM && *(cursor+1) != ARGLISTSEPARATESYM) { skip_tag(&cursor); } else if(*cursor == COMMENTSYM) { skip_comment(&cursor); } else if(*cursor == ARGLISTSEPARATESYM) { num_args++; cursor++; } else { cursor++; } } cursor = bookmark; /* Restoring the cursor */ element->params_count = num_args; params = skin_alloc_params(num_args); if (!params) return 0; /* Now we have to actually parse each argument */ for(i = 0; i < num_args; i++) { char type_code; /* Making sure we haven't run out of arguments */ if(*tag_args == '\0') { skin_error(TOO_MANY_ARGS, cursor); return 0; } /* Checking for the optional bar */ if(*tag_args == '|') { optional = 1; tag_args++; } /* Scanning the arguments */ skip_whitespace(&cursor); /* Checking for comments */ if(*cursor == COMMENTSYM) skip_comment(&cursor); if (*tag_args == '[') { /* we need to guess which type of param it is. * guess using this priority: * default > decimal/integer > single tag/code > string */ int j=0; bool canbedefault = false, last_char_is_percent = false; bool haspercent = false, number = true, hasdecimal = false; char temp_params[8]; open_square_bracket = tag_args; tag_args++; while (*tag_args != ']') { if (*tag_args >= 'a' && *tag_args <= 'z') canbedefault = true; temp_params[j++] = tolower(*tag_args++); } temp_params[j] = '\0'; j = 0; while (cursor[j] && cursor[j] != ',' && cursor[j] != ')') { haspercent = haspercent || (cursor[j] == '%'); hasdecimal = hasdecimal || (cursor[j] == '.'); number = number && (isdigit(cursor[j]) || (cursor[j] == '.') || (cursor[j] == '-') || (cursor[j] == '%')); j++; } last_char_is_percent = cursor[j-1] == '%'; type_code = '?'; if (canbedefault && *cursor == DEFAULTSYM && !isdigit(cursor[1])) { type_code = 'i'; } else if (number && hasdecimal && strchr(temp_params, 'd')) { type_code = 'd'; } else if (number && last_char_is_percent && strchr(temp_params, 'p')) { type_code = 'p'; } else if (number && (strchr(temp_params, 'i') || strchr(temp_params, 'd'))) { type_code = strchr(temp_params, 'i') ? 'i' : 'd'; } else if (haspercent && (strchr(temp_params, 't') || strchr(temp_params, 'c'))) { type_code = strchr(temp_params, 't') ? 't' : 'c'; } else if (strchr(temp_params, 's')) { type_code = 's'; } if (type_code == '?') { skin_error(INSUFFICIENT_ARGS, cursor); return 0; } } else type_code = *tag_args; /* Storing the type code */ params[i].type_code = type_code; /* Checking a nullable argument for null. */ if(*cursor == DEFAULTSYM && !isdigit(cursor[1])) { if(islower(type_code)) { params[i].type = DEFAULT; cursor++; } else { skin_error(DEFAULT_NOT_ALLOWED, cursor); return 0; } } else if(tolower(type_code) == 'i') { /* Scanning an int argument */ if(!isdigit(*cursor) && *cursor != '-') { skin_error(INT_EXPECTED, cursor); return 0; } params[i].type = INTEGER; params[i].data.number = scan_int(&cursor); } else if(tolower(type_code) == 'd' || tolower(type_code) == 'p') { int val = 0; bool have_point = false; bool have_tenth = false; while ( isdigit(*cursor) || *cursor == '.' ) { if (*cursor != '.') { val *= 10; val += *cursor - '0'; if (have_point) { have_tenth = true; cursor++; break; } } else have_point = true; cursor++; } if (have_tenth == false) val *= 10; if (tolower(type_code) == 'd') params[i].type = DECIMAL; else { params[i].type = PERCENT; cursor++; /* skip trailing % sign */ } params[i].data.number = val; } else if(tolower(type_code) == 's' || tolower(type_code) == 'f') { /* Scanning a string argument */ params[i].type = STRING; params[i].data.text = skin_buffer_to_offset(scan_string(&cursor)); } else if(tolower(type_code) == 'c') { /* Recursively parsing a code argument */ params[i].type = CODE; params[i].data.code = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); if(params[i].data.code < 0) return 0; } else if (tolower(type_code) == 't') { struct skin_element* child = skin_alloc_element(); child->type = TAG; if (!skin_parse_tag(child, &cursor)) return 0; child->next = skin_buffer_to_offset(NULL); params[i].type = CODE; params[i].data.code = skin_buffer_to_offset(child); } skip_whitespace(&cursor); if(*cursor != ARGLISTSEPARATESYM && i < num_args - 1) { skin_error(SEPARATOR_EXPECTED, cursor); return 0; } else if(*cursor != ARGLISTCLOSESYM && i == num_args - 1) { skin_error(CLOSE_EXPECTED, cursor); return 0; } else { cursor++; } if (*(tag_args + 1) == '*') { if (i+1 == num_args) tag_args += 2; else if (open_square_bracket && *tag_args == ']') { tag_args = open_square_bracket; open_square_bracket = NULL; } } else tag_args++; /* Checking for the optional bar */ if(*tag_args == '|') { optional = 1; tag_args++; } } element->params = skin_buffer_to_offset(params); /* Checking for a premature end */ if(*tag_args != '\0' && !optional) { skin_error(INSUFFICIENT_ARGS, cursor); return 0; } #ifdef ROCKBOX if (callback) { if (callback(element, callback_data) == CALLBACK_ERROR) { skin_error(GOT_CALLBACK_ERROR, *document); return 0; } } #endif *document = cursor; return 1; } /* * If the conditional flag is set true, then parsing text will stop at an * ARGLISTSEPARATESYM. Only set that flag when parsing within a conditional */ static int skin_parse_text(struct skin_element* element, const char** document, int conditional) { const char* cursor = *document; int length = 0; int dest; char *text = NULL; /* First figure out how much text we're copying */ while(*cursor != '\0' && *cursor != '\n' && *cursor != MULTILINESYM && *cursor != COMMENTSYM && !((*cursor == ARGLISTSEPARATESYM || *cursor == ARGLISTCLOSESYM || *cursor == ENUMLISTSEPARATESYM || *cursor == ENUMLISTCLOSESYM) && conditional)) { /* Dealing with possibility of escaped characters */ if(*cursor == TAGSYM) { if(find_escape_character(cursor[1])) cursor++; else break; } length++; cursor++; } cursor = *document; /* Copying the text into the element struct */ element->type = TEXT; element->line = skin_line; element->next = skin_buffer_to_offset(NULL); text = skin_alloc_string(length); element->data = skin_buffer_to_offset(text); if (element->data < 0) return 0; for(dest = 0; dest < length; dest++) { /* Advancing cursor if we've encountered an escaped character */ if(*cursor == TAGSYM) cursor++; text[dest] = *cursor; cursor++; } text[length] = '\0'; #ifdef ROCKBOX if (callback) { if (callback(element, callback_data) == CALLBACK_ERROR) { skin_error(GOT_CALLBACK_ERROR, *document); return 0; } } #endif *document = cursor; return 1; } static int skin_parse_conditional(struct skin_element* element, const char** document) { const char* cursor = *document + 1; /* Starting past the "%" */ const char* bookmark; int children = 1; int i; #ifdef ROCKBOX bool feature_available = true; const char *false_branch = NULL; const char *conditional_end = NULL; #endif OFFSETTYPE(struct skin_element*)* children_array = NULL; /* Some conditional tags allow for target feature checking, * so to handle that call the callback as usual with type == TAG * then call it a second time with type == CONDITIONAL and check the return * value */ element->type = TAG; element->line = skin_line; /* Parsing the tag first */ if(!skin_parse_tag(element, &cursor)) return 0; element->type = CONDITIONAL; #ifdef ROCKBOX if (callback) { switch (callback(element, callback_data)) { case FEATURE_NOT_AVAILABLE: feature_available = false; break; case CALLBACK_ERROR: return 0; default: break; } } #endif /* Counting the children */ if(*(cursor++) != ENUMLISTOPENSYM) { skin_error(ARGLIST_EXPECTED, cursor); return 0; } bookmark = cursor; while(*cursor != ENUMLISTCLOSESYM && *cursor != '\0') { if(*cursor == COMMENTSYM) { skip_comment(&cursor); } else if(*cursor == TAGSYM) { skip_tag(&cursor); } else if(*cursor == ENUMLISTSEPARATESYM) { children++; cursor++; if (*cursor == '\n') cursor++; #ifdef ROCKBOX if (false_branch == NULL && !feature_available) { false_branch = cursor; children--; } #endif } else { cursor++; } } #ifdef ROCKBOX if (*cursor == ENUMLISTCLOSESYM && false_branch == NULL && !feature_available) { false_branch = cursor+1; children--; } if (element->tag->flags&FEATURE_TAG) { if (feature_available && children > 1) children--; } conditional_end = cursor; /* if we are skipping the true branch fix that up */ cursor = false_branch ? false_branch : bookmark; #else cursor = bookmark; #endif /* Parsing the children */ /* Feature tags could end up having 0 children which breaks * the render in dangerous ways. Minor hack, but insert an empty * child. (e.g %?xx<foo> when xx isnt available ) */ if (children == 0) { const char* emptyline= ""; children = 1; children_array = skin_alloc_children(children); if (!children_array) return 0; element->children_count = children; children_array[0] = skin_buffer_to_offset(skin_parse_code_as_arg(&emptyline)); } else { children_array = skin_alloc_children(children); if (!children_array) return 0; element->children_count = children; for(i = 0; i < children; i++) { if (*cursor == '\n') { skin_line++; cursor++; } children_array[i] = skin_buffer_to_offset(skin_parse_code_as_arg(&cursor)); if (children_array[i] < 0) return 0; skip_whitespace(&cursor); #ifdef ROCKBOX if ((element->tag->flags&FEATURE_TAG) && feature_available) cursor = conditional_end; #endif if(i < children - 1 && *cursor != ENUMLISTSEPARATESYM) { skin_error(SEPARATOR_EXPECTED, cursor); return 0; } else if(i == children - 1 && *cursor != ENUMLISTCLOSESYM) { skin_error(CLOSE_EXPECTED, cursor); return 0; } else { cursor++; } } } *document = cursor; element->children = skin_buffer_to_offset(children_array); return 1; } static int skin_parse_comment(struct skin_element* element, const char** document) { const char* cursor = *document; #ifndef ROCKBOX char* text = NULL; #endif int length; /* * Finding the index of the ending newline or null-terminator * The length of the string of interest doesn't include the leading #, the * length we need to reserve is the same as the index of the last character */ for(length = 0; cursor[length] != '\n' && cursor[length] != '\0'; length++); element->type = COMMENT; element->line = skin_line; #ifdef ROCKBOX element->data = INVALID_OFFSET; #else element->data = text = skin_alloc_string(length); if (!element->data) return 0; /* We copy from one char past cursor to leave out the # */ memcpy((void*)text, (void*)(cursor + 1), sizeof(char) * (length-1)); text[length - 1] = '\0'; #endif if(cursor[length] == '\n') skin_line++; *document += (length); /* Move cursor up past # and all text */ if(**document == '\n') (*document)++; return 1; } static struct skin_element* skin_parse_code_as_arg(const char** document) { int sublines = 0; const char* cursor = *document; /* Checking for sublines */ while(*cursor != '\n' && *cursor != '\0' && *cursor != ENUMLISTSEPARATESYM && *cursor != ARGLISTSEPARATESYM && *cursor != ENUMLISTCLOSESYM && *cursor != ARGLISTCLOSESYM) { if(*cursor == MULTILINESYM) { sublines = 1; break; } else if(*cursor == TAGSYM) { skip_tag(&cursor); } else { /* Advancing the cursor as normal */ cursor++; } } if(sublines) return skin_parse_sublines_optional(document, 1); else return skin_parse_line_optional(document, 1); }
// returns a token on the heap, or a null pointer Token *scan_string(char **buf) { char *starting_buf = *buf; static int in_multiline_comment = false; char c = read_character(buf); if (in_multiline_comment) { if (c == '*') { if (read_character(buf) == '/') { in_multiline_comment = false; return token_new(COMMENT, "/* ... */", 9); } unread_character(buf); } if (c != '\0') { return scan_string(buf); } } switch(c) { case ':': if (read_character(buf) == '=') { return token_new(ASSIGN, ":=", 2); } unread_character(buf); case '+': return token_new(PLUS, "+", 1); case '-': return token_new(MINUS, "-", 1); case '*': return token_new(TIMES, "*", 1); case '/': c = read_character(buf); if (c == '/') { int len = 2; while ((c = read_character(buf)) && c != '\n' && c != EOF) { len++; } unread_character(buf); return token_new(COMMENT, *buf - len, len); } else if (c == '*' && !in_multiline_comment) { in_multiline_comment = true; return scan_string(buf); } unread_character(buf); return token_new(DIV, "/", 1); case '(': return token_new(LPAREN, "(", 1); case ')': return token_new(RPAREN, ")", 1); case ' ': case '\t': case '\n': return scan_string(buf); case '\0': case EOF: return NULL; } // try and parse an identifer or keyword if (isalpha(c)) { // check if keyword char *keywords[] = {"read", "write"}; int keywords_len = 2; for (int i = 0; i < keywords_len; i++) { if (strncmp(*buf - 1, keywords[i], strlen(keywords[i])) == 0) { *buf += strlen(keywords[i]) - 1; return token_new(KEYWORD, keywords[i], strlen(keywords[i])); } } // parse as identifer int len = 1; while ((c = read_character(buf)) && isalnum(c)) { len++; } // unread the character that broke the while loop unread_character(buf); return token_new(IDENTIFIER, *buf - len, len); } if (isdigit(c) || c == '.') { // parse as digit int len = 1; int dot_found = (c == '.'); while ((c = read_character(buf))) { if (c == '.') { if (dot_found) { break; } dot_found = true; } else if (!isdigit(c)) { break; } len++; } // unread the character that broke the while loop unread_character(buf); return token_new(NUMBER, *buf - len, len); } char debug_str[2] = {c, '\0'}; return token_new(INVALID, debug_str, 1); }
int main (int argc, char *argv[]) { const unsigned char *p, *eof; int i; const char *error_string; struct stat sb; Marpa_Config marpa_configuration; Marpa_Grammar g; Marpa_Recognizer r; /* Longest rule is 4 symbols */ Marpa_Symbol_ID rhs[4]; int fd = open (argv[1], O_RDONLY); //initialize a stat for getting the filesize if (fstat (fd, &sb) == -1) { perror ("fstat"); return 1; } //do the actual mmap, and keep pointer to the first element p = (unsigned char *) mmap (0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); //something went wrong if (p == MAP_FAILED) { perror ("mmap"); return 1; } marpa_c_init (&marpa_configuration); g = marpa_g_new (&marpa_configuration); if (!g) { Marpa_Error_Code errcode = marpa_c_error (&marpa_configuration, &error_string); printf ("marpa_g_new returned %d: %s", errcode, error_string); exit (1); } ((S_begin_array = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_begin_object = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_end_array = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_end_object = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_name_separator = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_value_separator = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_member = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_value = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_false = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_null = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_true = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_object = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_array = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_number = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_string = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_object_contents = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); ((S_array_contents = marpa_g_symbol_new (g)) >= 0) || fail ("marpa_g_symbol_new", g); rhs[0] = S_false; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_null; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_true; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_object; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_array; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_number; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_string; (marpa_g_rule_new (g, S_value, rhs, 1) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_begin_array; rhs[1] = S_array_contents; rhs[2] = S_end_array; (marpa_g_rule_new (g, S_array, rhs, 3) >= 0) || fail ("marpa_g_rule_new", g); rhs[0] = S_begin_object; rhs[1] = S_object_contents; rhs[2] = S_end_object; (marpa_g_rule_new (g, S_object, rhs, 3) >= 0) || fail ("marpa_g_rule_new", g); (marpa_g_sequence_new (g, S_array_contents, S_value, S_value_separator, 0, MARPA_PROPER_SEPARATION) >= 0) || fail ("marpa_g_sequence_new", g); (marpa_g_sequence_new (g, S_object_contents, S_member, S_value_separator, 0, MARPA_PROPER_SEPARATION) >= 0) || fail ("marpa_g_sequence_new", g); rhs[0] = S_string; rhs[1] = S_name_separator; rhs[2] = S_value; (marpa_g_rule_new (g, S_member, rhs, 3) >= 0) || fail ("marpa_g_rule_new", g); if (0) { (marpa_g_symbol_is_terminal_set (g, S_value_separator, 1) >= 0) || fail ("marpa_g_symbol_is_terminal", g); } (marpa_g_start_symbol_set (g, S_value) >= 0) || fail ("marpa_g_start_symbol_set", g); if (marpa_g_precompute (g) < 0) { marpa_g_error (g, &error_string); puts (error_string); exit (1); } r = marpa_r_new (g); if (!r) { marpa_g_error (g, &error_string); puts (error_string); exit (1); } if (!marpa_r_start_input (r)) { marpa_g_error (g, &error_string); puts (error_string); exit (1); } i = 0; eof = p + sb.st_size; while (p + i < eof) { Marpa_Symbol_ID token; const int start_of_token = i; switch (p[i]) { case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': i = scan_number (p + i, eof) - p; token = S_number; break; case '"': i = scan_string (p + i, eof) - p; token = S_string; break; case '[': token = S_begin_array; i++; break; case ']': token = S_end_array; i++; break; case '{': token = S_begin_object; i++; break; case '}': token = S_end_object; i++; break; case ',': token = S_value_separator; i++; break; case ':': token = S_name_separator; i++; break; case 'n': i = scan_constant ("null", (p + i), eof) - p; token = S_null; break; case ' ': case 0x09: case 0x0A: case 0x0D: i++; goto NEXT_TOKEN; default: marpa_g_error (g, &error_string); printf ("lexer failed at char %d: '%c'", i, p[i]); exit (1); } /* Token value of zero is not allowed, so we add one */ if (0) fprintf (stderr, "reading token %ld, %s\n", (long) token, symbol_name (token)); int status = marpa_r_alternative (r, token, start_of_token + 1, 1); if (status != MARPA_ERR_NONE) { Marpa_Symbol_ID expected[20]; int count_of_expected = marpa_r_terminals_expected (r, expected); int i; for (i = 0; i < count_of_expected; i++) { fprintf (stderr, "expecting symbol %ld, %s\n", (long) i, symbol_name (expected[i])); } marpa_g_error (g, &error_string); fprintf (stderr, "marpa_alternative(%p,%ld,%s,%ld,1) returned %d: %s", r, (long) token, symbol_name (token), (long) (start_of_token + 1), status, error_string); exit (1); } status = marpa_r_earleme_complete (r); if (status < 0) { marpa_g_error (g, &error_string); printf ("marpa_earleme_complete returned %d: %s", status, error_string); exit (1); } NEXT_TOKEN:; } { Marpa_Bocage bocage; Marpa_Order order; Marpa_Tree tree; bocage = marpa_b_new (r, -1); if (!bocage) { int errcode = marpa_g_error (g, &error_string); printf ("marpa_bocage_new returned %d: %s", errcode, error_string); exit (1); } order = marpa_o_new (bocage); if (!order) { int errcode = marpa_g_error (g, &error_string); printf ("marpa_order_new returned %d: %s", errcode, error_string); exit (1); } tree = marpa_t_new (order); if (!tree) { Marpa_Error_Code errcode = marpa_g_error (g, &error_string); printf ("marpa_t_new returned %d: %s", errcode, error_string); exit (1); } { Marpa_Value value = NULL; int column = 0; int tree_status; tree_status = marpa_t_next (tree); if (tree_status <= -1) { Marpa_Error_Code errcode = marpa_g_error (g, &error_string); printf ("marpa_t_next returned %d: %s", errcode, error_string); exit (1); } value = marpa_v_new (tree); if (!value) { Marpa_Error_Code errcode = marpa_g_error (g, &error_string); printf ("marpa_v_new returned %d: %s", errcode, error_string); exit (1); } while (1) { Marpa_Step_Type step_type = marpa_v_step (value); Marpa_Symbol_ID token; if (step_type < 0) { Marpa_Error_Code errcode = marpa_g_error (g, &error_string); printf ("marpa_v_event returned %d: %s", errcode, error_string); exit (1); } if (step_type == MARPA_STEP_INACTIVE) { if (0) printf ("No more events\n"); break; } if (step_type != MARPA_STEP_TOKEN) continue; token = marpa_v_token (value); if (1) { if (column > 60) { putchar ('\n'); column = 0; } if (token == S_begin_array) { putchar ('['); column++; continue; } if (token == S_end_array) { putchar (']'); column++; continue; } if (token == S_begin_object) { putchar ('{'); column++; continue; } if (token == S_end_object) { putchar ('}'); column++; continue; } if (token == S_name_separator) { putchar (':'); column++; continue; } if (token == S_value_separator) { putchar (','); column++; continue; } if (token == S_null) { fputs ("undef", stdout); column += 5; continue; } if (token == S_true) { putchar ('1'); column++; continue; } if (token == S_false) { putchar ('0'); column++; continue; } if (token == S_number) { /* We added one to avoid zero * Now we must subtract it */ int i; const int start_of_number = marpa_v_token_value (value) - 1; const int end_of_number = scan_number (p + start_of_number, eof) - p; column += 2 + (end_of_number - start_of_number); /* We output numbers as Perl strings */ putchar ('"'); for (i = start_of_number; i < end_of_number; i++) { putchar (p[i]); } putchar ('"'); continue; } if (token == S_string) { /* We added one to avoid zero * Now we must subtract it, but we also * add one for the initial double quote */ int i; const int start_of_string = marpa_v_token_value (value); /* Subtract one for the final double quote */ const int end_of_string = (scan_string (p + start_of_string, eof) - p) - 1; /* We add back the inital and final double quotes, * and increment the column accordingly. */ column += 2; putchar ('"'); i = start_of_string; while (i < end_of_string) { const unsigned char ch0 = p[i++]; if (ch0 == '\\') { const unsigned char ch1 = p[i++]; switch (ch1) { case '\\': case '/': case '"': case 'b': case 'f': case 'n': case 'r': case 't': /* explicit non-hex JSON escapes are the same * as the Perl escapes */ column += 2; putchar ('\\'); putchar (ch1); continue; case 'u': { int digit; putchar ('x'); putchar ('{'); for (digit = 0; digit < 4; digit++) { const unsigned char hex_ch = p[i + digit]; if ((hex_ch >= 'a' && hex_ch <= 'f') || (hex_ch >= 'A' && hex_ch <= 'F') || (hex_ch >= '0' && hex_ch <= '9')) { printf ("illegal char in JSON hex number at location %d (0x%x): '%c' ", i, hex_ch, hex_ch); exit (1); } putchar (hex_ch); } putchar ('}'); column += 7; i += 4; } continue; default: printf ("illegal escaped char in JSON input (0x%x):'%c' ", i, p[i]); exit (1); } } /* An unescaped JSON char, one that does not need Perl escaping */ if (ch0 == '_' || (ch0 >= '0' && ch0 <= '9') || (ch0 >= 'a' && ch0 <= 'z') || (ch0 >= 'A' && ch0 <= 'Z')) { putchar (ch0); column++; continue; } /* An unescaped JSON char, * but one which quotemeta would escape for Perl */ putchar ('\\'); putchar (ch0); column += 2; continue; } putchar ('"'); continue; } fprintf (stderr, "Unknown symbol %s at %d", symbol_name (token), marpa_v_token_value (value) - 1); exit (1); } } if (column > 60) { putchar ('\n'); column = 0; } } } return 0; }
void fscan_recipy(FILE *fp, struct vs_recipy *vs) { char lb[RECIPY_TEXT + RECSYM_SIZE + 1]; int ret; char *r, *val; if (fp == NULL) return; init_vs_recipy(vs); while ((r = fgets(lb, RECIPY_TEXT+16, fp)) != NULL) { ret = sym_lookup (lb, res_syms, &val); if (ret == -2) // commment, skip continue; if (ret == -1) { info_printf("fscan recipy: bad line: %s\n", lb); continue; } switch (ret) { case 1: scan_string(vs->objname, val, RECIPY_TEXT); break; case 2: scan_string(vs->chart, val, RECIPY_TEXT); break; case 3: scan_string(vs->frame, val, RECIPY_TEXT); break; case 4: scan_double(&(vs->p.r1), val); break; case 5: scan_double(&(vs->p.r2), val); break; case 6: scan_double(&(vs->p.r3), val); break; case 7: scan_int(&(vs->p.quads), val); break; case 8: scan_int(&(vs->p.sky_method), val); break; case 9: scan_double(&(vs->p.sigmas), val); break; case 10: scan_int(&(vs->p.max_iter), val); break; case 11: scan_int(&(vs->usewcs), val); break; case 12: scan_ra(&(vs->ra), val); break; case 13: scan_dec(&(vs->dec), val); break; case 14: ret = radd_std_star(vs, val); break; case 15: ret = radd_pgm_star(vs, val); break; case 16: scan_double(&(vs->p.sat_limit), val); break; case 17: scan_string(vs->repstar, val, RECIPY_TEXT); break; case 18: scan_string(vs->repinfo, val, RECIPY_TEXT); break; case 19: scan_double(&(vs->scint_factor), val); break; case 20: scan_double(&(vs->aperture), val); break; case 21: scan_double(&(vs->airmass), val); break; }; } }
int stream_vscanf (stream_t *stream, const char *fmt, /* Format string for the scanf */ va_list argp) /* Arguments to scanf */ #endif { unsigned char ch, size; unsigned base; unsigned short len; int nmatch, ic; void *ptr; const char *pattern = 0; nmatch = 0; for (;;) switch (ch = FETCH_BYTE (fmt++)) { case '\0': return nmatch; case '%': ch = FETCH_BYTE (fmt++); if (ch == '%') goto def; if (ch != '*') ptr = va_arg (argp, void*); else { ptr = 0; ch = FETCH_BYTE (fmt++); } len = 0; size = REGULAR; while (ch >= '0' && ch <= '9') { len = len*10 + ch - '0'; ch = FETCH_BYTE (fmt++); } if (len == 0) len = 30000; if (ch == 'l') { ch = FETCH_BYTE (fmt++); size = LONG; } else if (ch == 'h') { size = SHORT; ch = FETCH_BYTE (fmt++); } else if (ch == '[') { pattern = fmt; ch = FETCH_BYTE (fmt); if (ch == '^') ch = FETCH_BYTE (++fmt); while (ch != 0 && ch != ']') ch = FETCH_BYTE (++fmt); if (ch != 0) ++fmt; ch = '['; } if (ch >= 'A' && ch <= 'Z') { ch = ch + 'a' - 'A'; size = LONG; } switch (ch) { case 0: return -1; case 'c': if (len == 30000) len = 1; goto string; case 's': case '[': string: if (scan_string (stream, (char*) ptr, ch, len, pattern) && ptr) ++nmatch; break; case 'o': base = 8 | snoUnsigned; goto number; case 'x': base = 16 | snoUnsigned; goto number; case 'd': base = 10; goto number; case 'u': base = 10 | snoUnsigned; number: if (scan_number (stream, ptr, base, len, size) && ptr) ++nmatch; break; } if (feof (stream)) return nmatch ? nmatch : -1; break; case ' ': case '\n': case '\t': /* Skip spaces. */ for (;;) { ic = peekchar (stream); if (ic < 0) break; if (! ISSPACE ((unsigned char) ic)) break; getchar (stream); } break; default: def: ic = peekchar (stream); if (ic < 0) return -1; if ((unsigned char) ic != ch) return nmatch; getchar (stream); }