Пример #1
0
// processes an incoming byte in the midi state machine
void midi_msg_proc(uint8_t b)
{
    bool is_status = ((b & 0x80) != 0);

    // handle status byte
    if (is_status)  {
        if (is_realtime(b)) {
            // real-time, no data, process immediately
            msg_handle_fn(b, NULL, 0);
        } else {
            // non real-time
            idx = 0;
            len = get_len(b);
            status = b;
            if (len == 0) {
                // no data, process immediately
                msg_handle_fn(status, NULL, len);
                status = next_status(status);
            }
        }
        return;
    }

    // handle data byte
    if ((status > 0) && (len > 0)) {
        if (idx < len) {
            // store data byte
            data[idx++] = b;
            if (idx == len) {
                idx = 0;
                // process it
                msg_handle_fn(status, data, len);
                // prepare for next message
                status = next_status(status);
            }
        } else {
            // overrun, should never happen
        }
    } else {
        // unexpected data, ignore it
    }
}
Пример #2
0
int tokenize(struct token_list* tk_list, char* file_buffer)
{
  enum Status status;
   line_num;
  size_t token_begin, token_end;
  token_begin = 0, token_end  = 0;
  status = STATUS_INVALID;
  str_toupper(file_buffer);
  /*
   * Careful: it seems an error to let "i <= len", 
   * but we need one more execution to flush the last token into token list.
   */
  size_t line_num = 1;
  for (size_t i = 0; ; ++i) {
    struct token_node* tok_node;
    switch (status) {
    case STATUS_LETTER:
      if (!IS_LETTER(file_buffer[i]) && !IS_DIGIT(file_buffer[i])) {
        token_end = i;
        tok_node = create_token(TOKEN_LABEL, file_buffer + token_begin, token_end - token_begin);
        tok_node->type = letter_type(tok_node->liter, tok_node->len);
        token_append(tk_list, tok_node);
        token_begin = i;
        status = next_status(status, file_buffer[i]);
      }
      break;
    case STATUS_PRAGMA:
      if (!IS_LETTER(file_buffer[i])) {
        int type;
        token_end = i;
        type = pragma_type(file_buffer + token_begin, token_end - token_begin);
        if (type < 0) {
          error("invalid pragma ad line %d\n", line_num);
          return -4;
        }
        tok_node = create_token(type, file_buffer + token_begin, token_end - token_begin);
        token_append(tk_list, tok_node);
        token_begin = i;
        status = next_status(status, file_buffer[i]);
      }
      break;
    case STATUS_PUNCTUATION:
      token_end = i;
      tok_node = create_token(file_buffer[token_begin], file_buffer + token_begin, token_end - token_begin);
      token_append(tk_list, tok_node);
      token_begin = i;
      status = next_status(status, file_buffer[i]);
      break;
    case STATUS_NUMBER:
      if (!IS_NUMBER(file_buffer[i])) {
        token_end = i;
        if (!check_number(file_buffer + token_begin, token_end - token_begin)) {
          error("invalid number format at line %d\n", line_num);
          return -2;
        }
        tok_node = create_token(TOKEN_NUMBER, file_buffer + token_begin, token_end - token_begin);
        tok_node->data = parse_number(tok_node->liter);
        token_append(tk_list, tok_node);
        token_begin = i;
        status = next_status(status, file_buffer[i]);
      }
      break;
    case STATUS_BLANK:
      if (!IS_BLANK(file_buffer[i])) {
        token_begin = i;
        status = next_status(status, file_buffer[i]);
      }
      break;
    case STATUS_COMMENTS:
      //once status is in comments, it will always be in comments
      if ('\n' == file_buffer[i]) {
        token_begin = i;
        status = next_status(status, file_buffer[i]);
      }
      break;
    case STATUS_INVALID:
      token_begin = i;
      status = next_status(status, file_buffer[i]);
      if (STATUS_INVALID == status && 0 != file_buffer[i]) {
        error("invalid format at line %d\n", line_num);
        return -3;
      }
      break;
    }
    if (0 == file_buffer[i])
      break;
    else if ('\n' == file_buffer[i])
      ++line_num;
  }
  return 0;
}