/********************************************************************** ... ***********************************************************************/ const char *inf_token(struct inputfile *inf, enum inf_token_type type) { const char *c; const char *name; get_token_fn_t func; assert_sanity(inf); assert(type>=INF_TOK_FIRST && type<INF_TOK_LAST); name = tok_tab[type].name ? tok_tab[type].name : "(unnamed)"; func = tok_tab[type].func; if (!func) { freelog(LOG_ERROR, "token type %d (%s) not supported yet", type, name); c = NULL; } else { if (!have_line(inf)) (void) read_a_line(inf); if (!have_line(inf)) { c = NULL; } else { c = func(inf); } } if (c && INF_DEBUG_FOUND) { freelog(LOG_DEBUG, "inputfile: found %s '%s'", name, inf->token.str); } return c; }
/********************************************************************** ... ***********************************************************************/ static const char *get_token_entry_name(struct inputfile *inf) { char *c, *start, *end; assert(have_line(inf)); c = inf->cur_line.str + inf->cur_line_pos; while(*c != '\0' && my_isspace(*c)) { c++; } if (*c == '\0') return NULL; start = c; while (*c != '\0' && !my_isspace(*c) && *c != '=' && !is_comment(*c)) { c++; } if (!(*c != '\0' && (my_isspace(*c) || *c == '='))) return NULL; end = c; while (*c != '\0' && *c != '=' && !is_comment(*c)) { c++; } if (*c != '=') { return NULL; } *end = '\0'; inf->cur_line_pos = c + 1 - inf->cur_line.str; astr_minsize(&inf->token, strlen(start)+1); strcpy(inf->token.str, start); return inf->token.str; }
/********************************************************************** Get a flag token of a single character, with optional preceeding whitespace. ***********************************************************************/ static const char *get_token_white_char(struct inputfile *inf, char target) { char *c; assert(have_line(inf)); c = inf->cur_line.str + inf->cur_line_pos; while(*c != '\0' && my_isspace(*c)) { c++; } if (*c != target) return NULL; inf->cur_line_pos = c + 1 - inf->cur_line.str; assign_flag_token(&inf->token, target); return inf->token.str; }
void line_or_not(t_all *all) { unsigned int i; unsigned int j; int stars; i = -1; while (++i != all->param.rows) { stars = 0; j = -1; while (++j != all->param.cols) { if (!(all->param.map[i][j] != '0')) stars = 1; } if (stars == 0) have_line(i, all); } }
/********************************************************************** ... ***********************************************************************/ static const char *get_token_section_name(struct inputfile *inf) { char *c, *start; assert(have_line(inf)); c = inf->cur_line.str + inf->cur_line_pos; if (*c++ != '[') return NULL; start = c; while (*c != '\0' && *c != ']') { c++; } if (*c != ']') return NULL; *c++ = '\0'; inf->cur_line_pos = c - inf->cur_line.str; astr_minsize(&inf->token, strlen(start)+1); strcpy(inf->token.str, start); return inf->token.str; }
/********************************************************************** ... ***********************************************************************/ static const char *get_token_eol(struct inputfile *inf) { char *c; assert(have_line(inf)); if (!at_eol(inf)) { c = inf->cur_line.str + inf->cur_line_pos; while(*c != '\0' && my_isspace(*c)) { c++; } if (*c != '\0' && !is_comment(*c)) return NULL; } /* finished with this line: say that we don't have it any more: */ inf->cur_line.n = 0; inf->cur_line_pos = 0; assign_flag_token(&inf->token, ' '); return inf->token.str; }
/********************************************************************** This one is more complicated; note that it may read in multiple lines. ***********************************************************************/ static const char *get_token_value(struct inputfile *inf) { struct astring *partial; char *c, *start; char trailing; bool has_i18n_marking = FALSE; char border_character = '\"'; assert(have_line(inf)); c = inf->cur_line.str + inf->cur_line_pos; while(*c != '\0' && my_isspace(*c)) { c++; } if (*c == '\0') return NULL; if (*c == '-' || my_isdigit(*c)) { /* a number: */ start = c++; while(*c != '\0' && my_isdigit(*c)) { c++; } /* check that the trailing stuff is ok: */ if (!(*c == '\0' || *c == ',' || my_isspace(*c) || is_comment(*c))) { return NULL; } /* If its a comma, we don't want to obliterate it permanently, * so rememeber it: */ trailing = *c; *c = '\0'; inf->cur_line_pos = c - inf->cur_line.str; astr_minsize(&inf->token, strlen(start)+1); strcpy(inf->token.str, start); *c = trailing; return inf->token.str; } /* allow gettext marker: */ if (*c == '_' && *(c+1) == '(') { has_i18n_marking = TRUE; c += 2; while(*c != '\0' && my_isspace(*c)) { c++; } if (*c == '\0') return NULL; } border_character = *c; if (border_character != '\"' && border_character != '\'' && border_character != '$') { return NULL; } /* From here, we know we have a string, we just have to find the trailing (un-escaped) double-quote. We read in extra lines if necessary to find it. If we _don't_ find the end-of-string (that is, we come to end-of-file), we return NULL, but we leave the file in at_eof, and don't try to back-up to the current point. (That would be more difficult, and probably not necessary: at that point we probably have a malformed string/file.) As we read extra lines, the string value from previous lines is placed in partial. */ /* prepare for possibly multi-line string: */ inf->string_start_line = inf->line_num; inf->in_string = TRUE; partial = &inf->partial; /* abbreviation */ astr_minsize(partial, 1); partial->str[0] = '\0'; start = c++; /* start includes the initial \", to distinguish from a number */ for(;;) { int pos; while(*c != '\0' && *c != border_character) { /* skip over escaped chars, including backslash-doublequote, and backslash-backslash: */ if (*c == '\\' && *(c+1) != '\0') { c++; } c++; } if (*c == border_character) { /* Found end of string */ break; } /* Accumulate to partial string and try more lines; * note partial->n must be _exactly_ the right size, so we * can strcpy instead of strcat-ing all the way to the end * each time. */ pos = partial->n - 1; astr_minsize(partial, partial->n + c - start + 1); strcpy(partial->str + pos, start); strcpy(partial->str + partial->n - 2, "\n"); if (!read_a_line(inf)) { /* shouldn't happen */ inf_log(inf, LOG_ERROR, "Bad return for multi-line string from read_a_line"); return NULL; } c = start = inf->cur_line.str; } /* found end of string */ *c = '\0'; inf->cur_line_pos = c + 1 - inf->cur_line.str; astr_minsize(&inf->token, partial->n + strlen(start)); strcpy(inf->token.str, partial->str); strcpy(inf->token.str + partial->n - 1, start); /* check gettext tag at end: */ if (has_i18n_marking) { if (*++c == ')') { inf->cur_line_pos++; } else { inf_warn(inf, "Missing end of i18n string marking"); } } inf->in_string = FALSE; return inf->token.str; }