int map_collect_data_osm(FILE *in, struct maptool_osm *osm) { int size=BUFFER_SIZE; char buffer[BUFFER_SIZE]; char *p; sig_alrm(0); if (!fgets(buffer, size, in) || !xml_declaration_in_line(buffer)){ fprintf(stderr,"FATAL: First line does not start with XML declaration;\n" "this does not look like a valid OSM file.\n"); exit(EXIT_FAILURE); } while (fgets(buffer, size, in)) { p=strchr(buffer,'<'); if (! p) { fprintf(stderr,"FATAL: wrong line in input data (does not start with '<'): %s\n", buffer); fprintf(stderr,"This does not look like a valid OSM file.\n" "Note that maptool can only process OSM files without wrapped or empty lines.\n"); exit(EXIT_FAILURE); } if (!strncmp(p, "<osm ",5)) { } else if (!strncmp(p, "<bound ",7)) { } else if (!strncmp(p, "<node ",6)) { if (!parse_node(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); processed_nodes++; } else if (!strncmp(p, "<tag ",5)) { if (!parse_tag(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); } else if (!strncmp(p, "<way ",5)) { if (!parse_way(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); processed_ways++; } else if (!strncmp(p, "<nd ",4)) { if (!parse_nd(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); } else if (!strncmp(p, "<relation ",10)) { if (!parse_relation(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); processed_relations++; } else if (!strncmp(p, "<member ",8)) { if (!parse_member(p)) fprintf(stderr,"WARNING: failed to parse %s\n", buffer); } else if (!strncmp(p, "</node>",7)) { osm_end_node(osm); } else if (!strncmp(p, "</way>",6)) { osm_end_way(osm); } else if (!strncmp(p, "</relation>",11)) { osm_end_relation(osm); } else if (!strncmp(p, "</osm>",6)) { } else { fprintf(stderr,"WARNING: unknown tag in %s\n", buffer); } } sig_alrm(0); sig_alrm_end(); return 1; }
/* * Parse variable and output appropriate tokens. * Passed with initial identifier in token. * Returns with token terminating variable. * Handles { [ ( <expression> ) ] [ .<identifier> ] } ... */ int parse_variable(TOKEN *token, DECL_MEMBER **var_decl, DECL_ID **var_decl_id) { if (!find_symbol(token, var_decl, var_decl_id)) { parse_error("Undefined variable"); return ERROR; } return parse_member(token, *var_decl, *var_decl_id); }
/* * Parse expression and output appropriate tokens. * Return token at end of expression. */ int parse_expression(TOKEN *token) { int token_class; int i, last_class, temp_class; DECL_MEMBER *id_type; DECL_ID *id_id; char *new_id; char string_const[MAX_TOKEN_LENGTH], octal_const[5]; last_class = OPERATOR; token_class = get_token(token); while (1) { switch (token_class) { case LEFT_PAREN : if (last_class != OPERATOR) { parse_error("Missing operator"); return ERROR; } /* Sub-expression */ out_token(token); /* Parse to closing right paren */ token_class = parse_expression(token); if (token_class != RIGHT_PAREN) { parse_error("Missing ')'"); return ERROR; } out_token(token); break; case RIGHT_PAREN : return token_class; case OPERATOR : out_white_space(token); if (token->token_type == EQUAL) /* Make it a '==' */ out_str("=="); else /* Check for address operator '@' or '.' */ if ((token->token_type == AT_OP) || (token->token_type == PERIOD)) { token_class = get_token(token); if (token_class == IDENTIFIER) { /* Make it a '&' */ out_char('&'); /* See if it's a function reference */ if (find_symbol(token, &id_type, &id_id) && (id_type->type->token_type != PROCEDURE)) { /* Variable - parse it */ temp_class = parse_member(token, id_type, id_id); } else { /* Function call - Check for */ /* a function conversion */ if (check_cvt_id(token, &cvt_functions[0], &new_id)) /* Convert to desired function */ out_str(new_id); else /* Function call - output name */ out_token_name(token); temp_class = get_token(token); } } else if (token_class == LEFT_PAREN) { /* Constant list - convert to string */ out_char('"'); string_const[0] = '\0'; do { token_class = get_token(token); if (token_class == STRING) (void) strcat(string_const, token->token_name); else if (token_class == NUMERIC) { cvt_octal(token, octal_const); (void) strcat(string_const, octal_const); } else { parse_error("Illegal constant"); return ERROR; } token_class = get_token(token); } while (token_class == COMMA); if (token_class != RIGHT_PAREN) { parse_error("')' expected"); return ERROR; } i = strlen(string_const); if ((i >= 4) && (!strcmp(string_const + i - 4, "\\000"))) /* Discard trailing null */ string_const[i - 4] = '\0'; out_str(string_const); out_char('"'); } else { parse_error("Illegal operator"); return ERROR; } } else out_token_name(token); break; case IDENTIFIER : /* Check for identifier conversion */ if (check_cvt_id(token, &cvt_identifiers[0], &new_id)) { out_white_space(token); out_str(new_id); temp_class = get_token(token); } else /* See if variable in context */ if (find_symbol(token, &id_type, &id_id) && (id_type->type->token_type != PROCEDURE)) { /* Variable - parse it */ temp_class = parse_member(token, id_type, id_id); } else /* Function call - parse it */ temp_class = parse_function(token); break; case NUMERIC : out_token(token); break; case STRING : out_white_space(token); /* Convert to a numeric constant */ if (token->token_length > 4) { parse_error("Illegal string constant"); return ERROR; } if (token->token_length > 1) out_char('('); out_str_const(token->token_name, token->token_length); if (token->token_length > 1) out_char(')'); break; default : /* Must not be part of an expression! */ return token_class; } last_class = token_class; token_class = (last_class == IDENTIFIER) ? temp_class : get_token(token); } }
/* * Parse variable name or structure element and output appropriate tokens. * Passed with identifier in token, and declaration for token in decl. * Returns with token terminating variable. * Handles <member> { [ ( <expression> ) ] [ .<identifier> ] } */ int parse_member(TOKEN *token, DECL_MEMBER *decl, DECL_ID *decl_id) { int token_class; TOKEN member; DECL_MEMBER *var_decl; DECL_ID *var_decl_id; /* Check for literal */ if (decl->literal) { /* Yes - output case converted literal */ out_white_space(token); out_cvt_name(token); /* Return next token */ token_class = get_token(token); return token_class; } token_copy(token, &member); token_class = get_token(token); /* Check for array subscript */ if (decl->array_bound) { out_ident(&member, decl, decl_id); if (token_class == LEFT_PAREN) { /* Convert to open square bracket */ token->token_name[0] = '['; out_token(token); /* Parse expression to right parenthesis */ token_class = parse_expression(token); if (token_class != RIGHT_PAREN) { parse_error("')' expected"); return ERROR; } /* Convert to close square bracket */ token->token_name[0] = ']'; out_token(token); token_class = get_token(token); } } /* Check for .<identifier> */ if ((decl->type->token_type == STRUCTURE) && (token_class == PERIOD)) { if (decl->array_bound) /* Already printed identifier */ out_token(token); else { if (decl->at_ptr || decl_id->based_name) { /* * --- Note: Does not handle BASED AT variables! */ /* Print 'member->' */ out_token(&member); out_str("->"); } else { /* Print 'member.' */ out_ident(&member, decl, decl_id); out_token(token); } } token_class = get_token(token); if (token_class != IDENTIFIER) { parse_error("Illegal structure member"); return ERROR; } /* Find variable in list */ if (!find_list_symbol(token, decl->struct_list, &var_decl, &var_decl_id)) { parse_error("Undefined structure member"); return ERROR; } /* Parse this member now */ token_class = parse_member(token, var_decl, var_decl_id); } else if (decl->array_bound == NULL) out_ident(&member, decl, decl_id); return token_class; }