Beispiel #1
0
void
checker_in_eoln(int lineno)
{
  int c;

  c = getc(f_in);
  while (c != EOF && c != '\n' && isspace(c)) c = getc(f_in);
  if (c != EOF && c != '\n') {
    if (c < ' ') {
      if (lineno > 0) {
        fatal_CF(_("%s: %d: invalid control character with code %d"),
                 gettext(f_arr_names[0]), lineno, c);
      } else {
        fatal_CF(_("%s: invalid control character with code %d"),
                 gettext(f_arr_names[0]), c);
      }
    }
    if (lineno > 0) {
      fatal_CF(_("%s: %d: end-of-line expected"), gettext(f_arr_names[0]), lineno);
    } else {
      fatal_CF(_("%s: end-of-line expected"), gettext(f_arr_names[0]));
    }
  }
  if (ferror(f_in)) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[0]));
  }
}
Beispiel #2
0
checker_sexpr_t
checker_read_sexpr(int ind)
{
  int c;
  checker_sexpr_t cur = 0, *plast = &cur, p, q;

  c = getc_unlocked(f_arr[ind]);
  while (c != EOF && isspace(c)) c = getc_unlocked(f_arr[ind]);
  if (c == EOF && ferror(f_arr[ind])) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
  }
  if (c != EOF && c < ' ') {
    fatal_read(ind, _("Invalid control character with code %d"), c);
  }

  if (c == '(') {
    while (1) {
      c = getc_unlocked(f_arr[ind]);
      while (c != EOF && isspace(c)) c = getc_unlocked(f_arr[ind]);
      if (c == EOF && ferror(f_arr[ind])) {
        fatal_CF("%s: input error", gettext(f_arr_names[ind]));
      }
      if (c != EOF && c < ' ') {
        fatal_read(ind, _("Invalid control character with code %d"), c);
      }
      if (c == EOF) {
        fatal_read(ind, _("Unexpected EOF"));
      }
      if (c == ')') break;
      ungetc(c, f_arr[ind]);
      q = checker_read_sexpr(ind);
      p = xcalloc(1, sizeof(*p));
      p->p.kind = CHECKER_SEXPR_PAIR;
      p->p.head = q;
      *plast = p;
      plast = &p->p.tail;
    }
    return cur;
  }

  if (c == EOF && ferror(f_arr[ind])) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
  }
  if (c == EOF) {
    fatal_read(ind, _("Unexpected EOF"));
  }
  ungetc(c, f_arr[ind]);
  p = xcalloc(1, sizeof(*p));
  p->a.kind = CHECKER_SEXPR_ATOM;
  p->a.value = read_atom(ind);
  return p;
}
Beispiel #3
0
int
checker_skip_eoln_ex(
        FILE *f,
        checker_error_func_t error_func,
        const char *name,
        int eof_error_flag)
{
  int c;

  c = getc(f);
  while (c != EOF && c != '\n') {
    if (!isspace(c) && c < ' ') {
      error_func(_("%s: invalid control character with code %d"), name, c);
    }
    c = getc(f);
  }
  if (c == EOF && ferror(f)) {
    fatal_CF(_("%s: input error while seeking EOLN"), name);
  }
  if (c == EOF) {
    if (!eof_error_flag) return -1;
    error_func(_("%s: unexpected EOF while seeking EOLN"), name);
  }
  return 0;
}
Beispiel #4
0
int
checker_main(int argc, char *argv[])
{
  char outsbuf[BUFSIZE], corrsbuf[BUFSIZE];
  char *outdbuf = 0, *corrdbuf = 0;
  size_t outdsz = 0, corrdsz = 0;
  char *outval, *corrval;

  checker_l10n_prepare();

  if (getenv("EJ_REQUIRE_NL")) {
    if (fseek(f_out, -1L, SEEK_END) >= 0) {
      if (getc(f_out) != '\n') fatal_PE(_("No final \\n in the output file"));
      fseek(f_out, 0L, SEEK_SET);
    }
  }

  corrval = checker_read_buf_2(2,_("correct"),1,corrsbuf,BUFSIZE,&corrdbuf,&corrdsz);
  checker_corr_eof();
  if (!is_number(corrval)) fatal_CF(_("correct: not a number"));
  normalize_number(corrval);

  outval = checker_read_buf_2(1, _("output"), 1, outsbuf, BUFSIZE, &outdbuf, &outdsz);
  checker_out_eof();
  if (!is_number(outval)) fatal_PE(_("output: not a number"));
  normalize_number(outval);

  if (strcmp(outval, corrval) != 0)
    fatal_WA(_("Wrong answer: output: %s, correct: %s"), outval, corrval);

  checker_OK();
}
Beispiel #5
0
void *
xmalloc(size_t size)
{
  void *ptr = malloc(size);
  if (!ptr) fatal_CF(_("Out of heap memory: malloc(%zu) failed"),size);
  return ptr;
}
Beispiel #6
0
void
checker_corr_eof(void)
{
    int c;

    while ((c = getc(f_corr)) != EOF && isspace(c));
    if (c != EOF) {
        if (c < ' ') {
            fatal_CF(_("%s: invalid control character with code %d"),
                     gettext(f_arr_names[2]), c);
        } else {
            fatal_CF(_("%s: garbage where EOF expected"),
                     gettext(f_arr_names[2]));
        }
    }
    if (ferror(f_corr)) {
        fatal_CF(_("%s: input error"), gettext(f_arr_names[2]));
    }
}
Beispiel #7
0
static unsigned char *
read_atom(int ind)
{
  int c;
  unsigned char *buf = 0, *tmp;
  size_t buf_a = 0, buf_u = 0;

  c = getc_unlocked(f_arr[ind]);
  while (c != EOF && isspace(c)) c = getc_unlocked(f_arr[ind]);
  if (c != EOF && c < ' ') {
    fatal_read(ind, _("Invalid control character with code %d"), c);
  }
  if (c == EOF && ferror(f_arr[ind])) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
  }

  buf_a = 128;
  buf = alloca(buf_a);

  while (c != EOF && c != ')' && c != '(' && c > ' ') {
    if (buf_u + 1 >= buf_a) {
      buf_a *= 2;
      tmp = alloca(buf_a);
      memcpy(tmp, buf, buf_u);
      buf = tmp;
    }
    buf[buf_u++] = c;
    c = getc_unlocked(f_arr[ind]);
  }
  if (c != EOF && c < ' ' && !isspace(c)) {
    fatal_read(ind, _("Invalid control character with code %d"), c);
  }
  buf[buf_u] = 0;
  if (c != EOF) ungetc(c, f_arr[ind]);
  if (c == EOF && ferror(f_arr[ind])) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
  }
  return xstrdup(buf);
}
Beispiel #8
0
void
checker_read_file_by_line_f(FILE *f,
                            const char *path,
                            char ***out_lines,
                            size_t *out_lines_num)
{
  char **lb_v = 0;
  size_t lb_a = 0, lb_u = 0;
  unsigned char *b_v = 0;
  size_t b_a = 0, b_u = 0;
  unsigned char tv[512];
  size_t tl;

  lb_a = 128;
  lb_v = (char **) xcalloc(lb_a, sizeof(lb_v[0]));
  lb_v[0] = NULL;

  b_a = 1024;
  b_v = (unsigned char *) xmalloc(b_a);
  b_v[0] = 0;

  while (fgets(tv, sizeof(tv), f)) {
    tl = strlen(tv);
    if (tl + b_u >= b_a) {
      while (tl + b_u >= b_a) b_a *= 2;
      b_v = (unsigned char*) xrealloc(b_v, b_a);
    }
    memcpy(b_v + b_u, tv, tl + 1);
    b_u += tl;

    if (tl < sizeof(tv) - 1 || feof(f)) {
      if (lb_u >= lb_a - 1) {
        lb_a *= 2;
        lb_v = (char **) xrealloc(lb_v, lb_a * sizeof(lb_v[0]));
      }
      lb_v[lb_u] = xstrdup(b_v);
      lb_v[++lb_u] = 0;
      b_u = 0;
      b_v[0] = 0;
    }
  }
  if (ferror(f)) {
    fatal_CF(_("Input error from %s file"), path);
  }

  if (out_lines_num) *out_lines_num = lb_u;
  if (out_lines) *out_lines = lb_v;

  free(b_v);
}
Beispiel #9
0
void
checker_do_init(int argc, char **argv, int corr_flag, int info_flag,
                int tgz_flag)
{
  int errcode;
  int need_arg = 3;
  int arg_ind = 3;

  if (corr_flag) need_arg++;
  if (info_flag) need_arg++;
  if (tgz_flag) need_arg += 2;
  if (argc < need_arg)
    fatal_CF(_("Invalid number of arguments: %d instead of %d"), argc, need_arg);

  if (!(f_in = fopen(argv[1], "r")))
    fatal_CF(_("Cannot open input file '%s'"), argv[1]);
  f_arr[0] = f_in;
  if (!(f_out = fopen(argv[2], "r")))
    fatal_PE(_("Cannot open output file '%s'"), argv[2]);
  f_arr[1] = f_out;
  // backward compatibility
  f_team = f_out;

  if (corr_flag) {
    if (!(f_corr = fopen(argv[arg_ind], "r")))
      fatal_CF(_("Cannot open correct output file '%s'"), argv[arg_ind]);
    f_arr[2] = f_corr;
    arg_ind++;
  }

  if (info_flag) {
    if (!testinfo_parse_func)
      fatal_CF(_("Test info is requested, but no code compiled in"));
    errcode = (*testinfo_parse_func)(argv[arg_ind++], &test_info);
    if (errcode < 0)
      fatal_CF(_("Test info parsing failed: %s"),
               (*testinfo_strerror_func)(errcode));
  }

#if !defined __MINGW32__
  if (tgz_flag) {
    if (!(dir_in = opendir(argv[arg_ind])))
      fatal_CF(_("Cannot open input directory '%s'"), argv[arg_ind]);
    dir_in_path = xstrdup(argv[arg_ind]);
    arg_ind++;
    if (!(dir_out = opendir(argv[arg_ind])))
      fatal_CF(_("Cannot open output directory '%s'"), argv[arg_ind]);
    dir_out_path = xstrdup(argv[arg_ind]);
    arg_ind++;
  }
#endif
}
Beispiel #10
0
void
checker_in_open(const char *path)
{
  if (f_in && f_in == f_arr[0]) {
    fclose(f_in); f_in = 0; f_arr[0] = 0;
  }
  if (f_in) fclose(f_in);
  f_in = 0;
  if (f_arr[0]) fclose(f_arr[0]);
  f_arr[0] = 0;

  if (!(f_in = fopen(path, "r")))
    fatal_CF(_("%s: cannot open %s for reading"), gettext(f_arr_names[0]), path);
  f_arr[0] = f_in;
}
Beispiel #11
0
/**
   read a string (i.e. sequence of chars except whitespace)
   \param ind input stream index (0 - test in, 1 - program out, 2 - correct)
   \param name description of data to be read
   \param eof_error_flag if TRUE, EOF condition is error
   \param sbuf static buffer for the string
   \param ssz static buffer size for the string
   \param pdbuf pointer to dynamic buffer pointer
   \param pdsz pointer to dynamic buffer size
 */
char *
checker_read_buf_2(
        int ind,
        const char *name,
        int eof_error_flag,
        char *sbuf,
        size_t ssz,
        char **pdbuf,
        size_t *pdsz)
{
  int c, i = 0;
  char *dbuf = 0;
  size_t dsz = 0;

  c = getc(f_arr[ind]);
  while (isspace(c)) c = getc(f_arr[ind]);
  if (ferror(f_arr[ind])) {
    fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
  }
  if (feof(f_arr[ind])) {
    if (eof_error_flag) fatal_read(ind, _("Unexpected EOF"));
    else return 0;
  }

  if (c < ' ') fatal_read(ind, _("Invalid control character %d"), c);

  if (sbuf && ssz > 1) {
    while (c != EOF && !isspace(c) && i + 1 < ssz) {
      if (c < ' ') fatal_read(ind, _("Invalid control character %d"), c);
      sbuf[i++] = c;
      c = getc(f_arr[ind]);
    }
    if (c == EOF) {
      if (ferror(f_arr[ind])) {
        fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
      }
      sbuf[i] = 0;
      return sbuf;
    }
    if (isspace(c)) {
      ungetc(c, f_arr[ind]);
      sbuf[i] = 0;
      return sbuf;
    }
    if (!pdbuf || !pdsz) fatal_read(ind, _("Input element is too long"));
  } else {
    if (!pdbuf || !pdsz) fatal_CF(_("Invalid arguments"));
  }

  dbuf = *pdbuf;
  dsz = *pdsz;
  if (!dbuf || !dsz) {
    dsz = 32;
    while (i >= dsz) dsz *= 2;
    dbuf = (char *) xmalloc(dsz);
  } else {
    while (i >= dsz) dsz *= 2;
    dbuf = (char*) xrealloc(dbuf, dsz);
  }
  if (i > 0) memcpy(dbuf, sbuf, i + 1);

  while (c != EOF && !isspace(c)) {
    if (c < ' ') fatal_read(ind, _("Invalid control character %d"), c);
    if (i + 1 >= dsz) {
      dsz *= 2;
      dbuf = (char*) xrealloc(dbuf, dsz);
    }
    dbuf[i++] = c;
    c = getc(f_arr[ind]);
  }
  if (c == EOF) {
    if (ferror(f_arr[ind])) {
      fatal_CF(_("%s: input error"), gettext(f_arr_names[ind]));
    }
  } else {
    ungetc(c, f_arr[ind]);
  }
  dbuf[i] = 0;
  *pdbuf = dbuf;
  *pdsz = dsz;
  return dbuf;
}
Beispiel #12
0
void
checker_read_file_by_line_ex(
        FILE *f,
        checker_error_func_t error_func,
        const char *name,
        char ***out_lines,
        size_t *out_lines_num)
{
  unsigned char **lines = 0, **new_l = 0;
  size_t lines_u = 0, lines_a = 0, new_a = 0;
  unsigned char *buf = 0;
  size_t buf_u = 0, buf_a = 0;
  int c;

  *out_lines = 0;
  *out_lines_num = 0;
  if (!name) name = "";

  while ((c = getc_unlocked(f)) != EOF) {
    if (!isspace(c) && c < ' ') {
      error_func(_("%s: invalid control character with code %d"), name, c);
    }
    if (buf_u == buf_a) {
      if (!buf_a) buf_a = 16;
      buf = xrealloc(buf, buf_a *= 2);
    }
    buf[buf_u++] = c;
    if (c == '\n') {
      if (buf_u == buf_a) {
      if (!buf_a) buf_a = 16;
        buf = xrealloc(buf, buf_a *= 2);
      }
      buf[buf_u] = 0;
      if (lines_u == lines_a) {
        if(!(new_a = lines_a * 2)) new_a = 16;
        XCALLOC(new_l, new_a);
        if (lines_a > 0) {
          memcpy(new_l, lines, lines_a * sizeof(new_l[0]));
        }
        free(lines);
        lines_a = new_a;
        lines = new_l;
      }
      lines[lines_u++] = xstrdup(buf);
      buf_u = 0;
    }
  }

  if (ferror_unlocked(f)) {
    fatal_CF(_("%s: input error"), name);
  }
  if (buf_u > 0) {
    if (buf_u == buf_a) {
      buf = xrealloc(buf, buf_a *= 2);
    }
    buf[buf_u] = 0;

    if (lines_u == lines_a) {
      if(!(new_a = lines_a * 2)) new_a = 16;
      XCALLOC(new_l, new_a);
      if (lines_a > 0) {
        memcpy(new_l, lines, lines_a * sizeof(new_l[0]));
      }
      free(lines);
      lines_a = new_a;
      lines = new_l;
    }
    lines[lines_u++] = buf;
    buf = 0; buf_u = buf_a = 0;
  }

  *out_lines = (char**) lines;
  *out_lines_num = lines_u;
}