void db_def_macro_cmd(void) { register char *p; register int c; register struct db_user_macro *mp, *ep; if (db_read_token() != tIDENT) { db_printf("Bad macro name \"%s\"\n", db_tok_string); db_error(0); /* NOTREACHED */ } if ((mp = db_lookup_macro(db_tok_string)) == 0) { if (db_macro_free <= 0) db_error("Too many macros\n"); /* NOTREACHED */ ep = &db_user_macro[DB_NUSER_MACRO]; for (mp = db_user_macro; mp < ep && mp->m_name[0]; mp++); if (mp >= ep) db_error("ddb: internal error(macro)\n"); /* NOTREACHED */ db_macro_free--; strlcpy(mp->m_name, db_tok_string, TOK_STRING_SIZE); } for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); for (p = mp->m_lbuf; c > 0; c = db_read_char()) *p++ = c; *p = 0; mp->m_size = p - mp->m_lbuf; }
void db_cond_cmd(void) { register int c; register struct db_cond *cp; register char *p; db_expr_t value; db_thread_breakpoint_t bkpt; if (db_read_token() != tHASH || db_read_token() != tNUMBER) { db_printf("#<number> expected instead of \"%s\"\n", db_tok_string); db_error(0); return; } if ((bkpt = db_find_breakpoint_number(db_tok_number, 0)) == 0) { db_printf("No such break point #%d\n", db_tok_number); db_error(0); return; } /* * if the break point already has a condition, free it first */ if (bkpt->tb_cond > 0) { cp = &db_cond[bkpt->tb_cond - 1]; db_cond_free(bkpt); } else { if (db_ncond_free <= 0) { db_error("Too many conditions\n"); return; } for (cp = db_cond; cp < &db_cond[DB_MAX_COND]; cp++) if (cp->c_size == 0) break; if (cp >= &db_cond[DB_MAX_COND]) panic("bad db_cond_free"); } for (c = db_read_char(); c == ' ' || c == '\t'; c = db_read_char()); for (p = cp->c_cond_cmd; c >= 0; c = db_read_char()) *p++ = c; /* * switch to saved data and call db_expression to check the condition. * If no condition is supplied, db_expression will return false. * In this case, clear previous condition of the break point. * If condition is supplied, set the condition to the permanent area. * Note: db_expression will not return here, if the condition * expression is wrong. */ db_switch_input(cp->c_cond_cmd, p - cp->c_cond_cmd); if (!db_expression(&value)) { /* since condition is already freed, do nothing */ db_flush_lex(); return; } db_flush_lex(); db_ncond_free--; cp->c_size = p - cp->c_cond_cmd; bkpt->tb_cond = (cp - db_cond) + 1; }
int db_lex(void) { int c; c = db_read_char(); while (c <= ' ' || c > '~') { if (c == '\n' || c == -1) return (tEOL); c = db_read_char(); } if (c >= '0' && c <= '9') { /* number */ int r, digit = 0; if (c > '0') r = db_radix; else { c = db_read_char(); if (c == 'O' || c == 'o') r = 8; else if (c == 'T' || c == 't') r = 10; else if (c == 'X' || c == 'x') r = 16; else { r = db_radix; db_unread_char(c); } c = db_read_char(); } db_tok_number = 0; for (;;) { if (c >= '0' && c <= ((r == 8) ? '7' : '9')) digit = c - '0'; else if (r == 16 && ((c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'))) { if (c >= 'a') digit = c - 'a' + 10; else if (c >= 'A') digit = c - 'A' + 10; } else break; db_tok_number = db_tok_number * r + digit; c = db_read_char(); } if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c == '_')) { db_error("Bad character in number\n"); /*NOTREACHED*/ } db_unread_char(c); return (tNUMBER); } if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_' || c == '\\') { /* string */ char *cp; cp = db_tok_string; if (c == '\\') { c = db_read_char(); if (c == '\n' || c == -1) { db_error("Bad escape\n"); /*NOTREACHED*/ } } *cp++ = c; while (1) { c = db_read_char(); if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_' || c == '\\' || c == ':') { if (c == '\\') { c = db_read_char(); if (c == '\n' || c == -1) { db_error("Bad escape\n"); /*NOTREACHED*/ } } *cp++ = c; if (cp == db_tok_string+sizeof(db_tok_string)) { db_error("String too long\n"); /*NOTREACHED*/ } continue; } else { *cp = '\0'; break; } } db_unread_char(c); return (tIDENT); } switch (c) { case '+': return (tPLUS); case '-': return (tMINUS); case '.': c = db_read_char(); if (c == '.') return (tDOTDOT); db_unread_char(c); return (tDOT); case '*': return (tSTAR); case '/': return (tSLASH); case '=': return (tEQ); case '%': return (tPCT); case '#': return (tHASH); case '(': return (tLPAREN); case ')': return (tRPAREN); case ',': return (tCOMMA); case '"': return (tDITTO); case '$': return (tDOLLAR); case '!': return (tEXCL); case '<': c = db_read_char(); if (c == '<') return (tSHIFT_L); db_unread_char(c); break; case '>': c = db_read_char(); if (c == '>') return (tSHIFT_R); db_unread_char(c); break; case -1: return (tEOF); } db_printf("Bad character\n"); db_flush_lex(); return (tEOF); }