示例#1
0
文件: motion.c 项目: bobrippling/tim
int m_mos(motion_arg const *m, unsigned repeat, window *win, point_t *to)
{
	int y, h;
	screen_or_buf_dimensions(win, &y, &h);
	to->y = y + h / 2;

	start_of_line(to, win);
	return MOTION_SUCCESS;
}
示例#2
0
文件: motion.c 项目: bobrippling/tim
static int m_line_goto(point_t *const pt, unsigned repeat, bool end, window *win)
{
	if(repeat == 0) /* default */
		pt->y = end ? list_count(win->buf->head) : 0;
	else
		pt->y = repeat - 1;

	start_of_line(pt, win);

	return MOTION_SUCCESS;
}
示例#3
0
// Remove any text up to the last GDB prompt
void gdbClearWindowCB(Widget, XtPointer, XtPointer)
{
    XmTextPosition start = start_of_line();
    if (start == XmTextPosition(-1))
	return;

    private_gdb_output = true;

    XmTextReplace(gdb_w, 0, start, XMST(""));

    promptPosition  -= start;
    messagePosition -= start;
    XmTextSetInsertionPosition(gdb_w, XmTextGetLastPosition(gdb_w));

    private_gdb_output = false;
}
示例#4
0
void k_jumpscroll(const keyarg_u *a, unsigned repeat, const int from_ch)
{
	window *w = windows_cur();
	const int height = w->screen_coord.h + 1;

	int inc = 0;

	switch(abs(a->i)){
		case 2:  inc = height;     break;
		case 1:  inc = height / 2; break;
	}

	if(a->i < 0)
		inc = -inc;

	w->ui_pos->y += inc;
	w->ui_start.y += inc;

	start_of_line(NULL, w);

	ui_cur_changed();
	ui_redraw();
}
示例#5
0
文件: motion.c 项目: bobrippling/tim
int m_sos(motion_arg const *m, unsigned repeat, window *win, point_t *to)
{
	to->y = UI_TOP(win);
	start_of_line(to, win);
	return MOTION_SUCCESS;
}
示例#6
0
/* character input
 */
static void _tinysh_char_in(uchar c)
{
  uchar *line=input_buffers[cur_buf_index];

  if(c=='\n' || c=='\r') /* validate command */
    {
      tinysh_cmd_t *cmd;
      int context=0;

/* first, echo the newline */
      if(echo)
        putchar(c);

      while(*line && *line==' ') line++;
      if(*line) /* not empty line */
        {
          cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
          exec_command_line(cmd,line);
          cur_buf_index=(cur_buf_index+1)%HISTORY_DEPTH;
          cur_index=0;
          input_buffers[cur_buf_index][0]=0;
        }
      start_of_line();
    }
/*
  else if(c==TOPCHAR) // return to top level //
    {
      if(echo)
        putchar(c);

      cur_context=0;
      cur_cmd_ctx=0;
    }
//*/
  else if(c==8 || c==127) /* backspace */
    {
      if(cur_index>0)
        {
          puts("\b \b");
          cur_index--;
          line[cur_index]=0;
        }
    }
  else if(c==16) /* CTRL-P: back in history */
    {
      int prevline=(cur_buf_index+HISTORY_DEPTH-1)%HISTORY_DEPTH;

      if(input_buffers[prevline][0])
        {
          line=input_buffers[prevline];
          /* fill the rest of the line with spaces */
          while(cur_index-->strlen(line))
            puts("\b \b");
          putchar('\r');
          start_of_line();
          puts(line);
          cur_index=strlen(line);
          cur_buf_index=prevline;
        }
    }
  else if(c==14) /* CTRL-N: next in history */
    {
      int nextline=(cur_buf_index+1)%HISTORY_DEPTH;

      if(input_buffers[nextline][0])
        {
          line=input_buffers[nextline];
          /* fill the rest of the line with spaces */
          while(cur_index-->strlen(line))
            puts("\b \b");
          putchar('\r');
          start_of_line();
          puts(line);
          cur_index=strlen(line);
          cur_buf_index=nextline;
        }
    }
/*
  else if(c=='?') // display help //
    {
      tinysh_cmd_t *cmd;
      cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
      help_command_line(cmd,line);
      start_of_line();
      puts(line);
      cur_index=strlen(line);
    }
//*/
  else if(c==9) /* TAB: autocompletion */
    {
      tinysh_cmd_t *cmd;
      cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
      //puts(cur_cmd_ctx);puts("--\r\n");
      if(complete_command_line(cmd,line))
        {
          start_of_line();
          puts(line);
        }
      cur_index=strlen(line);
      //sprintf(buf, "cur_index: %d--\r\n", cur_index);
      //puts(buf);
      //puts("cur index:--");puts(cur_index);puts("--\r\n");
    }
  else /* any input character */
    {
      if(cur_index<BUFFER_SIZE)
        {
          if(echo)
            putchar(c);
          line[cur_index++]=c;
          line[cur_index]=0;
        }
    }
}
示例#7
0
	/***************************************************************
	 * fgets_with_edit:
	 ***************************************************************/
char  *fgets_with_edit(		/* Returns:  addr of usrline, or NULL	*/
    char  usrline[]		/* <w> user's input buffer		*/
   ,int   maxlen		/* <r> length of input buffer		*/
   ,FILE  *fp			/* <r> file pointer			*/
   ,char  *prompt		/* <r:opt> prompt string		*/
   )
   {
    int   i,k;
    int   fd;
    int   sts;
    char  *p;
    static char  clrEol[12];
    static char  cursorRight[12];
#ifdef vms
    static int   pasteboard_id;
    static int   keyboard_id;
    static int   key_table_id;
    int   flags;
    short wlen;
    struct descriptor  *dscPtr;
    static DYNAMIC_DESCRIPTOR(dsc_cmdline);
    static struct descriptor dsc_prompt = {0,DSC_K_DTYPE_T,DSC_K_CLASS_S,0};
#else
    int   idx;
    int   ierr;
    int   kchar;
    int   num;
    char  c;
    char  line[256];
    char  displayLine[256];
#if !defined(_WIN32)
    struct termios  tt,ttsave;
#endif
#endif

    fd = fileno(fp);
    if (!isatty(fd))
        return(fgets(usrline,maxlen,fp));

		/*=======================================================
		 * Note: vt100 "terminfo" seems to have extra chars in
		 *  its "cursor_right" escape sequence.  We'll use
		 *  local string "cursorRight" instead ...
		 *  Likewise for "clr_eol" escape sequence.
		 *======================================================*/
    if (!cursorRight[0])
       {			/* first time only ...			*/
        irecall = HISTORY_NOT_ACTIVE;

#ifdef vms
        flags = 1;
        smg$create_pasteboard(&pasteboard_id,0,0,0,&flags);	/*  */
        smg$create_virtual_keyboard(&keyboard_id);
/*        smg$create_key_table(&key_table_id);		/*  */
        cursorRight[0] = 1;		/* indicate no longer first time */
#else
        sts = setupterm(0,1,&ierr);
        if (sts || ierr!=1)
           {
            printf("after setupterm: sts=%d  ierr=%d\n");
            usrline[0] = '\0';
            return(0);
           }

        if (!strncmp(cursor_right,"\033[C",3))
            strncpy(cursorRight,cursor_right,3);
        else
           {
            if (strlen(cursor_right) >= sizeof(cursorRight))
               {
                fprintf(stderr,"fgets_with_edit: cursorRight too short\n");
                exit(0);
               }
            strcpy(cursorRight,cursor_right);
           }

        if (!strncmp(clr_eol,"\033[K",3))
            strncpy(clrEol,clr_eol,3);
        else
           {
            if (strlen(clr_eol) >= sizeof(clrEol))
               {
                fprintf(stderr,"fgets_with_edit: clrEol[] is too short\n");
                exit(0);
               }
            strcpy(clrEol,clr_eol);
           }
#endif
       }

#ifdef vms
		/*=======================================================
		 * VMS only: read using smg routine ...
		 *======================================================*/
    dscPtr = prompt ? &dsc_prompt : 0;
    if (dscPtr)
       {
        dsc_prompt.dscA_pointer = prompt ? prompt : "Command> ";
        dsc_prompt.dscW_length = strlen(dsc_prompt.dscA_pointer);
       }
    sts = smg$read_composed_line(&keyboard_id,0,
                &dsc_cmdline,dscPtr,&wlen);
    if (~sts & 1)
       {
        dasmsg(sts,"Error from smg$read_composed_string");
        return(0);
       }
    p = dsc_cmdline.dscA_pointer ? dsc_cmdline.dscA_pointer : "";
    k = (wlen<maxlen) ? wlen : maxlen;
    strncpy(usrline,p,k);
    if (wlen < maxlen)
        usrline[wlen] = '\0';
#else

		/*=======================================================
		 * Save tty settings;  reset tty for command-line editing.
		 *======================================================*/
#if !defined(_WIN32)
    sts = tcgetattr(fd,&tt);
    memcpy(&ttsave,&tt,sizeof(ttsave));	/* save copy of tt	*/
    tt.c_lflag &= ~ICANON;
    tt.c_lflag &= ~ECHO;
    tt.c_cc[VTIME] = 0;
    tt.c_cc[VMIN] = 1;
    sts = tcsetattr(fd,TCSANOW,&tt);
    if (sts)
       {
        perror("Error from tcseattr");
        usrline[0] = '\0';
        return(0);
       }
#endif
		/*=======================================================
		 * Edit input line from tty ...
		 *======================================================*/
    line[0] = '\0';
    if (prompt)
        printf("%s",prompt);
    fflush(stdout);
    for (p=line ; ; )
       {
        k = read(fd,&c,1);
        if (k<=0 || c=='\n')
            break;

        if (isprint(c) || isspace(c))
           {
            write(1,&c,1);	/* Write c at current position ...	*/
            if (*p)
               {		/* if not at end of line		*/
                if (insert_mode)
                   {
                    k = strlen(p);
                    p[k+1] = '\0';
                    for ( ; k ; k--)
                        p[k] = p[k-1];
                    k = sprintf(displayLine,"%s%s%s",
                            save_cursor,p+1,restore_cursor);
                    i = write(1,displayLine,k);
                   }
               }
            else
                *(p+1) = '\0';		/* else, set new EOL		*/
            *p++ = c;
            continue;
           }
        if (!iscntrl(c))
            continue;

        if (c == DEL)
           {
            if (p <= line)
                continue;
            for (i=0,p-- ; p[i]=p[i+1] ; i++)
                ;
            k = sprintf(displayLine,"%s%s%s %s",
                cursor_left,save_cursor,(i?p:""),restore_cursor);
            write(1,displayLine,k);
            continue;
           }

        switch(c)
           {
            default:
                sprintf(displayLine," ^%c=0x%02X",c+'@',c);
                break;

            case ESC:
                kchar = decode_escape_sequence(fd);
                if (kchar == KEY_LEFT)
                   {
                    if (p > line)
                       {
                        p--;
                        write(1,cursor_left,strlen(cursor_left));
                       }
                   }
                else if (kchar == KEY_RIGHT)
                   {
                    if (*p)
                       {
                        p++;
                        k = strlen(cursorRight);
                        write(1,cursorRight,k);
                       }
                   }
                else if (kchar==KEY_UP || kchar==KEY_DOWN)
                   {
                    p = start_of_line(line,p);
                    write(1,clrEol,strlen(clrEol));
                    strcpy(line,get_history_line(kchar));
                    k = strlen(line);
                    write(1,line,k);
                    p = line + k;
                   }
                break;

            case CTRL_E:	/* Jump to end of line ...		*/
                num = strlen(p);
                if (num)
                   {
                    k = 0;
                    for (i=0 ; i<num ; i++)
                        k += sprintf(displayLine+k,cursorRight);
                    write(1,displayLine,k);
                    p += num;
                   }
                break;

            case CTRL_H:	/* Jump to beginning of line ...	*/
                p = start_of_line(line,p);
                break;

            case CTRL_U:	/* Delete to beginning of line ...	*/
                num = p - line;		/* num chars preceding p	*/
                if (num)
                   {
                    for (i=0,k=0 ; i<num ; i++)
                        k += sprintf(displayLine+k,cursor_left);
                    k += sprintf(displayLine+k,"%s%s",p,clrEol);
                    write(1,displayLine,k);
                    for (i=0 ; line[i]=p[i] ; i++)
                        ;		/* shift chars within line[]	*/
                    p = start_of_line(line,line+i);
                   }
                break;
           }
       }
    if (!icnt && (k=strlen(line)))
        history[icnt++] = strcpy(malloc(k+1),line);
    else
       {
        idx = (icnt-1) % MAX_HISTORY;
        if (nonblank(line) && strcmp(line,history[idx]))
           {
            idx = icnt++ % MAX_HISTORY;
            if (history[idx])
                free(history[idx]);
            history[idx] = strcpy(malloc(strlen(line)+1),line);
           }
       }
    irecall = HISTORY_NOT_ACTIVE;
#if !defined(_WIN32)
    sts = tcsetattr(fd,TCSANOW,&ttsave);
    if (sts)
        perror("Error from tcseattr");
#endif
    strncpy(usrline,line,maxlen);
    printf("\n");
#endif
    return(usrline);
   }
示例#8
0
// Show prompt according to current mode
static void show_isearch()
{
    XmTextPosition start = start_of_line();
    if (start == XmTextPosition(-1))
	return;

    string prompt;
    switch (isearch_state)
    {
    case ISEARCH_NONE:
	prompt = gdb->prompt();
	break;

    case ISEARCH_NEXT:
	prompt = isearch_prompt;
	break;

    case ISEARCH_PREV:
	prompt = reverse_isearch_prompt;
	break;
    }

    if (isearch_state != ISEARCH_NONE)
	prompt += "`" + cook(isearch_string) + "': ";
    string input = current_line();
    string line  = prompt + input;

    bool old_private_gdb_output = private_gdb_output;
    private_gdb_output = true;
    XmTextReplace(gdb_w, start, XmTextGetLastPosition(gdb_w), XMST(line.chars()));
    promptPosition = start + prompt.length();

    XmTextPosition pos = promptPosition;
    int index = input.index(isearch_string);
    if (isearch_state == ISEARCH_NONE || index < 0)
    {
	XmTextSetHighlight(gdb_w, 0, XmTextGetLastPosition(gdb_w),
			   XmHIGHLIGHT_NORMAL);
    }
    else
    {
	XmTextSetHighlight(gdb_w,
			   0,
			   pos + index,
			   XmHIGHLIGHT_NORMAL);
	XmTextSetHighlight(gdb_w,
			   pos + index, 
			   pos + index + isearch_string.length(),
			   XmHIGHLIGHT_SECONDARY_SELECTED);
	XmTextSetHighlight(gdb_w, 
			   pos + index + isearch_string.length(),
			   XmTextGetLastPosition(gdb_w),
			   XmHIGHLIGHT_NORMAL);
    }

    if (index >= 0)
	pos += index;

    XmTextSetInsertionPosition(gdb_w, pos);
    XmTextShowPosition(gdb_w, pos);
    have_isearch_line = false;
    private_gdb_output = old_private_gdb_output;
}
示例#9
0
文件: config_parser.c 项目: smrt28/i3
struct ConfigResultIR *parse_config(const char *input, struct context *context) {
    /* Dump the entire config file into the debug log. We cannot just use
     * DLOG("%s", input); because one log message must not exceed 4 KiB. */
    const char *dumpwalk = input;
    int linecnt = 1;
    while (*dumpwalk != '\0') {
        char *next_nl = strchr(dumpwalk, '\n');
        if (next_nl != NULL) {
            DLOG("CONFIG(line %3d): %.*s\n", linecnt, (int)(next_nl - dumpwalk), dumpwalk);
            dumpwalk = next_nl + 1;
        } else {
            DLOG("CONFIG(line %3d): %s\n", linecnt, dumpwalk);
            break;
        }
        linecnt++;
    }
    state = INITIAL;
    statelist_idx = 1;

    /* A YAJL JSON generator used for formatting replies. */
    command_output.json_gen = yajl_gen_alloc(NULL);

    y(array_open);

    const char *walk = input;
    const size_t len = strlen(input);
    int c;
    const cmdp_token *token;
    bool token_handled;
    linecnt = 1;

// TODO: make this testable
#ifndef TEST_PARSER
    cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
#endif

    /* The "<=" operator is intentional: We also handle the terminating 0-byte
     * explicitly by looking for an 'end' token. */
    while ((size_t)(walk - input) <= len) {
        /* Skip whitespace before every token, newlines are relevant since they
         * separate configuration directives. */
        while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
            walk++;

        //printf("remaining input: %s\n", walk);

        cmdp_token_ptr *ptr = &(tokens[state]);
        token_handled = false;
        for (c = 0; c < ptr->n; c++) {
            token = &(ptr->array[c]);

            /* A literal. */
            if (token->name[0] == '\'') {
                if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
                    if (token->identifier != NULL)
                        push_string(token->identifier, token->name + 1);
                    walk += strlen(token->name) - 1;
                    next_state(token);
                    token_handled = true;
                    break;
                }
                continue;
            }

            if (strcmp(token->name, "number") == 0) {
                /* Handle numbers. We only accept decimal numbers for now. */
                char *end = NULL;
                errno = 0;
                long int num = strtol(walk, &end, 10);
                if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
                    (errno != 0 && num == 0))
                    continue;

                /* No valid numbers found */
                if (end == walk)
                    continue;

                if (token->identifier != NULL)
                    push_long(token->identifier, num);

                /* Set walk to the first non-number character */
                walk = end;
                next_state(token);
                token_handled = true;
                break;
            }

            if (strcmp(token->name, "string") == 0 ||
                strcmp(token->name, "word") == 0) {
                const char *beginning = walk;
                /* Handle quoted strings (or words). */
                if (*walk == '"') {
                    beginning++;
                    walk++;
                    while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\'))
                        walk++;
                } else {
                    if (token->name[0] == 's') {
                        while (*walk != '\0' && *walk != '\r' && *walk != '\n')
                            walk++;
                    } else {
                        /* For a word, the delimiters are white space (' ' or
                         * '\t'), closing square bracket (]), comma (,) and
                         * semicolon (;). */
                        while (*walk != ' ' && *walk != '\t' &&
                               *walk != ']' && *walk != ',' &&
                               *walk != ';' && *walk != '\r' &&
                               *walk != '\n' && *walk != '\0')
                            walk++;
                    }
                }
                if (walk != beginning) {
                    char *str = scalloc(walk - beginning + 1);
                    /* We copy manually to handle escaping of characters. */
                    int inpos, outpos;
                    for (inpos = 0, outpos = 0;
                         inpos < (walk - beginning);
                         inpos++, outpos++) {
                        /* We only handle escaped double quotes to not break
                         * backwards compatibility with people using \w in
                         * regular expressions etc. */
                        if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"')
                            inpos++;
                        str[outpos] = beginning[inpos];
                    }
                    if (token->identifier)
                        push_string(token->identifier, str);
                    free(str);
                    /* If we are at the end of a quoted string, skip the ending
                     * double quote. */
                    if (*walk == '"')
                        walk++;
                    next_state(token);
                    token_handled = true;
                    break;
                }
            }

            if (strcmp(token->name, "line") == 0) {
                while (*walk != '\0' && *walk != '\n' && *walk != '\r')
                    walk++;
                next_state(token);
                token_handled = true;
                linecnt++;
                walk++;
                break;
            }

            if (strcmp(token->name, "end") == 0) {
                //printf("checking for end: *%s*\n", walk);
                if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
                    next_state(token);
                    token_handled = true;
/* To make sure we start with an appropriate matching
                     * datastructure for commands which do *not* specify any
                     * criteria, we re-initialize the criteria system after
                     * every command. */
// TODO: make this testable
#ifndef TEST_PARSER
                    cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
#endif
                    linecnt++;
                    walk++;
                    break;
                }
            }
        }

        if (!token_handled) {
            /* Figure out how much memory we will need to fill in the names of
             * all tokens afterwards. */
            int tokenlen = 0;
            for (c = 0; c < ptr->n; c++)
                tokenlen += strlen(ptr->array[c].name) + strlen("'', ");

            /* Build up a decent error message. We include the problem, the
             * full input, and underline the position where the parser
             * currently is. */
            char *errormessage;
            char *possible_tokens = smalloc(tokenlen + 1);
            char *tokenwalk = possible_tokens;
            for (c = 0; c < ptr->n; c++) {
                token = &(ptr->array[c]);
                if (token->name[0] == '\'') {
                    /* A literal is copied to the error message enclosed with
                     * single quotes. */
                    *tokenwalk++ = '\'';
                    strcpy(tokenwalk, token->name + 1);
                    tokenwalk += strlen(token->name + 1);
                    *tokenwalk++ = '\'';
                } else {
                    /* Skip error tokens in error messages, they are used
                     * internally only and might confuse users. */
                    if (strcmp(token->name, "error") == 0)
                        continue;
                    /* Any other token is copied to the error message enclosed
                     * with angle brackets. */
                    *tokenwalk++ = '<';
                    strcpy(tokenwalk, token->name);
                    tokenwalk += strlen(token->name);
                    *tokenwalk++ = '>';
                }
                if (c < (ptr->n - 1)) {
                    *tokenwalk++ = ',';
                    *tokenwalk++ = ' ';
                }
            }
            *tokenwalk = '\0';
            sasprintf(&errormessage, "Expected one of these tokens: %s",
                      possible_tokens);
            free(possible_tokens);

            /* Go back to the beginning of the line */
            const char *error_line = start_of_line(walk, input);

            /* Contains the same amount of characters as 'input' has, but with
             * the unparseable part highlighted using ^ characters. */
            char *position = scalloc(strlen(error_line) + 1);
            const char *copywalk;
            for (copywalk = error_line;
                 *copywalk != '\n' && *copywalk != '\r' && *copywalk != '\0';
                 copywalk++)
                position[(copywalk - error_line)] = (copywalk >= walk ? '^' : (*copywalk == '\t' ? '\t' : ' '));
            position[(copywalk - error_line)] = '\0';

            ELOG("CONFIG: %s\n", errormessage);
            ELOG("CONFIG: (in file %s)\n", context->filename);
            char *error_copy = single_line(error_line);

            /* Print context lines *before* the error, if any. */
            if (linecnt > 1) {
                const char *context_p1_start = start_of_line(error_line - 2, input);
                char *context_p1_line = single_line(context_p1_start);
                if (linecnt > 2) {
                    const char *context_p2_start = start_of_line(context_p1_start - 2, input);
                    char *context_p2_line = single_line(context_p2_start);
                    ELOG("CONFIG: Line %3d: %s\n", linecnt - 2, context_p2_line);
                    free(context_p2_line);
                }
                ELOG("CONFIG: Line %3d: %s\n", linecnt - 1, context_p1_line);
                free(context_p1_line);
            }
            ELOG("CONFIG: Line %3d: %s\n", linecnt, error_copy);
            ELOG("CONFIG:           %s\n", position);
            free(error_copy);
            /* Print context lines *after* the error, if any. */
            for (int i = 0; i < 2; i++) {
                char *error_line_end = strchr(error_line, '\n');
                if (error_line_end != NULL && *(error_line_end + 1) != '\0') {
                    error_line = error_line_end + 1;
                    error_copy = single_line(error_line);
                    ELOG("CONFIG: Line %3d: %s\n", linecnt + i + 1, error_copy);
                    free(error_copy);
                }
            }

            context->has_errors = true;

            /* Format this error message as a JSON reply. */
            y(map_open);
            ystr("success");
            y(bool, false);
            /* We set parse_error to true to distinguish this from other
             * errors. i3-nagbar is spawned upon keypresses only for parser
             * errors. */
            ystr("parse_error");
            y(bool, true);
            ystr("error");
            ystr(errormessage);
            ystr("input");
            ystr(input);
            ystr("errorposition");
            ystr(position);
            y(map_close);

            /* Skip the rest of this line, but continue parsing. */
            while ((size_t)(walk - input) <= len && *walk != '\n')
                walk++;

            free(position);
            free(errormessage);
            clear_stack();

            /* To figure out in which state to go (e.g. MODE or INITIAL),
             * we find the nearest state which contains an <error> token
             * and follow that one. */
            bool error_token_found = false;
            for (int i = statelist_idx - 1; (i >= 0) && !error_token_found; i--) {
                cmdp_token_ptr *errptr = &(tokens[statelist[i]]);
                for (int j = 0; j < errptr->n; j++) {
                    if (strcmp(errptr->array[j].name, "error") != 0)
                        continue;
                    next_state(&(errptr->array[j]));
                    error_token_found = true;
                    break;
                }
            }

            assert(error_token_found);
        }
    }
示例#10
0
/* character input 
 */
static void _tinysh_char_in(uchar c)
{
uchar *line=input_buffers[cur_buf_index];
int i;

  if(c==128) // start binary transaction
    {
      binary_transaction();
      return;
    }

  if(last_was_switch)
    {
      last_was_switch = 0;
    }
  else if(last_was_escape)
    {
      last_was_escape=0;
      last_was_dummy=1;
    }
  else if(last_was_dummy)
    {
      if(c==65) /* up arrow: back in history */
        {
          int prevline=(cur_buf_index_for_viewing+HISTORY_DEPTH-1)%HISTORY_DEPTH;

          if(input_buffers[prevline][0])
            {
              line=input_buffers[prevline];
              /* fill the rest of the line with spaces */
              while(cur_index-->strlen(line))
                puts("\b \b");
              tinysh_char_out('\r');
              start_of_line();
              puts(line);
              cur_index=strlen(line);
              cur_buf_index_for_viewing=prevline;
              line=input_buffers[cur_buf_index];
              for(i=0;input_buffers[cur_buf_index_for_viewing][i]!=0;i++)
                input_buffers[cur_buf_index][i]=input_buffers[cur_buf_index_for_viewing][i];
              input_buffers[cur_buf_index][i] = 0;
            }
        }
      else if(c==66) /* down: next in history */
        {
          int nextline=(cur_buf_index_for_viewing+1)%HISTORY_DEPTH;

          if(input_buffers[nextline][0])
            {
              line=input_buffers[nextline];
              /* fill the rest of the line with spaces */
              while(cur_index-->strlen(line))
                puts("\b \b");
              tinysh_char_out('\r');
              start_of_line();
              puts(line);
              cur_index=strlen(line);
              cur_buf_index_for_viewing=nextline;
              line=input_buffers[cur_buf_index];
              for(i=0;input_buffers[cur_buf_index_for_viewing][i]!=0;i++)
                input_buffers[cur_buf_index][i]=input_buffers[cur_buf_index_for_viewing][i];
              input_buffers[cur_buf_index][i] = 0;
            }
        }
      last_was_dummy=0;
    }
  else
    {

      if(c=='\n' || c=='\r') /* validate command */
        {
          tinysh_cmd_t *cmd;
          int context=0;
      
    /* first, echo the newline */
          if(echo)
            tinysh_char_out('\n');
            tinysh_char_out('\r');

          line=input_buffers[cur_buf_index];
          input_buffers[cur_buf_index][strlen(line)]=0;
          if(*line) /* not empty line */
            {
              cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
              exec_command_line(cmd,line);
              cur_buf_index=(cur_buf_index+1)%HISTORY_DEPTH;
              cur_index=0;
              input_buffers[cur_buf_index][0]=0;
              cur_buf_index_for_viewing=cur_buf_index;
            }
          start_of_line();
        }
      else if(c==TOPCHAR) /* return to top level */
        {
          if(echo)
            tinysh_char_out(c);

          cur_context=0;
          cur_cmd_ctx=0;
        }
      else if(c==8 || c==127) /* backspace */
        {
          if(cur_index>0)
            {
              puts("\b \b");
              cur_index--;
              line[cur_index]=0;
            }
        }
      else if(c=='~') /* repeat the current line */
        {
          repeat_line();
        }
      else if(c==3) /* cancel the current line */
        {
          if(echo)
            tinysh_char_out('\n');
            tinysh_char_out('\r');
          line=input_buffers[cur_buf_index];
          input_buffers[cur_buf_index][strlen(line)]=0;
          start_of_line();
        }
      else if(c=='`') /* switch FPGA */
        {
          last_was_switch=1;
        }
      else if(c==16) /* CTRL-P: back in history */
        {
          int prevline=(cur_buf_index_for_viewing+HISTORY_DEPTH-1)%HISTORY_DEPTH;

          if(input_buffers[prevline][0])
            {
              line=input_buffers[prevline];
              /* fill the rest of the line with spaces */
              while(cur_index-->strlen(line))
                puts("\b \b");
              tinysh_char_out('\r');
              start_of_line();
              puts(line);
              cur_index=strlen(line);
              cur_buf_index_for_viewing=prevline;
              line=input_buffers[cur_buf_index];
              for(i=0;input_buffers[cur_buf_index_for_viewing][i]!=0;i++)
                input_buffers[cur_buf_index][i]=input_buffers[cur_buf_index_for_viewing][i];
              input_buffers[cur_buf_index][i] = 0;
            }
        }
      else if(c==14) /* CTRL-N: next in history */
        {
          int nextline=(cur_buf_index_for_viewing+1)%HISTORY_DEPTH;

          if(input_buffers[nextline][0])
            {
              line=input_buffers[nextline];
              /* fill the rest of the line with spaces */
              while(cur_index-->strlen(line))
                puts("\b \b");
              tinysh_char_out('\r');
              start_of_line();
              puts(line);
              cur_index=strlen(line);
              cur_buf_index_for_viewing=nextline;
              line=input_buffers[cur_buf_index];
              for(i=0;input_buffers[cur_buf_index_for_viewing][i]!=0;i++)
                input_buffers[cur_buf_index][i]=input_buffers[cur_buf_index_for_viewing][i];
              input_buffers[cur_buf_index][i] = 0;
            }
        }
      else if(c=='?') /* display help */
        {
          tinysh_cmd_t *cmd;
          cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
          help_command_line(cmd,line);
          start_of_line();
          puts(line);
          cur_index=strlen(line);
        }
      else if(c==9 || c=='!') /* TAB: autocompletion */
        {
          tinysh_cmd_t *cmd;
          cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd;
          if(complete_command_line(cmd,line))
            {
              start_of_line();
              puts(line);
            }
          cur_index=strlen(line);
        }      
      else if(c==27)
        {
          last_was_escape=1;
        }
      else /* any input character */
        {
          if(cur_index<BUFFER_SIZE)
            {
              if(echo)
                tinysh_char_out(c);
              line[cur_index++]=c;
              line[cur_index]=0;
            }
        }
    }

}