/********************************************************************** 
  ...
***********************************************************************/
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;
}
Exemple #4
0
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;
}