コード例 #1
0
/********************************************************************** 
  ...
***********************************************************************/
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;
}
コード例 #2
0
/********************************************************************** 
  Close the file and free associated memory, but don't recurse
  included_from files, and don't free the actual memory where
  the inf record is stored (ie, the memory where the users pointer
  points to).  This is used when closing an included file.
***********************************************************************/
static void inf_close_partial(struct inputfile *inf)
{
  assert_sanity(inf);

  freelog(LOG_DEBUG, "inputfile: sub-closing \"%s\"", inf_filename(inf));

  if (fz_ferror(inf->fp) != 0) {
    freelog(LOG_ERROR, "Error before closing %s: %s", inf_filename(inf),
	    fz_strerror(inf->fp));
    fz_fclose(inf->fp);
    inf->fp = NULL;
  }
  else if (fz_fclose(inf->fp) != 0) {
    freelog(LOG_ERROR, "Error closing %s", inf_filename(inf));
  }
  if (inf->filename) {
    free(inf->filename);
  }
  inf->filename = NULL;
  astr_free(&inf->cur_line);
  astr_free(&inf->copy_line);
  astr_free(&inf->token);
  astr_free(&inf->partial);

  /* assign zeros for safety if accidently re-use etc: */
  init_zeros(inf);
  inf->magic = ~INF_MAGIC;

  freelog(LOG_DEBUG, "inputfile: sub-closed ok");
}
コード例 #3
0
/********************************************************************** 
  Give a detailed log message, including information on
  current line number etc.  Message can be NULL: then just logs
  information on where we are in the file.
***********************************************************************/
void inf_log(struct inputfile *inf, int loglevel, const char *message)
{
  assert_sanity(inf);

  if (message) {
    freelog(loglevel, "%s", message);
  }
  freelog(loglevel, "  file \"%s\", line %d, pos %d%s",
	  inf_filename(inf), inf->line_num, inf->cur_line_pos,
	  (inf->at_eof ? ", EOF" : ""));
  if (inf->cur_line.str && inf->cur_line.n > 0) {
    freelog(loglevel, "  looking at: '%s'",
	    inf->cur_line.str+inf->cur_line_pos);
  }
  if (inf->copy_line.str && inf->copy_line.n > 0) {
    freelog(loglevel, "  original line: '%s'", inf->copy_line.str);
  }
  if (inf->in_string) {
    freelog(loglevel, "  processing string starting at line %d",
	    inf->string_start_line);
  }
  while ((inf=inf->included_from)) {    /* local pointer assignment */
    freelog(loglevel, "  included from file \"%s\", line %d",
	    inf_filename(inf), inf->line_num);
  }
}
コード例 #4
0
/********************************************************************** 
  Close the file and free associated memory, included any partially
  recursed included files, and the memory allocated for 'inf' itself.
  Should only be used on an actually open inputfile.
  After this, the pointer should not be used.
***********************************************************************/
void inf_close(struct inputfile *inf)
{
  assert_sanity(inf);

  freelog(LOG_DEBUG, "inputfile: closing \"%s\"", inf_filename(inf));
  if (inf->included_from) {
    inf_close(inf->included_from);
  }
  inf_close_partial(inf);
  free(inf);
  freelog(LOG_DEBUG, "inputfile: closed ok");
}
コード例 #5
0
/********************************************************************** 
  Check sensible values for an opened inputfile.
***********************************************************************/
static void assert_sanity(struct inputfile *inf)
{
  assert(inf != NULL);
  assert(inf->magic==INF_MAGIC);
  assert(inf->fp != NULL);
  assert(inf->line_num >= 0);
  assert(inf->cur_line_pos >= 0);
  assert(inf->at_eof == FALSE || inf->at_eof == TRUE);
  assert(inf->in_string == FALSE || inf->in_string == TRUE);
#ifdef DEBUG
  assert(inf->string_start_line >= 0);
  assert(inf->cur_line.n >= 0);
  assert(inf->copy_line.n >= 0);
  assert(inf->token.n >= 0);
  assert(inf->partial.n >= 0);
  assert(inf->cur_line.n_alloc >= 0);
  assert(inf->copy_line.n_alloc >= 0);
  assert(inf->token.n_alloc >= 0);
  assert(inf->partial.n_alloc >= 0);
  if(inf->included_from) {
    assert_sanity(inf->included_from);
  }
#endif
}
コード例 #6
0
ファイル: datum_sequence.cpp プロジェクト: vadz/lmi
void datum_sequence::block_keyword_values(bool z)
{
    keyword_values_are_blocked_ = z;
    assert_sanity();
}
コード例 #7
0
ファイル: datum_sequence.cpp プロジェクト: vadz/lmi
datum_sequence::datum_sequence(std::string const& s)
    :datum_string(s)
    ,keyword_values_are_blocked_(false)
{
    assert_sanity();
}
コード例 #8
0
ファイル: datum_sequence.cpp プロジェクト: vadz/lmi
datum_sequence::datum_sequence()
    :keyword_values_are_blocked_(false)
{
    assert_sanity();
}
コード例 #9
0
/********************************************************************** 
  Read a new line into cur_line; also copy to copy_line.
  Increments line_num and cur_line_pos.
  Returns 0 if didn't read or other problem: treat as EOF.
  Strips newline from input.
***********************************************************************/
static bool read_a_line(struct inputfile *inf)
{
  struct astring *line;
  char *ret;
  int pos;
  
  assert_sanity(inf);

  if (inf->at_eof)
    return FALSE;
  
  /* abbreviation: */
  line = &inf->cur_line;
  
  /* minimum initial line length: */
  astr_minsize(line, 80);
  pos = 0;

  /* don't print "orig line" in warnings until we have it: */
  inf->copy_line.n = 0;
  
  /* Read until we get a full line:
   * At start of this loop, pos is index to trailing null
   * (or first position) in line.
   */
  for(;;) {
    ret = fz_fgets(line->str + pos, line->n_alloc - pos, inf->fp);
    
    if (!ret) {
      /* fgets failed */
      inf->at_eof = TRUE;
      if (inf->in_string) {
        /* Note: Don't allow multi-line strings to cross "include"
         * boundaries */
        inf_log(inf, LOG_ERROR, "Multi-line string went to end-of-file");
        return FALSE;
      }
      break;
    }
    
    pos += strlen(line->str + pos);
    line->n = pos + 1;
    
    if (line->str[pos-1] == '\n') {
      line->str[pos-1] = '\0';
      line->n--;
      break;
    }
    if (line->n != line->n_alloc) {
      freelog(LOG_VERBOSE, "inputfile: expect missing newline at EOF");
    }
    astr_minsize(line, line->n*2);
  }
  inf->line_num++;
  inf->cur_line_pos = 0;

  astr_minsize(&inf->copy_line, inf->cur_line.n + ((inf->cur_line.n == 0) ? 1 : 0));
  strcpy(inf->copy_line.str, inf->cur_line.str);

  if (check_include(inf)) {
    return read_a_line(inf);
  }

  if (inf->at_eof) {
    line->str[0] = '\0';
    line->n = 0;
    if (inf->included_from) {
      /* Pop the include, and get next line from file above instead. */
      struct inputfile *inc = inf->included_from;
      inf_close_partial(inf);
      *inf = *inc;    /* so the user pointer in still valid
                       * (and inf pointers in calling functions) */
      free(inc);
      return read_a_line(inf);
    }
    return FALSE;
  } else {
    return TRUE;
  }
}
コード例 #10
0
/********************************************************************** 
  Check for an include command, which is an isolated line with:
     *include "filename"
  If a file is included via this mechanism, returns 1, and sets up
  data appropriately: (*inf) will now correspond to the new file,
  which is opened but no data read, and inf->included_from is set
  to newly malloced memory which corresponds to the old file.
***********************************************************************/
static bool check_include(struct inputfile *inf)
{
  const char *include_prefix = "*include";
  static size_t len = 0;
  char *bare_name, *full_name, *c;
  struct inputfile *new_inf, temp;

  if (len==0) {
    len = strlen(include_prefix);
  }
  assert_sanity(inf);
  if (inf->in_string || inf->cur_line.n <= len || inf->cur_line_pos > 0) {
    return FALSE;
  }
  if (strncmp(inf->cur_line.str, include_prefix, len)!=0) {
    return FALSE;
  }
  /* from here, the include-line must be well formed or we die */
  /* keep inf->cur_line_pos accurate just so error messages are useful */

  /* skip any whitespace: */
  inf->cur_line_pos = len;
  c = inf->cur_line.str + len;
  while (*c != '\0' && my_isspace(*c)) c++;

  if (*c != '\"') {
    inf_log(inf, LOG_ERROR, 
            "Did not find opening doublequote for '*include' line");
    return FALSE;
  }
  c++;
  inf->cur_line_pos = c - inf->cur_line.str;

  bare_name = c;
  while (*c != '\0' && *c != '\"') c++;
  if (*c != '\"') {
    inf_log(inf, LOG_ERROR, 
            "Did not find closing doublequote for '*include' line");
    return FALSE;
  }
  *c++ = '\0';
  inf->cur_line_pos = c - inf->cur_line.str;

  /* check rest of line is well-formed: */
  while (*c != '\0' && my_isspace(*c) && !is_comment(*c)) c++;
  if (!(*c=='\0' || is_comment(*c))) {
    inf_log(inf, LOG_ERROR, "Junk after filename for '*include' line");
    return FALSE;
  }
  inf->cur_line_pos = inf->cur_line.n-1;

  full_name = inf->datafn(bare_name);
  if (!full_name) {
    freelog(LOG_ERROR, "Could not find included file \"%s\"", bare_name);
    return FALSE;
  }

  /* avoid recursion: (first filename may not have the same path,
     but will at least stop infinite recursion) */
  {
    struct inputfile *inc = inf;
    do {
      if (inc->filename && strcmp(full_name, inc->filename)==0) {
        freelog(LOG_ERROR, 
                "Recursion trap on '*include' for \"%s\"", full_name);
        return FALSE;
      }
    } while((inc=inc->included_from));
  }
  
  new_inf = inf_from_file(full_name, inf->datafn);

  /* Swap things around so that memory pointed to by inf (user pointer,
     and pointer in calling functions) contains the new inputfile,
     and newly allocated memory for new_inf contains the old inputfile.
     This is pretty scary, lets hope it works...
  */
  temp = *new_inf;
  *new_inf = *inf;
  *inf = temp;
  inf->included_from = new_inf;
  return TRUE;
}
コード例 #11
0
/********************************************************************** 
  ...
***********************************************************************/
bool inf_at_eof(struct inputfile *inf)
{
  assert_sanity(inf);
  return inf->at_eof;
}
コード例 #12
0
/********************************************************************** 
  Return 1 if current pos is at end of current line.
***********************************************************************/
static bool at_eol(struct inputfile *inf)
{
  assert_sanity(inf);
  assert(inf->cur_line_pos <= inf->cur_line.n);
  return (inf->cur_line_pos >= inf->cur_line.n - 1);
}
コード例 #13
0
/********************************************************************** 
  Return 1 if have data for current line.
***********************************************************************/
static bool have_line(struct inputfile *inf)
{
  assert_sanity(inf);
  return (inf->cur_line.n > 0);
}