void parser_t::dippins() { pstring_list_t pins; pins.add(get_identifier()); require_token(m_tok_comma); while (true) { pstring t1 = get_identifier(); pins.add(t1); token_t n = get_token(); if (n.is(m_tok_param_right)) break; if (!n.is(m_tok_comma)) error(pfmt("expected a comma, found <{1}>")(n.str()) ); } if ((pins.size() % 2) == 1) error("You must pass an equal number of pins to DIPPINS"); unsigned n = pins.size(); for (unsigned i = 0; i < n / 2; i++) { m_setup.register_alias(pfmt("{1}")(i+1), pins[i*2]); m_setup.register_alias(pfmt("{1}")(n-i), pins[i*2 + 1]); } }
void addenv(var *v) { char envname[Maxenvname]; word *w; int f; io *fd; if(v->changed){ v->changed = 0; snprint(envname, sizeof envname, "/env/%s", v->name); if((f = Creat(envname))<0) pfmt(err, "rc: can't open %s: %r\n", envname); else{ for(w = v->val;w;w = w->next) write(f, w->word, strlen(w->word)+1L); close(f); } } if(v->fnchanged){ v->fnchanged = 0; snprint(envname, sizeof envname, "/env/fn#%s", v->name); if((f = Creat(envname))<0) pfmt(err, "rc: can't open %s: %r\n", envname); else{ if(v->fn){ fd = openfd(f); pfmt(fd, "fn %q %s\n", v->name, v->fn[v->pc-1].s); closeio(fd); } close(f); } } }
void panic(char *s, int n) { pfmt(err, "rc: "); pfmt(err, s, n); pchr(err, '\n'); flush(err); Abort(); }
void Xsimple(void) { word *a; thread *p = runq; var *v; struct builtin *bp; int pid; globlist(); a = runq->argv->words; if(a==0){ Xerror1("empty argument list"); return; } if(flag['x']) pfmt(err, "%v\n", p->argv->words); /* wrong, should do redirs */ v = gvlook(a->word); if(v->fn) execfunc(v); else{ if(strcmp(a->word, "builtin")==0){ if(count(a)==1){ pfmt(err, "builtin: empty argument list\n"); setstatus("empty arg list"); poplist(); return; } a = a->next; popword(); } for(bp = Builtin;bp->name;bp++) if(strcmp(a->word, bp->name)==0){ (*bp->fnc)(); return; } if(exitnext()){ /* fork and wait is redundant */ pushword("exec"); execexec(); Xexit(); } else{ flush(err); Updenv(); /* necessary so changes don't go out again */ if((pid = execforkexec()) < 0){ Xerror("try again"); return; } /* interrupts don't get us out */ poplist(); while(Waitfor(pid, 1) < 0) ; } } }
static void bcheck2(int n, int c1, int c2) { if (n == 1) pfmt(stderr, MM_ERROR, ":21:Missing %c\n", c2); else if (n > 1) pfmt(stderr, MM_ERROR, ":22:%d missing %c's\n", n, c2); else if (n == -1) pfmt(stderr, MM_ERROR, ":23:Extra %c\n", c2); else if (n < -1) pfmt(stderr, MM_ERROR, ":24:%d extra %c's\n", -n, c2); }
void Xerror1(char *s) { if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0) pfmt(err, "rc: %s\n", s); else pfmt(err, "rc (%s): %s\n", argv0, s); flush(err); setstatus("error"); while(!runq->iflag) Xreturn(); }
double ptokenizer::get_number_double() { token_t tok = get_token(); if (!tok.is_type(NUMBER)) { error(pfmt("Expected a number, got <{1}>")(tok.str()) ); } bool err = false; double ret = tok.str().as_double(&err); if (err) error(pfmt("Expected a number, got <{1}>")(tok.str()) ); return ret; }
// FIXME: combine into template double ptokenizer::get_number_double() { token_t tok = get_token(); if (!tok.is_type(NUMBER)) { error(pfmt("Expected a number, got <{1}>")(tok.str()) ); } bool err; double ret = plib::pstonum_ne<double>(tok.str(), err); if (err) error(pfmt("Expected a number, got <{1}>")(tok.str()) ); return ret; }
long ptokenizer::get_number_long() { token_t tok = get_token(); if (!tok.is_type(NUMBER)) { error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); } bool err; long ret = plib::pstonum_ne<long>(tok.str(), err); if (err) error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); return ret; }
long ptokenizer::get_number_long() { token_t tok = get_token(); if (!tok.is_type(NUMBER)) { error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); } bool err = false; long ret = tok.str().as_long(&err); if (err) error(pfmt("Expected a long int, got <{1}>")(tok.str()) ); return ret; }
void execnewpgrp(void) { int arg; char *s; switch(count(runq->argv->words)){ case 1: arg = RFENVG|RFNAMEG|RFNOTEG; break; case 2: arg = 0; for(s = runq->argv->words->next->word;*s;s++) switch(*s){ default: goto Usage; case 'n': arg|=RFNAMEG; break; case 'N': arg|=RFCNAMEG; break; case 'm': arg|=RFNOMNT; break; case 'e': arg|=RFENVG; break; case 'E': arg|=RFCENVG; break; case 's': arg|=RFNOTEG; break; case 'f': arg|=RFFDG; break; case 'F': arg|=RFCFDG; break; } break; default: Usage: pfmt(err, "Usage: %s [fnesFNEm]\n", runq->argv->words->word); setstatus("rfork usage"); poplist(); return; } if(rfork(arg)==-1){ pfmt(err, "rc: %s failed\n", runq->argv->words->word); setstatus("rfork failed"); } else setstatus(""); poplist(); }
void Xwrite(void) { char *file; int f; switch(count(runq->argv->words)){ default: Xerror1("> requires singleton\n"); return; case 0: Xerror1("> requires file\n"); return; case 1: break; } file = runq->argv->words->word; if((f = Creat(file))<0){ pfmt(err, "%s: ", file); Xerror("can't open"); return; } pushredir(ROPEN, f, runq->code[runq->pc].i); runq->pc++; poplist(); }
void execshift(void) { int n; word *a; var *star; switch(count(runq->argv->words)){ default: pfmt(err, "Usage: shift [n]\n"); setstatus("shift usage"); poplist(); return; case 2: n = atoi(runq->argv->words->next->word); break; case 1: n = 1; break; } star = vlook("*"); for(;n && star->val;--n){ a = star->val->next; efree(star->val->word); efree((char *)star->val); star->val = a; star->changed = 1; } setstatus(""); poplist(); }
void yyerror(char *s) { extern unsigned char /**cmdname,*/ *curfname; static int been_here = 0; if (been_here++ > 2) return; pfmt(stderr, (MM_ERROR | MM_NOGET), "%s", s); pfmt(stderr, MM_NOSTD, atline, lineno); if (curfname != NULL) pfmt(stderr, MM_NOSTD, infunc, curfname); fprintf(stderr, "\n"); errorflag = 2; eprint(); }
void Abort(void) { pfmt(err, "aborting\n"); flush(err); Exit("aborting"); }
/* * Initialise threading. */ static void init_uts(struct uts_data *data, struct uts_runq *q) { struct kse_thr_mailbox *tm; int mib[2]; char *p; #if 0 size_t len; #endif /* * Create initial thread. */ tm = (struct kse_thr_mailbox *)calloc(1, sizeof(struct kse_thr_mailbox)); /* Throw us into its context. */ getcontext(&tm->tm_context); /* Find our stack. */ mib[0] = CTL_KERN; mib[1] = KERN_USRSTACK; #if 0 len = sizeof(p); if (sysctl(mib, 2, &p, &len, NULL, 0) == -1) pstr("sysctl(CTL_KER.KERN_USRSTACK) failed.\n"); #endif p = (char *)malloc(MAIN_STACK_SIZE) + MAIN_STACK_SIZE; pfmt("main() : 0x%x\n", tm); pfmt("eip -> 0x%x\n", tm->tm_context.uc_mcontext.mc_eip); tm->tm_context.uc_stack.ss_sp = p - MAIN_STACK_SIZE; tm->tm_context.uc_stack.ss_size = MAIN_STACK_SIZE; /* * Create KSE mailbox. */ p = (char *)malloc(THREAD_STACK_SIZE); bzero(&data->mb, sizeof(struct kse_mailbox)); data->mb.km_stack.ss_sp = p; data->mb.km_stack.ss_size = THREAD_STACK_SIZE; data->mb.km_func = (void *)uts; data->mb.km_udata = data; data->mb.km_quantum = 10000; data->cur_thread = tm; data->runq = q; pfmt("uts() at : 0x%x\n", uts); pfmt("uts stack at : 0x%x - 0x%x\n", p, p + THREAD_STACK_SIZE); }
void efree(void *p) { /* pfmt(err, "free %p\n", p); flush(err); /**/ if(p) free(p); else pfmt(err, "free 0\n"); }
void execcd(void) { word *a = runq->argv->words; word *cdpath; char dir[512]; setstatus("can't cd"); cdpath = vlook("cdpath")->val; switch(count(a)){ default: pfmt(err, "Usage: cd [directory]\n"); break; case 2: if(a->next->word[0]=='/' || cdpath==0) cdpath=&nullpath; for(;cdpath;cdpath = cdpath->next){ strcpy(dir, cdpath->word); if(dir[0]) strcat(dir, "/"); strcat(dir, a->next->word); if(dochdir(dir)>=0){ if(strlen(cdpath->word) && strcmp(cdpath->word, ".")!=0) pfmt(err, "%s\n", dir); setstatus(""); break; } } if(cdpath==0) pfmt(err, "Can't cd %s: %r\n", a->next->word); break; case 1: a = vlook("home")->val; if(count(a)>=1){ if(dochdir(a->word)>=0) setstatus(""); else pfmt(err, "Can't cd %s: %r\n", a->word); } else pfmt(err, "Can't cd -- $home empty\n"); break; } poplist(); }
static void start_uts(struct uts_data *data, int newgrp) { /* * Start KSE scheduling. */ pfmt("kse_create() -> %d\n", kse_create(&data->mb, newgrp)); data->mb.km_curthread = data->cur_thread; }
pstring ptokenizer::get_string() { token_t tok = get_token(); if (!tok.is_type(STRING)) { error(pfmt("Expected a string, got <{1}>")(tok.str()) ); } return tok.str(); }
pstring ptokenizer::get_identifier() { token_t tok = get_token(); if (!tok.is_type(IDENTIFIER)) { error(pfmt("Expected an identifier, got <{1}>")(tok.str()) ); } return tok.str(); }
void pquo(Io *f, char *s) { pchr(f, '\''); for(;*s;s++) if(*s=='\'') pfmt(f, "''"); else pchr(f, *s); pchr(f, '\''); }
static void eprint(void) /* try to print context around error */ { unsigned char *p, *q, *r; int c, episnul; static int been_here = 0; extern unsigned char ebuf[300], *ep; if (compile_time == 2 || compile_time == 0 || been_here++ > 0) return; episnul = ep > ebuf && ep[-1] == '\0'; p = ep - 1 - episnul; if (p > ebuf && *p == '\n') p--; for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--) ; while (*p == '\n') p++; if (0 /* posix */) pfmt(stderr, MM_INFO, ":28:Context is\n\t"); else pfmt(stderr, MM_INFO|MM_NOSTD, ":2228: context is\n\t"); for (q=ep-1-episnul; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ; for (r = q; r < ep; r++) { if (*r != ' ' && *r != '\t' && *r != '\n') { for ( ; p < q; p++) if (*p) putc(*p, stderr); break; } } fprintf(stderr, " >>> "); for ( ; p < ep; p++) if (*p) putc(*p, stderr); fprintf(stderr, " <<< "); if (*ep) while ((c = awk_input()) != '\n' && c != '\0' && c != EOF) { putc(c, stderr); bclass(c); } putc('\n', stderr); ep = ebuf; }
void vyyerror(const char *msg, ...) { extern unsigned char *curfname; va_list args; if (been_here++ > 2) return; va_start(args, msg); vpfmt(stderr, MM_ERROR, msg, args); pfmt(stderr, MM_NOSTD, atline, lineno); if (curfname != NULL) pfmt(stderr, MM_NOSTD, infunc, curfname); fprintf(stderr, "\n"); errorflag = 2; eprint(); va_end(args); }
void pfnc(io *fd, thread *t) { int i; void (*fn)(void) = t->code[t->pc].f; list *a; pfmt(fd, "pid %d cycle %p %d ", getpid(), t->code, t->pc); for (i = 0; fname[i].f; i++) if (fname[i].f == fn) { pstr(fd, fname[i].name); break; } if (!fname[i].f) pfmt(fd, "%p", fn); for (a = t->argv; a; a = a->next) pfmt(fd, " (%v)", a->words); pchr(fd, '\n'); flush(fd); }
void execexit(void) { switch(count(runq->argv->words)){ default: pfmt(err, "Usage: exit [status]\nExiting anyway\n"); case 2: setstatus(runq->argv->words->next->word); case 1: Xexit(); } }
void ptokenizer::require_token(const token_t tok, const token_id_t &token_num) { if (!tok.is(token_num)) { pstring val(""); for (auto &i : m_tokens) if (i.second.id() == token_num.id()) val = i.first; error(pfmt("Expected token <{1}> got <{2}>")(val)(tok.str()) ); } }
void Vinit(void) { int dir, f, len, i, n, nent; char *buf, *s; char envname[Maxenvname]; word *val; Dir *ent; dir = open("/env", OREAD); if(dir<0){ pfmt(err, "rc: can't open /env: %r\n"); return; } ent = nil; for(;;){ nent = dirread(dir, &ent); if(nent <= 0) break; for(i = 0; i<nent; i++){ len = ent[i].length; if(len && strncmp(ent[i].name, "fn#", 3)!=0){ snprint(envname, sizeof envname, "/env/%s", ent[i].name); if((f = open(envname, 0))>=0){ buf = emalloc(len+1); n = readn(f, buf, len); if (n <= 0) buf[0] = '\0'; else buf[n] = '\0'; val = 0; /* Charitably add a 0 at the end if need be */ if(buf[len-1]) buf[len++]='\0'; s = buf+len-1; for(;;){ while(s!=buf && s[-1]!='\0') --s; val = newword(s, val); if(s==buf) break; --s; } setvar(ent[i].name, val); vlook(ent[i].name)->changed = 0; close(f); efree(buf); } } } free(ent); } close(dir); }
const pstring nl_convert_base_t::get_nl_val(const double val) { { int i = 0; while (m_units[i].m_unit != "-" ) { if (m_units[i].m_mult <= std::abs(val)) break; i++; } return pfmt(m_units[i].m_func.cstr())(val / m_units[i].m_mult); } }
void notifyf(void* v, char *s) { int i; for(i = 0;syssigname[i];i++) if(strncmp(s, syssigname[i], strlen(syssigname[i]))==0){ if(strncmp(s, "sys: ", 5)!=0) interrupted = 1; goto Out; } pfmt(err, "rc: note: %s\n", s); noted(NDFLT); return; Out: if(strcmp(s, "interrupt")!=0 || trap[i]==0){ trap[i]++; ntrap++; } if(ntrap>=32){ /* rc is probably in a trap loop */ pfmt(err, "rc: Too many traps (trap %s), aborting\n", s); abort(); } noted(NCONT); }