Example #1
0
CAMLexport value caml_read_root(caml_root root)
{
  value v = (value)root;
  value x;
  Assert(root);
  Assert(Hd_val(root));
  Assert(Int_field(v,1) == 0 || Int_field(v,1) == 1);
  caml_read_field(v, 0, &x);
  return x;
}
Example #2
0
static void decode_terminal_status(value v, int field)
{
  long * pc;
  int i;

  for (pc = terminal_io_descr; *pc != End; field++) {
    switch(*pc++) {
    case Bool:
      { int * dst = (int *) (*pc++);
        int msk = *pc++;
        if (Bool_field(v, field))
          *dst |= msk;
        else
          *dst &= ~msk;
        break; }
    case Enum:
      { int * dst = (int *) (*pc++);
        int ofs = *pc++;
        int num = *pc++;
        int msk = *pc++;
        i = Int_field(v, field) - ofs;
        if (i >= 0 && i < num) {
          *dst = (*dst & ~msk) | pc[i];
        } else {
          unix_error(EINVAL, "tcsetattr", Nothing);
        }
        pc += num;
        break; }
    case Speed:
      { int which = *pc++;
        int baud = Int_field(v, field);
        int res = 0;
        for (i = 0; i < NSPEEDS; i++) {
          if (baud == speedtable[i].baud) {
            switch (which) {
            case Output:
              res = cfsetospeed(&terminal_status, speedtable[i].speed); break;
            case Input:
              res = cfsetispeed(&terminal_status, speedtable[i].speed); break;
            }
            if (res == -1) uerror("tcsetattr", Nothing);
            goto ok;
          }
        }
        unix_error(EINVAL, "tcsetattr", Nothing);
      ok:
        break; }
    case Char:
      { int which = *pc++;
        terminal_status.c_cc[which] = Int_field(v, field);
        break; }
    }
  }
}
Example #3
0
CAMLprim value caml_gr_wait_event(value eventlist) /* ML */
{
  int mask, poll;

  gr_check_open();
  mask = 0;
  poll = 0;
  while (eventlist != Val_int(0)) {
    switch (Int_field(eventlist, 0)) {
    case 0:                     /* Button_down */
      mask |= EVENT_BUTTON_DOWN; break;
    case 1:                     /* Button_up */
      mask |= EVENT_BUTTON_UP; break;
    case 2:                     /* Key_pressed */
      mask |= EVENT_KEY_PRESSED; break;
    case 3:                     /* Mouse_motion */
      mask |= EVENT_MOUSE_MOTION; break;
    case 4:                     /* Poll */
      poll = 1; break;
    }
    eventlist = Field_imm(eventlist, 1);
  }
  if (poll)
    return caml_gr_wait_event_poll();
  else
    return caml_gr_wait_event_blocking(mask);
}
Example #4
0
void caml_cleanup_deleted_roots()
{
  value r, prev;
  int first = 1;
  caml_plat_lock(&roots_mutex);

  r = roots_all;
  while (Is_block(r)) {
    Assert(!Is_foreign(Op_val(r)[2]));
    value next = Op_val(r)[2];
    if (Int_field(r, 1) == 0) {
      /* root was deleted, remove from list */
      if (first) {
        roots_all = next;
      } else {
        caml_modify_field(prev, 2, next);
      }
    }

    prev = r;
    first = 0;
    r = next;
  }

  caml_plat_unlock(&roots_mutex);
}
Example #5
0
value caml_gr_wait_event(value eventlist) /* ML */
{
  int mask;
  Bool poll;

  caml_gr_check_open();
  mask = 0;
  poll = False;
  while (eventlist != Val_int(0)) {
    switch (Int_field(eventlist, 0)) {
    case 0:                     /* Button_down */
      mask |= ButtonPressMask | OwnerGrabButtonMask; break;
    case 1:                     /* Button_up */
      mask |= ButtonReleaseMask | OwnerGrabButtonMask; break;
    case 2:                     /* Key_pressed */
      mask |= KeyPressMask; break;
    case 3:                     /* Mouse_motion */
      mask |= PointerMotionMask; break;
    case 4:                     /* Poll */
      poll = True; break;
    }
    eventlist = Field_imm(eventlist, 1);
  }
  if (poll)
    return caml_gr_wait_event_poll();
  else
    return caml_gr_wait_event_blocking(mask);
}
Example #6
0
CAMLprim value unix_error_message(value err)
{
  int errnum;
  wchar_t buffer[512];

  errnum = Is_block(err) ? Int_field(err, 0) : error_table[Int_val(err)];
  if (errnum > 0)
    return caml_copy_string(strerror(errnum));
  if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                    NULL,
                    -errnum,
                    0,
                    buffer,
                    sizeof(buffer)/sizeof(wchar_t),
                    NULL))
    return caml_copy_string_of_utf16(buffer);
  swprintf(buffer, sizeof(buffer)/sizeof(wchar_t), L"unknown error #%d", errnum);
  return caml_copy_string_of_utf16(buffer);
}
Example #7
0
CAMLprim value unix_error_message(value err)
{
  int errnum;
  errnum = Is_block(err) ? Int_field(err, 0) : error_table[Int_val(err)];
  return caml_copy_string(strerror(errnum));
}
Example #8
0
CAMLprim value caml_parse_engine(struct parser_tables *tables,
                                 struct parser_env *env, value cmd, value arg)
{
  int state;
  mlsize_t sp, asp;
  int errflag;
  int n, n1, n2, m, state1;

  switch(Int_val(cmd)) {

  case START:
    state = 0;
    sp = Int_val(env->sp);
    errflag = 0;

  loop:
    n = Short(tables->defred, state);
    if (n != 0) goto reduce;
    if (Int_val(env->curr_char) >= 0) goto testshift;
    SAVE;
    return READ_TOKEN;
                                /* The ML code calls the lexer and updates */
                                /* symb_start and symb_end */
  case TOKEN_READ:
    RESTORE;
    if (Is_block(arg)) {
      env->curr_char = Val_int(Int_field(tables->transl_block, Tag_val(arg)));
      caml_modify_field((value)env,
                        offsetof(struct parser_env, lval) / sizeof(value),
                        Field(arg, 0));
    } else {
      env->curr_char = Val_int(Int_field(tables->transl_const, Int_val(arg)));
      caml_modify_field((value)env,
                        offsetof(struct parser_env, lval) / sizeof(value),
                        Val_long(0));
    }
    if (trace()) print_token(tables, state, arg);

  testshift:
    n1 = Short(tables->sindex, state);
    n2 = n1 + Int_val(env->curr_char);
    if (n1 != 0 && n2 >= 0 && n2 <= Int_val(tables->tablesize) &&
        Short(tables->check, n2) == Int_val(env->curr_char)) goto shift;
    n1 = Short(tables->rindex, state);
    n2 = n1 + Int_val(env->curr_char);
    if (n1 != 0 && n2 >= 0 && n2 <= Int_val(tables->tablesize) &&
        Short(tables->check, n2) == Int_val(env->curr_char)) {
      n = Short(tables->table, n2);
      goto reduce;
    }
    if (errflag > 0) goto recover;
    SAVE;
    return CALL_ERROR_FUNCTION;
                                /* The ML code calls the error function */
  case ERROR_DETECTED:
    RESTORE;
  recover:
    if (errflag < 3) {
      errflag = 3;
      while (1) {
        state1 = Int_field(env->s_stack, sp);
        n1 = Short(tables->sindex, state1);
        n2 = n1 + ERRCODE;
        if (n1 != 0 && n2 >= 0 && n2 <= Int_val(tables->tablesize) &&
            Short(tables->check, n2) == ERRCODE) {
          if (trace())
            fprintf(stderr, "Recovering in state %d\n", state1);
          goto shift_recover;
        } else {
          if (trace()){
            fprintf(stderr, "Discarding state %d\n", state1);
          }
          if (sp <= Int_val(env->stackbase)) {
            if (trace()){
              fprintf(stderr, "No more states to discard\n");
            }
            return RAISE_PARSE_ERROR; /* The ML code raises Parse_error */
          }
          sp--;
        }
      }
    } else {
      if (Int_val(env->curr_char) == 0)
        return RAISE_PARSE_ERROR; /* The ML code raises Parse_error */
      if (trace()) fprintf(stderr, "Discarding last token read\n");
      env->curr_char = Val_int(-1);
      goto loop;
    }

  shift:
    env->curr_char = Val_int(-1);
    if (errflag > 0) errflag--;
  shift_recover:
    if (trace())
      fprintf(stderr, "State %d: shift to state %d\n",
              state, Short(tables->table, n2));
    state = Short(tables->table, n2);
    sp++;
    if (sp < Long_val(env->stacksize)) goto push;
    SAVE;
    return GROW_STACKS_1;
                                 /* The ML code resizes the stacks */
  case STACKS_GROWN_1:
    RESTORE;
  push:
    Store_field (env->s_stack, sp, Val_int(state));
    Store_field (env->v_stack, sp, env->lval);
    Store_field (env->symb_start_stack, sp, env->symb_start);
    Store_field (env->symb_end_stack, sp, env->symb_end);
    goto loop;

  reduce:
    if (trace())
      fprintf(stderr, "State %d: reduce by rule %d\n", state, n);
    m = Short(tables->len, n);
    env->asp = Val_int(sp);
    env->rule_number = Val_int(n);
    env->rule_len = Val_int(m);
    sp = sp - m + 1;
    m = Short(tables->lhs, n);
    state1 = Int_field(env->s_stack, sp - 1);
    n1 = Short(tables->gindex, m);
    n2 = n1 + state1;
    if (n1 != 0 && n2 >= 0 && n2 <= Int_val(tables->tablesize) &&
        Short(tables->check, n2) == state1) {
      state = Short(tables->table, n2);
    } else {
      state = Short(tables->dgoto, m);
    }
    if (sp < Long_val(env->stacksize)) goto semantic_action;
    SAVE;
    return GROW_STACKS_2;
                                /* The ML code resizes the stacks */
  case STACKS_GROWN_2:
    RESTORE;
  semantic_action:
    SAVE;
    return COMPUTE_SEMANTIC_ACTION;
                                /* The ML code calls the semantic action */
  case SEMANTIC_ACTION_COMPUTED:
    RESTORE;
    Store_field(env->s_stack, sp, Val_int(state));
    caml_modify_field(env->v_stack, sp, arg);
    asp = Int_val(env->asp);
    Store_field (env->symb_end_stack, sp, Field(env->symb_end_stack, asp));
    if (sp > asp) {
      /* This is an epsilon production. Take symb_start equal to symb_end. */
      Store_field (env->symb_start_stack, sp, Field(env->symb_end_stack, asp));
    }
    goto loop;

  default:                      /* Should not happen */
    CAMLassert(0);
    return RAISE_PARSE_ERROR;   /* Keeps gcc -Wall happy */
  }