int cmdexec(File *f, Cmd *cp) { int i; Addr *ap; Address a; if(f && f->unread) load(f); if(f==0 && (cp->addr==0 || cp->addr->type!='"') && !utfrune("bBnqUXY!", cp->cmdc) && cp->cmdc!=('c'|0x100) && !(cp->cmdc=='D' && cp->ctext)) error(Enofile); i = lookup(cp->cmdc); if(i >= 0 && cmdtab[i].defaddr != aNo){ if((ap=cp->addr)==0 && cp->cmdc!='\n'){ cp->addr = ap = newaddr(); ap->type = '.'; if(cmdtab[i].defaddr == aAll) ap->type = '*'; }else if(ap && ap->type=='"' && ap->next==0 && cp->cmdc!='\n'){ ap->next = newaddr(); ap->next->type = '.'; if(cmdtab[i].defaddr == aAll) ap->next->type = '*'; } if(cp->addr){ /* may be false for '\n' (only) */ static Address none = {0,0,0}; if(f) addr = address(ap, f->dot, 0); else /* a " */ addr = address(ap, none, 0); f = addr.f; } } current(f); switch(cp->cmdc){ case '{': a = cp->addr? address(cp->addr, f->dot, 0): f->dot; for(cp = cp->ccmd; cp; cp = cp->next){ a.f->dot = a; cmdexec(a.f, cp); } break; default: i=(*cmdtab[i].fn)(f, cp); return i; } return 1; }
void editthread(void*) { Cmd *cmdp; threadsetname("editthread"); while((cmdp=parsecmd(0)) != 0){ // ocurfile = curfile; // loaded = curfile && !curfile->unread; if(cmdexec(curtext, cmdp) == 0) break; freecmd(); } sendp(editerrc, nil); }
void filelooper(Cmd *cp, int XY) { File *f, *cur; int i; if(Glooping++) error(EnestXY); nest++; settempfile(); cur = curfile; for(i = 0; i<tempfile.nused; i++){ f = tempfile.filepptr[i]; if(f==cmd) continue; if(cp->re==0 || filematch(f, cp->re)==XY) cmdexec(f, cp->ccmd); } if(cur && whichmenu(cur)>=0) /* check that cur is still a file */ current(cur); --Glooping; --nest; }
void looper(File *f, Cmd *cp, int xy) { Posn p, op; Range r; r = addr.r; op= xy? -1 : r.p1; nest++; compile(cp->re); for(p = r.p1; p<=r.p2; ){ if(!execute(f, p, r.p2)){ /* no match, but y should still run */ if(xy || op>r.p2) break; f->dot.r.p1 = op, f->dot.r.p2 = r.p2; p = r.p2+1; /* exit next loop */ }else{ if(sel.p[0].p1==sel.p[0].p2){ /* empty match? */ if(sel.p[0].p1==op){ p++; continue; } p = sel.p[0].p2+1; }else p = sel.p[0].p2; if(xy) f->dot.r = sel.p[0]; else f->dot.r.p1 = op, f->dot.r.p2 = sel.p[0].p1; } op = sel.p[0].p2; cmdexec(f, cp->ccmd); compile(cp->re); } --nest; }
/** * @brief Shell thread function. * * @param[in] p pointer to a @p BaseSequentialStream object * @return Termination reason. * @retval RDY_OK terminated by command. * @retval RDY_RESET terminated by reset condition on the I/O channel. */ static msg_t shell_thread(void *p) { int n; msg_t msg = RDY_OK; BaseSequentialStream *chp = ((ShellConfig *)p)->sc_channel; const ShellCommand *scp = ((ShellConfig *)p)->sc_commands; char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH]; char *args[SHELL_MAX_ARGUMENTS + 1]; chRegSetThreadName("shell"); chprintf(chp, "\r\nChibiOS/RT Shell\r\n"); while (TRUE) { chprintf(chp, "ch> "); if (shellGetLine(chp, line, sizeof(line))) { chprintf(chp, "\r\nlogout"); break; } lp = _strtok(line, " \009", &tokp); cmd = lp; n = 0; while ((lp = _strtok(NULL, " \009", &tokp)) != NULL) { if (n >= SHELL_MAX_ARGUMENTS) { chprintf(chp, "too many arguments\r\n"); cmd = NULL; break; } args[n++] = lp; } args[n] = NULL; if (cmd != NULL) { if (strcasecmp(cmd, "exit") == 0) { if (n > 0) { usage(chp, "exit"); continue; } break; } else if (strcasecmp(cmd, "help") == 0) { if (n > 0) { usage(chp, "help"); continue; } chprintf(chp, "Commands: help exit "); list_commands(chp, local_commands); if (scp != NULL) list_commands(chp, scp); chprintf(chp, "\r\n"); } else if (cmdexec(local_commands, chp, cmd, n, args) && ((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) { chprintf(chp, "%s", cmd); chprintf(chp, " ?\r\n"); } } } /* Atomically broadcasting the event source and terminating the thread, there is not a chSysUnlock() because the thread terminates upon return.*/ chSysLock(); chEvtBroadcastI(&shell_terminated); chThdExitS(msg); return 0; /* Never executed.*/ }
/** * @brief Shell thread function. * * @param[in] p pointer to a @p BaseSequentialStream object */ THD_FUNCTION(shellThread, p) { int n; ShellConfig *scfg = p; BaseSequentialStream *chp = scfg->sc_channel; const ShellCommand *scp = scfg->sc_commands; char *lp, *cmd, *tokp, line[SHELL_MAX_LINE_LENGTH]; char *args[SHELL_MAX_ARGUMENTS + 1]; #if SHELL_USE_HISTORY == TRUE *(scfg->sc_histbuf) = 0; ShellHistory hist = { scfg->sc_histbuf, scfg->sc_histsize, 0, 0, 0 }; ShellHistory *shp = &hist; #else ShellHistory *shp = NULL; #endif chprintf(chp, SHELL_NEWLINE_STR); chprintf(chp, "ChibiOS/RT Shell"SHELL_NEWLINE_STR); while (true) { chprintf(chp, SHELL_PROMPT_STR); if (shellGetLine(scfg, line, sizeof(line), shp)) { #if (SHELL_CMD_EXIT_ENABLED == TRUE) && !defined(_CHIBIOS_NIL_) chprintf(chp, SHELL_NEWLINE_STR); chprintf(chp, "logout"); break; #else /* Putting a delay in order to avoid an endless loop trying to read an unavailable stream.*/ osalThreadSleepMilliseconds(100); #endif } lp = parse_arguments(line, &tokp); cmd = lp; n = 0; while ((lp = parse_arguments(NULL, &tokp)) != NULL) { if (n >= SHELL_MAX_ARGUMENTS) { chprintf(chp, "too many arguments"SHELL_NEWLINE_STR); cmd = NULL; break; } args[n++] = lp; } args[n] = NULL; if (cmd != NULL) { if (strcmp(cmd, "help") == 0) { if (n > 0) { shellUsage(chp, "help"); continue; } chprintf(chp, "Commands: help "); list_commands(chp, shell_local_commands); if (scp != NULL) list_commands(chp, scp); chprintf(chp, SHELL_NEWLINE_STR); } else if (cmdexec(shell_local_commands, chp, cmd, n, args) && ((scp == NULL) || cmdexec(scp, chp, cmd, n, args))) { chprintf(chp, "%s", cmd); chprintf(chp, " ?"SHELL_NEWLINE_STR); } } } shellExit(MSG_OK); }