Beispiel #1
0
/* 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;
	}
}
Beispiel #2
0
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);
      }
    }
}