/* try to read a label and optionally store it in the list */ static void readlabel(const char **p, int store) { const char *c, *d, *pos, *dummy; int i, j; struct label *buf, *previous; for (d = *p; *d && *d != ';'; ++d); for (c = *p; !strchr (" \r\n\t", *c) && c < d; ++c); pos = strchr (*p, ':'); if (!pos || pos >= c) return; if (pos == *p) { eprintf ("`:' found without a label"); return; } if (!store) { *p = pos + 1; return; } c = pos + 1; dummy = *p; j = rd_label (&dummy, &i, &previous, sp, 0); if (i || j) { eprintf ("duplicate definition of label %s\n", *p); *p = c; return; } if (! (buf = malloc (sizeof (struct label) + c - *p))) { eprintf ("not enough memory to store label %s\n", *p); *p = c; return; } strncpy (buf->name, *p, c - *p - 1); buf->name[c - *p - 1] = 0; *p = c; buf->value = addr; //lastlabel = buf; if (previous) { buf->next = previous->next; } else { buf->next = NULL; } buf->prev = previous; buf->valid = 1; buf->busy = 0; buf->ref = NULL; if (buf->prev) { buf->prev->next = buf; } if (buf->next) { buf->next->prev = buf; } }
static int rd_value (const char **p, int *valid, int level, int *check, int print_errors) { int sign = 1, not = 0, base, v; const char *p0, *p1, *p2; if (verbose >= 6) fprintf (stderr, "%5d (0x%04x): Starting to read value (string=%s).\n", stack[sp].line, addr, *p); *p = delspc (*p); while (**p && strchr ("+-~", **p)) { if (**p == '-') sign = -sign; else if (**p == '~') not = ~not; (*p)++; *p = delspc (*p); } base = 10; /* Default base for suffixless numbers */ /* Check for parenthesis around full expression: not if no parenthesis */ if (**p != '(') *check = 0; switch (**p) { int exist, retval; char quote; int dummy_check; case '(': (*p)++; dummy_check = 0; retval = not ^ (sign * do_rd_expr (p, ')', valid, level, &dummy_check, print_errors)); ++*p; return retval; case '0': if ((*p)[1] == 'x') { (*p) += 2; return not ^ (sign * rd_number (p, NULL, 0x10)); } base = 8; /* If first digit it 0, assume octal unless suffix */ /* fall through */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': p0 = *p; rd_number (p, &p1, 36); /* Advance to end of numeric string */ p1--; /* Last character in numeric string */ switch (*p1) { case 'h': case 'H': base = 16; break; case 'b': case 'B': base = 2; break; case 'o': case 'O': case 'q': case 'Q': base = 8; break; case 'd': case 'D': base = 10; break; default: /* No suffix */ p1++; break; } v = rd_number (&p0, &p2, base); if (p1 != p2) { if (valid) *valid = 0; else if (print_errors) printerr (1, "invalid character in number: \'%c\'\n", *p2); } return not ^ (sign * v); case '$': ++*p; *p = delspc (*p); p0 = *p; v = rd_number (&p0, &p2, 0x10); if (p2 == *p) { v = baseaddr; } else *p = p2; return not ^ (sign * v); case '%': (*p)++; return not ^ (sign * rd_number (p, NULL, 2)); case '\'': case '"': quote = **p; ++*p; retval = not ^ (sign * rd_character (p, valid, print_errors)); if (**p != quote) { if (valid) *valid = 0; else if (print_errors) printerr (1, "missing closing quote (%c)\n", quote); return 0; } ++*p; return retval; case '@': return not ^ (sign * rd_otherbasenumber (p, valid, print_errors)); case '?': rd_label (p, &exist, NULL, level, 0); return not ^ (sign * exist); case '&': { ++*p; switch (**p) { case 'h': case 'H': base = 0x10; break; case 'o': case 'O': base = 010; break; case 'b': case 'B': base = 2; break; default: if (valid) *valid = 0; else if (print_errors) printerr (1, "invalid literal starting with &%c\n", **p); return 0; } ++*p; return not ^ (sign * rd_number (p, NULL, base)); } default: { int value; exist = 1; value = rd_label (p, valid ? &exist : NULL, NULL, level, print_errors); if (!exist) *valid = 0; return not ^ (sign * value); } } }