Пример #1
0
void
typeinfo_clear_bits(typeinfo_t ptr, int bits)
{
    ASSERT(ptr);
    switch (ptr->tag) {
    case CPT_ARITH:
    case CPT_BUILTIN:
        ptr->t_builtin.bits &= ~bits;
        break;
    case CPT_ENUM:
        ptr->t_enum.bits &= ~bits;
        break;
    case CPT_POINTER:
        ptr->t_pointer.bits &= ~bits;
        break;
    case CPT_ARRAY:
        ptr->t_array.bits &= ~bits;
        break;
    case CPT_FUNCTION:
        ptr->t_function.bits &= ~bits;
        break;
    case CPT_AGGREG:
        ptr->t_aggreg.bits &= ~bits;
        break;
    default:
        SWERR(("bad typeinfo tag: %d", ptr->tag));
    }
}
Пример #2
0
void *
os_AttachFILE(int handle, char const *mode)
{
  int   fmode = 0;
  int   fd    = 0;
  FILE *f;

  if (!strcmp(mode, "r")) {
    fmode |= O_RDONLY;
  } else {
    SWERR(("os_AttachFILE: bad mode: %s", mode));
  }
  fd = _open_osfhandle(handle, fmode);
  if (fd < 0) {
    write_log(LOG_REUSE, LOG_ERROR,
	      "os_AttachFILE: _open_osfhandle(%u, %u) failed",
	      (unsigned int) handle, (unsigned int) fmode);
    return NULL;
  }
  write_log(LOG_REUSE, LOG_DEBUG, "os_AttachFILE: fd = %d", fd);
  f = _fdopen(fd, mode);
  if (!f) {
    write_log(LOG_REUSE, LOG_DEBUG, "_fdopen failed");
    return NULL;
  }
  return f;
}
Пример #3
0
int
digest_get_ascii_size(int kind)
{
    switch (kind) {
    case DIGEST_SHA1:
        return 40;
    default:
        SWERR(("unhandled digest type %d", kind));
    }
}
Пример #4
0
/**
 * NAME:    os_rGetWorkingDir
 * PURPOSE: Get the current working directory
 *          path       - the buffer to store the path
 *          maxlen     - the size of the buffer
 *          abort_flag - if 1, failure of getcwd function will
 *                       lead to runtime error (abort)
 * RETURN:  strlen of the current working directory path
 */
int
os_rGetWorkingDir(char *path, unsigned int maxlen, int abort_flag)
{
  errno = 0;
  if (!getcwd(path, maxlen)) {
    if (errno == ERANGE && abort_flag) {
      SWERR(("os_rGetWorkingDir: buffer is too small (size = %d)", maxlen));
    }
    return -1;
  }
  return strlen(path);
}
Пример #5
0
typeinfo_t
typeinfo_clone(typeinfo_t ptr, int flags)
{
    ASSERT(!(flags & ~STI_CLONE_SETABLE));
    ASSERT(ptr);

    switch (ptr->tag) {
    case CPT_ARITH:
        return typeinfo_create_arith((ptr->t_builtin.bits & ~STI_CLONE_CLEAR) | flags, ptr->t_builtin.ind);

    case CPT_BUILTIN:
        return typeinfo_create_builtin((ptr->t_builtin.bits & ~STI_CLONE_CLEAR) | flags, ptr->t_builtin.ind);

    case CPT_ENUM:
        return typeinfo_create_enum((ptr->t_enum.bits & ~STI_CLONE_CLEAR) | flags, ptr->t_enum.id, ptr->t_enum.def);

    case CPT_POINTER:
        return typeinfo_create_pointer((ptr->t_pointer.bits & ~STI_CLONE_CLEAR) | flags,
                                       ptr->t_pointer.type);

    case CPT_ARRAY:
    {
        typeinfo_t tmpt = 0;
        tmpt = typeinfo_create_array(typeinfo_clone(ptr->t_array.type, flags),
                                     ptr->t_array.elnum,
                                     ptr->t_array.size_def);
        tmpt->t_array.size_expr = ptr->t_array.size_expr;
        tmpt->t_array.size_reg = ptr->t_array.size_reg;
        return tmpt;
    }

    case CPT_FUNCTION:
        return typeinfo_create_function(ptr->t_function.bits,
                                        typeinfo_clone(ptr->t_function.ret_type,
                                                flags),
                                        ptr->t_function.par_scope,
                                        ptr->t_function.impl_par_scope);

    case CPT_AGGREG:
        return typeinfo_create_aggreg((ptr->t_aggreg.bits & ~STI_CLONE_CLEAR) | flags, ptr->t_aggreg.id, ptr->t_aggreg.def);

    default:
        SWERR(("bad typeinfo tag: %d", ptr->tag));
    }
}
Пример #6
0
static void
do_build_doc(tex_dom_t node, tex_doc_t pdoc, tex_attr_t *pattr)
{
  tex_attr_t locattr;

  if (!node) return;
  locattr = *pattr;
  switch (node->tag) {
  case TEX__DOC:
    do_build_doc(node->first, pdoc, pattr);
    break;
  case TEX__PAR:
    create_new_paragraph(pdoc, pattr->par_align);
    locattr.is_new_word = 1;
    do_build_doc(node->first, pdoc, &locattr);
    do_build_doc(node->next, pdoc, pattr);
    break;
  case TEX__BLOCK:
    do_build_doc(node->first, pdoc, pattr);
    do_build_doc(node->next, pdoc, pattr);
    break;
  case TEX__WORD:
    if (pattr->is_new_word) create_new_word(pdoc);
    locattr.is_new_word = 0;
    append_to_word(pdoc, node->txt, pattr->font, pattr->is_italic,
                   pattr->is_slanted, pattr->is_bold, pattr->is_underlined);
    do_build_doc(node->next, pdoc, &locattr);
    break;
  case TEX__SPACE:
    locattr.is_new_word = 1;
    do_build_doc(node->next, pdoc, &locattr);
    break;
  case TEX_ENV_CENTER:
    locattr.par_align = TEX_ALIGN_CENTER;
    do_build_doc(node->first, pdoc, &locattr);
    do_build_doc(node->next, pdoc, pattr);
    break;
  default:
    SWERR(("do_build_doc: unhandled node %d (%s)", node->tag,
           tex_dom_get_node_name(node->tag)));
  }
}
Пример #7
0
int
typeinfo_get_bits(typeinfo_t ptr)
{
    ASSERT(ptr);
    switch (ptr->tag) {
    case CPT_ARITH:
        return ptr->t_builtin.bits;
    case CPT_BUILTIN:
        return ptr->t_builtin.bits;
    case CPT_ENUM:
        return ptr->t_enum.bits;
    case CPT_POINTER:
        return ptr->t_pointer.bits;
    case CPT_ARRAY:
        return ptr->t_array.bits;
    case CPT_FUNCTION:
        return ptr->t_function.bits;
    case CPT_AGGREG:
        return ptr->t_aggreg.bits;
    default:
        SWERR(("bad typeinfo tag: %d", ptr->tag));
    }
    return 0;
}
Пример #8
0
static int
do_eval(struct filter_env *env,
        struct filter_tree *t,
        struct filter_tree *res)
{
  int c;
  struct filter_tree r1, r2;
  int lang_id, prob_id, user_id, flags;
  const struct userlist_user *u;
  const struct userlist_member *m;
  const unsigned char *s;

  memset(res, 0, sizeof(*res));
  switch (t->kind) {
  case TOK_LOGOR:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_BOOL_L);
    if (!r1.v.b) {
      if ((c = do_eval(env, t->v.t[1], &r2)) < 0) return c;
      ASSERT(r2.kind == TOK_BOOL_L);
      res->v.b = r2.v.b;
    } else {
      res->v.b = 1;
    }
    break;
    
  case TOK_LOGAND:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_BOOL_L);
    if (r1.v.b) {
      if ((c = do_eval(env, t->v.t[1], &r2)) < 0) return c;
      ASSERT(r2.kind == TOK_BOOL_L);
      res->v.b = r2.v.b;
    } else {
      res->v.b = 0;
    }
    break;

    /* binary */
  case '^':
  case '|':
  case '&':
  case '*':
  case '/':
  case '%':
  case '+':
  case '-':
  case '>':
  case '<':
  case TOK_EQ:
  case TOK_NE:
  case TOK_LE:
  case TOK_GE:
  case TOK_ASL:
  case TOK_ASR:
  case TOK_REGEXP:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    if ((c = do_eval(env, t->v.t[1], &r2)) < 0) return c;
    return filter_tree_eval_node(env->mem, t->kind, res, &r1, &r2);

    /* unary */
  case '~':
  case '!':
  case TOK_UN_MINUS:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    return filter_tree_eval_node(env->mem, t->kind, res, &r1, 0);

  case TOK_TIME:
  case TOK_DUR:
  case TOK_SIZE:
  case TOK_HASH:
  case TOK_UUID:
  case TOK_IP:
  case TOK_PROB:
  case TOK_UID:
  case TOK_LOGIN:
  case TOK_NAME:
  case TOK_GROUP:
  case TOK_LANG:
  case TOK_ARCH:
  case TOK_RESULT:
  case TOK_SCORE:
  case TOK_TEST:
  case TOK_IMPORTED:
  case TOK_HIDDEN:
  case TOK_READONLY:
  case TOK_MARKED:
  case TOK_SAVED:
  case TOK_VARIANT:
  case TOK_RAWVARIANT:
  case TOK_USERINVISIBLE:
  case TOK_USERBANNED:
  case TOK_USERLOCKED:
  case TOK_USERINCOMPLETE:
  case TOK_USERDISQUALIFIED:
  case TOK_LATEST:
  case TOK_LATESTMARKED:
  case TOK_AFTEROK:
  case TOK_EXAMINABLE:
  case TOK_CYPHER:
  case TOK_MISSINGSOURCE:
  case TOK_JUDGE_ID:
  case TOK_PASSED_MODE:
  case TOK_EOLN_TYPE:
  case TOK_STORE_FLAGS:
  case TOK_TOKEN_FLAGS:
  case TOK_TOKEN_COUNT:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_INT_L);
    if (r1.v.i < 0) r1.v.i = env->rtotal + r1.v.i;
    if (r1.v.i >= env->rtotal) return -FILTER_ERR_RANGE;
    if (r1.v.i < 0) return -FILTER_ERR_RANGE;
    switch (t->kind) {
    case TOK_TIME:
      res->kind = TOK_TIME_L;
      res->type = FILTER_TYPE_TIME;
      res->v.a = env->rentries[r1.v.i].time;
      break;
    case TOK_DUR:
      res->kind = TOK_DUR_L;
      res->type = FILTER_TYPE_DUR;
      res->v.u = env->rentries[r1.v.i].time - env->rhead.start_time;
      break;
    case TOK_SIZE:
      res->kind = TOK_SIZE_L;
      res->type = FILTER_TYPE_SIZE;
      res->v.z = env->rentries[r1.v.i].size;
      break;
    case TOK_HASH:
      res->kind = TOK_HASH_L;
      res->type = FILTER_TYPE_HASH;
      memcpy(res->v.h, env->rentries[r1.v.i].sha1, sizeof(env->cur->sha1));
      break;
    case TOK_UUID:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      res->v.s = envdup(env, ej_uuid_unparse(&env->rentries[r1.v.i].run_uuid, ""));
      break;
    case TOK_IP:
      res->kind = TOK_IP_L;
      res->type = FILTER_TYPE_IP;
      run_entry_to_ipv6(&env->rentries[r1.v.i], &res->v.p);
      break;
    case TOK_PROB:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      prob_id = env->rentries[r1.v.i].prob_id;
      if (prob_id <= 0 || prob_id > env->maxprob || !env->probs[prob_id]) {
        res->v.s = envdup(env, "");
      } else {
        res->v.s = envdup(env, env->probs[prob_id]->short_name);
      }
      break;
    case TOK_UID:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = env->rentries[r1.v.i].user_id;
      break;
    case TOK_LOGIN:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.s = envdup(env, "");
      } else {
        res->v.s = envdup(env, teamdb_get_login(env->teamdb_state, user_id));
      }
      break;
    case TOK_NAME:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.s = envdup(env, "");
      } else {
        res->v.s = envdup(env, teamdb_get_name(env->teamdb_state, user_id));
      }
      break;
    case TOK_GROUP:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      user_id = env->rentries[r1.v.i].user_id;
      if (user_id > 0
          && (u = teamdb_get_userlist(env->teamdb_state, user_id))
          && u->cnts0
          && (m = userlist_members_get_first(u->cnts0->members))) {
        res->v.s = envdup(env, m->group);
      } else {
        res->v.s = envdup(env, "");
      }
      break;
    case TOK_LANG:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      lang_id = env->rentries[r1.v.i].lang_id;
      if (lang_id <= 0 || lang_id > env->maxlang || !env->langs[lang_id]) {
        res->v.s = envdup(env, "");
      } else {
        res->v.s = envdup(env, env->langs[lang_id]->short_name);
      }
      break;
    case TOK_ARCH:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      lang_id = env->rentries[r1.v.i].lang_id;
      if (lang_id <= 0 || lang_id > env->maxlang || !env->langs[lang_id]) {
        res->v.s = envdup(env, "");
      } else {
        res->v.s = envdup(env, env->langs[lang_id]->arch);
      }
      break;
    case TOK_RESULT:
      res->kind = TOK_RESULT_L;
      res->type = FILTER_TYPE_RESULT;
      res->v.r = env->rentries[r1.v.i].status;
      break;
    case TOK_SCORE:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = env->rentries[r1.v.i].score;
      break;
    case TOK_TEST:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = env->rentries[r1.v.i].test;
      break;
    case TOK_IMPORTED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = env->rentries[r1.v.i].is_imported;
      break;
    case TOK_HIDDEN:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = env->rentries[r1.v.i].is_hidden;
      break;
    case TOK_READONLY:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = env->rentries[r1.v.i].is_readonly;
      break;
    case TOK_MARKED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = env->rentries[r1.v.i].is_marked;
      break;
    case TOK_SAVED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = env->rentries[r1.v.i].is_saved;
      break;
    case TOK_VARIANT:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      c = env->rentries[r1.v.i].variant;
      if (!c) {
        c = find_variant(env->serve_state, env->rentries[r1.v.i].user_id,
                         env->rentries[r1.v.i].prob_id, 0);
      }
      res->v.i = c;
      break;
    case TOK_RAWVARIANT:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      c = env->rentries[r1.v.i].variant;
      res->v.i = c;
      break;
    case TOK_USERINVISIBLE:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.b = 0;
      } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
        res->v.b = 0;
      } else if ((flags & TEAM_INVISIBLE)) {
        res->v.b = 1;
      } else {
        res->v.b = 0;
      }
      break;
    case TOK_USERBANNED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.b = 0;
      } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
        res->v.b = 0;
      } else if ((flags & TEAM_BANNED)) {
        res->v.b = 1;
      } else {
        res->v.b = 0;
      }
      break;
    case TOK_USERLOCKED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.b = 0;
      } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
        res->v.b = 0;
      } else if ((flags & TEAM_LOCKED)) {
        res->v.b = 1;
      } else {
        res->v.b = 0;
      }
      break;
    case TOK_USERINCOMPLETE:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.b = 0;
      } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
        res->v.b = 0;
      } else if ((flags & TEAM_INCOMPLETE)) {
        res->v.b = 1;
      } else {
        res->v.b = 0;
      }
      break;
    case TOK_USERDISQUALIFIED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      user_id = env->rentries[r1.v.i].user_id;
      if (!user_id) {
        res->v.b = 0;
      } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
        res->v.b = 0;
      } else if ((flags & TEAM_DISQUALIFIED)) {
        res->v.b = 1;
      } else {
        res->v.b = 0;
      }
      break;
    case TOK_LATEST:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = is_latest(env, r1.v.i);
      break;
    case TOK_LATESTMARKED:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = is_latestmarked(env, r1.v.i);
      break;
    case TOK_AFTEROK:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = is_afterok(env, r1.v.i);
      break;
    case TOK_EXAMINABLE:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      //res->v.b = env->rentries[r1.v.i].is_examinable;
      res->v.b = 0;
      break;
    case TOK_CYPHER:
      res->kind = TOK_STRING_L;
      res->type = FILTER_TYPE_STRING;
      user_id = env->rentries[r1.v.i].user_id;
      u = 0; s = 0;
      if (user_id > 0) u = teamdb_get_userlist(env->teamdb_state, user_id);
      if (u && u->cnts0) s = u->cnts0->exam_cypher;
      res->v.s = envdup(env, s);
      break;
    case TOK_MISSINGSOURCE:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.b = is_missing_source(env, &env->rentries[r1.v.i]);
      break;
    case TOK_JUDGE_ID:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = env->rentries[r1.v.i].judge_id;
      break;
    case TOK_PASSED_MODE:
      res->kind = TOK_BOOL_L;
      res->type = FILTER_TYPE_BOOL;
      res->v.i = !!env->rentries[r1.v.i].passed_mode;
      break;
    case TOK_EOLN_TYPE:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = !!env->rentries[r1.v.i].eoln_type;
      break;
    case TOK_STORE_FLAGS:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = !!env->rentries[r1.v.i].store_flags;
      break;
    case TOK_TOKEN_FLAGS:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = !!env->rentries[r1.v.i].token_flags;
      break;
    case TOK_TOKEN_COUNT:
      res->kind = TOK_INT_L;
      res->type = FILTER_TYPE_INT;
      res->v.i = !!env->rentries[r1.v.i].token_count;
      break;
    default:
      abort();
    }
    break;

  case TOK_INT:
  case TOK_STRING:
  case TOK_BOOL:
  case TOK_TIME_T:
  case TOK_DUR_T:
  case TOK_SIZE_T:
  case TOK_RESULT_T:
  case TOK_HASH_T:
  case TOK_IP_T:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    return filter_tree_eval_node(env->mem, t->kind, res, &r1, 0);

    /* variables */
  case TOK_ID:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->rid;
    break;
  case TOK_CURTIME:
    res->kind = TOK_TIME_L;
    res->type = FILTER_TYPE_TIME;
    res->v.a = env->cur->time;
    break;
  case TOK_CURDUR:
    res->kind = TOK_DUR_L;
    res->type = FILTER_TYPE_DUR;
    res->v.u = env->cur->time - env->rhead.start_time;
    break;
  case TOK_CURSIZE:
    res->kind = TOK_SIZE_L;
    res->type = FILTER_TYPE_SIZE;
    res->v.z = env->cur->size;
    break;
  case TOK_CURHASH:
    res->kind = TOK_HASH_L;
    res->type = FILTER_TYPE_HASH;
    memcpy(res->v.h, env->cur->sha1, sizeof(env->cur->sha1));
    break;
  case TOK_CURUUID:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    res->v.s = envdup(env, ej_uuid_unparse(&env->cur->run_uuid, ""));
    break;
  case TOK_CURIP:
    res->kind = TOK_IP_L;
    res->type = FILTER_TYPE_IP;
    run_entry_to_ipv6(env->cur, &res->v.p);
    break;
  case TOK_CURPROB:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    if (env->cur->prob_id <= 0 || env->cur->prob_id > env->maxprob || !env->probs[env->cur->prob_id]) {
      res->v.s = envdup(env, "");
    } else {
      res->v.s = envdup(env, env->probs[env->cur->prob_id]->short_name);
    }
    break;
  case TOK_CURUID:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->user_id;
    break;
  case TOK_CURLOGIN:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    if (!env->cur->user_id) {
      res->v.s = envdup(env, "");
    } else {
      res->v.s = envdup(env, teamdb_get_login(env->teamdb_state, env->cur->user_id));
    }
    break;
  case TOK_CURNAME:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    if (!env->cur->user_id) {
      res->v.s = envdup(env, "");
    } else {
      res->v.s = envdup(env, teamdb_get_name(env->teamdb_state, env->cur->user_id));
    }
    break;
  case TOK_CURGROUP:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    user_id = env->cur->user_id;
    if (user_id > 0
        && (u = teamdb_get_userlist(env->teamdb_state, user_id))
        && u->cnts0
        && (m = userlist_members_get_first(u->cnts0->members))) {
      res->v.s = envdup(env, m->group);
    } else {
      res->v.s = envdup(env, "");
    }
    break;
  case TOK_CURLANG:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    if (env->cur->lang_id <= 0 || env->cur->lang_id > env->maxlang || !env->langs[env->cur->lang_id]) {
      res->v.s = envdup(env, "");
    } else {
      res->v.s = envdup(env, env->langs[env->cur->lang_id]->short_name);
    }
    break;
  case TOK_CURARCH:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    if (env->cur->lang_id <= 0 || env->cur->lang_id > env->maxlang || !env->langs[env->cur->lang_id]) {
      res->v.s = envdup(env, "");
    } else {
      res->v.s = envdup(env, env->langs[env->cur->lang_id]->arch);
    }
    break;
  case TOK_CURRESULT:
    res->kind = TOK_RESULT_L;
    res->type = FILTER_TYPE_RESULT;
    res->v.r = env->cur->status;
    break;
  case TOK_CURSCORE:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->score;
    break;
  case TOK_CURTEST:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->test;
    break;
  case TOK_CURIMPORTED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = env->cur->is_imported;
    break;
  case TOK_CURHIDDEN:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = env->cur->is_hidden;
    break;
  case TOK_CURREADONLY:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = env->cur->is_readonly;
    break;
  case TOK_CURMARKED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = env->cur->is_marked;
    break;
  case TOK_CURSAVED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = env->cur->is_saved;
    break;
  case TOK_CURVARIANT:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    c = env->cur->variant;
    if (!c) c = find_variant(env->serve_state, env->cur->user_id,
                             env->cur->prob_id, 0);
    res->v.i = c;
    break;
  case TOK_CURRAWVARIANT:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    c = env->cur->variant;
    res->v.i = c;
    break;
  case TOK_CURUSERINVISIBLE:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    user_id = env->cur->user_id;
    if (!user_id) {
      res->v.b = 0;
    } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
      res->v.b = 0;
    } else if ((flags & TEAM_INVISIBLE)) {
      res->v.b = 1;
    } else {
      res->v.b = 0;
    }
    break;
  case TOK_CURUSERBANNED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    user_id = env->cur->user_id;
    if (!user_id) {
      res->v.b = 0;
    } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
      res->v.b = 0;
    } else if ((flags & TEAM_BANNED)) {
      res->v.b = 1;
    } else {
      res->v.b = 0;
    }
    break;
  case TOK_CURUSERLOCKED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    user_id = env->cur->user_id;
    if (!user_id) {
      res->v.b = 0;
    } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
      res->v.b = 0;
    } else if ((flags & TEAM_LOCKED)) {
      res->v.b = 1;
    } else {
      res->v.b = 0;
    }
    break;
  case TOK_CURUSERINCOMPLETE:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    user_id = env->cur->user_id;
    if (!user_id) {
      res->v.b = 0;
    } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
      res->v.b = 0;
    } else if ((flags & TEAM_INCOMPLETE)) {
      res->v.b = 1;
    } else {
      res->v.b = 0;
    }
    break;
  case TOK_CURUSERDISQUALIFIED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    user_id = env->cur->user_id;
    if (!user_id) {
      res->v.b = 0;
    } else if ((flags = teamdb_get_flags(env->teamdb_state, user_id)) < 0) {
      res->v.b = 0;
    } else if ((flags & TEAM_DISQUALIFIED)) {
      res->v.b = 1;
    } else {
      res->v.b = 0;
    }
    break;
  case TOK_CURLATEST:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = is_latest(env, env->cur->run_id);
    break;
  case TOK_CURLATESTMARKED:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = is_latestmarked(env, env->cur->run_id);
    break;
  case TOK_CURAFTEROK:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = is_afterok(env, env->cur->run_id);
    break;
  case TOK_CUREXAMINABLE:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    //res->v.b = env->cur->is_examinable;
    res->v.b = 0;
    break;
  case TOK_CURCYPHER:
    res->kind = TOK_STRING_L;
    res->type = FILTER_TYPE_STRING;
    user_id = env->cur->user_id;
    u = 0; s = 0;
    if (user_id > 0) u = teamdb_get_userlist(env->teamdb_state, user_id);
    if (u && u->cnts0) s = u->cnts0->exam_cypher;
    res->v.s = envdup(env, s);
    break;
  case TOK_CURMISSINGSOURCE:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = is_missing_source(env, env->cur);
    break;
  case TOK_CURJUDGE_ID:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->judge_id;
    break;
  case TOK_CURPASSED_MODE:
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.i = !!env->cur->passed_mode;
    break;
  case TOK_CUREOLN_TYPE:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->eoln_type;
    break;
  case TOK_CURSTORE_FLAGS:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->store_flags;
    break;
  case TOK_CURTOKEN_FLAGS:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->token_flags;
    break;
  case TOK_CURTOKEN_COUNT:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->cur->token_count;
    break;
  case TOK_CURTOTAL_SCORE:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = serve_get_user_result_score(env->serve_state,env->cur->user_id);
    break;

  case TOK_NOW:
    res->kind = TOK_TIME_L;
    res->type = FILTER_TYPE_TIME;
    res->v.a = env->cur_time;
    break;
  case TOK_START:
    res->kind = TOK_TIME_L;
    res->type = FILTER_TYPE_TIME;
    res->v.a = env->rhead.start_time;
    break;
  case TOK_FINISH:
    res->kind = TOK_TIME_L;
    res->type = FILTER_TYPE_TIME;
    res->v.a = env->rhead.stop_time;
    break;
  case TOK_TOTAL:
    res->kind = TOK_INT_L;
    res->type = FILTER_TYPE_INT;
    res->v.i = env->rtotal;
    break;

  case TOK_INT_L:
  case TOK_STRING_L:
  case TOK_BOOL_L:
  case TOK_TIME_L:
  case TOK_DUR_L:
  case TOK_SIZE_L:
  case TOK_RESULT_L:
  case TOK_HASH_L:
  case TOK_IP_L:
    *res = *t;
    return 0;

  case TOK_EXAMINATOR:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_INT_L);
    if (r1.v.i < 0) r1.v.i = env->rtotal + r1.v.i;
    if (r1.v.i >= env->rtotal) return -FILTER_ERR_RANGE;
    if (r1.v.i < 0) return -FILTER_ERR_RANGE;
    if ((c = do_eval(env, t->v.t[1], &r2)) < 0) return c;
    ASSERT(r2.kind == TOK_INT_L);
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = 0;
    /*
    for (c = 0; c < 3; c++) {
      if (env->rentries[r1.v.i].examiners[c] == r2.v.i) {
        res->v.b = 1;
        break;
      }
    }
    */
    break;

  case TOK_CUREXAMINATOR:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_INT_L);
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = 0;
    /*
    for (c = 0; c < 3; c++) {
      if (env->cur->examiners[c] == r1.v.i) {
        res->v.b = 1;
        break;
      }
    }
    */
    break;

  case TOK_INUSERGROUP:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_STRING_L);
    if ((c = find_user_group(env, r1.v.s)) < 0) return c;
    t->kind = TOK_INUSERGROUPINT;
    t->v.t[0] = filter_tree_new_int(env->mem, c);
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = check_user_group(env, env->cur->user_id, c);
    break;

  case TOK_INUSERGROUPINT:
    if ((c = do_eval(env, t->v.t[0], &r1)) < 0) return c;
    ASSERT(r1.kind == TOK_INT_L); 
    res->kind = TOK_BOOL_L;
    res->type = FILTER_TYPE_BOOL;
    res->v.b = check_user_group(env, env->cur->user_id, r1.v.i);
    break;   

  default:
    SWERR(("unhandled kind: %d", t->kind));
  }

  return 0;
}
Пример #9
0
static int
right_par_render_func(tex_par_t ppar, tex_buffer_t pbuf, int curline)
{
  SWERR(("not implemented"));
}
Пример #10
0
int
tree_fold(tree_t node, c_value_t *pval)
{
  semainfo_t si;
  struct sema_def *def;
  c_value_t v1, v2;
  int opcode;
  size_t size;
  typeinfo_t tt;
  tree_t decl;

  if (!node) goto failure;

  switch (node->kind) {
  case NODE_EXPRTERNARY:
    if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
    if (c_value_is_true(&v1)) {
      if (tree_fold(node->node.refs[5], pval) < 0) goto failure;
    } else {
      if (tree_fold(node->node.refs[7], pval) < 0) goto failure;
    }
    break;

  case NODE_EXPRBINARY:
    opcode = sema_binop_to_c_operation(node->node.refs[4]->kind);

    switch (opcode) {
    case COP_ASSIGN:
    case COP_MULASSIGN:
    case COP_DIVASSIGN:
    case COP_MODASSIGN:
    case COP_ADDASSIGN:
    case COP_SUBASSIGN:
    case COP_ASLASSIGN:
    case COP_ASRASSIGN:
    case COP_ANDASSIGN:
    case COP_XORASSIGN:
    case COP_ORASSIGN:
      goto failure;

    case COP_COMMA:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (tree_fold(node->node.refs[5], pval) < 0) goto failure;
      break;

    case COP_LOGAND:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (c_value_is_false(&v1)) goto set_false_value;
      if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
      if (c_value_is_false(&v2)) goto set_false_value;
      goto set_true_value;

    case COP_LOGOR:
      if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
      if (c_value_is_true(&v1)) goto set_true_value;
      if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
      if (c_value_is_true(&v2)) goto set_true_value;
      goto set_false_value;

    case COP_BITOR:
    case COP_BITXOR:
    case COP_BITAND:
    case COP_EQ:
    case COP_NE:
    case COP_LT:
    case COP_GT:
    case COP_LE:
    case COP_GE:
    case COP_ASR:
    case COP_ASL:
    case COP_ADD:
    case COP_SUB:
    case COP_MUL:
    case COP_DIV:
    case COP_MOD:
      break;

    default:
      SWERR(("tree_fold: unhandled binary opcode: %d", opcode));
    }

    if (tree_fold(node->node.refs[3], &v1) < 0) goto failure;
    if (tree_fold(node->node.refs[5], &v2) < 0) goto failure;
    if (c_value_operation(0, opcode, &v1, &v2, 0, pval) < 0) goto failure;
    break;

  case NODE_EXPRCAST:
    if (tree_fold(node->node.refs[6], &v1) < 0) goto failure;
    tt = sema_get_expr_type(node->node.refs[6]);
    ASSERT(tt);
    if (tt->tag != CPT_ARITH && tt->tag != CPT_ENUM) goto failure;
    tt = sema_get_expr_type(node);
    if (tt->tag != CPT_ARITH) goto failure;
    if (c_value_cast(&v1, sema_typeinfo_to_index(tt), pval) < 0) goto failure;
    break;

  case NODE_EXPRSIZEOF:
    decl = node->node.refs[5];
    if (!decl) goto failure;
    ASSERT(decl->kind == NODE_DECL);
    si = decl->node.sema;
    if (!si) goto failure;
    ASSERT(si->tag == ST_TYPE);
    tt = si->s_type.type;
    size = sema_get_type_size(tt);
    if (size == SEMA_NO_SIZE) goto failure;
    memset(pval, 0, sizeof(*pval));
    pval->tag = C_ULONG;
    pval->v.ct_ulint = size;
    break;

  case NODE_EXPRUNARY:
    opcode = sema_unop_to_c_operation(node->node.refs[3]->kind);

    switch (opcode) {
    case COP_PREINC:
    case COP_PREDEC:
      goto failure;

    case COP_SIZEOF:
      tt = sema_get_expr_type(node->node.refs[4]);
      size = sema_get_type_size(tt);
      if (size == SEMA_NO_SIZE) goto failure;
      memset(pval, 0, sizeof(*pval));
      pval->tag = C_ULONG;
      pval->v.ct_ulint = size;
      break;

    case COP_DEREF:
    case COP_ADDRESS:
      goto failure;

    case COP_PLUS:
    case COP_MINUS:
    case COP_BITNOT:
    case COP_LOGNOT:
      if (tree_fold(node->node.refs[4], &v1) < 0) goto failure;
      if (c_value_operation(0, opcode, &v1, 0, 0, pval) < 0) goto failure;
      break;

    default:
      SWERR(("tree_fold: unhandled unary opcode: %d", opcode));
    }
    break;

  case NODE_EXPRARRAY:
  case NODE_EXPRCALL:
  case NODE_EXPRFIELD:
  case NODE_EXPRPOSTFIX:
    return -1;

  case NODE_EXPRBRACKETS:
    return tree_fold(node->node.refs[4], pval);

  case NODE_EXPRIDENT:
    si = node->node.sema;
    if (!si) goto failure;
    ASSERT(si->tag == ST_IDUSE);
    def = si->s_iduse.def;
    ASSERT(def->type);
    if (def->type->tag != CPT_ENUM) goto failure;
    if (!SSC_IS_ENUMCONST(def->flags)) goto failure;
    memset(pval, 0, sizeof(*pval));
    memcpy(pval, def->value, sizeof(c_value_t));
    break;

  case NODE_EXPRCONST:
    memset(pval, 0, sizeof(*pval));
    memcpy(pval, &node->node.refs[3]->val.val, sizeof(c_value_t));
    break;

  case NODE_EXPRSTRING:
  case NODE_EXPRVASTART:
  case NODE_EXPRVAARG:
  case NODE_EXPRVAEND:
  case NODE_EXPRINIT:
  case NODE_EXPRASM:
    return -1;
  default:
    SWERR(("tree_fold: bad node: kind == %d", node->kind));
  }
  return 0;

 failure:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  return -1;

 set_false_value:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  return 0;

 set_true_value:
  memset(pval, 0, sizeof(*pval));
  pval->tag = C_INT;
  pval->v.ct_int = 1;
  return 0;
}