static char *parse_tempo(char *p,
			 struct SYMBOL *s)
{
	char c, str[80];
	int i, l, n, top, bot;

	/* string before */
	if (*p == '"') {
		p = get_str(str, p, sizeof str);
		s->u.tempo.str1 = getarena(strlen(str) + 1);
		strcpy(s->u.tempo.str1, str);
	}

	/* beat */
	if (*p == 'C' || *p == 'c'
	 || *p == 'L' || *p == 'l') {
		s->u.tempo.beats[0] = ulen;
		if (parse.abc_vers >= (2 << 16))
			syntax("Deprecated Q: value", p);
		p++;
		while (isspace((unsigned char) *p))
			p++;
		if (*p != '=')
			goto inval;
		c = '=';
		p--;
	} else if (isdigit((unsigned char) *p)) {
		if (strchr(p, '/') != NULL) {
			i = 0;
			while (isdigit((unsigned char) *p)) {
				if (sscanf(p, "%d/%d%n", &top, &bot, &n) != 2
				 || bot <= 0)
					goto inval;
				l = (BASE_LEN * top) / bot;
				if (l <= 0
				 || i >= sizeof s->u.tempo.beats
						/ sizeof s->u.tempo.beats[0])
					goto inval;
				s->u.tempo.beats[i++] = l;
				p += n;
				while (isspace((unsigned char) *p))
					p++;
			}
			c = *p;
			if (c != '=')
				goto inval;
		} else {
			s->u.tempo.beats[0] = ulen;
			if (parse.abc_vers >= (2 << 16))
				syntax("Deprecated Q: value", p);
			c = '=';
			p--;
		}
	} else {
		c = '\0';
	}

	/* tempo value */
	if (c == '=') {
		p++;
		if (strncmp(p, "ca. ", 4) == 0) {
			s->u.tempo.circa = 1;
			p += 4;
		}
		if (sscanf(p, "%d/%d%n", &top, &bot, &n) == 2) {
			if (bot <= 0)
				goto inval;
			l = (BASE_LEN * top) / bot;
			if (l <= 0)
				goto inval;
			s->u.tempo.new_beat = l;
		} else {
			if (sscanf(p, "%d%n", &top, &n) != 1)
				goto inval;
			s->u.tempo.tempo = top;
		}
		p += n;
		while (isspace((unsigned char) *p))
			p++;
	}

	/* string after */
	if (*p == '"') {
		p = get_str(str, p, sizeof str);
		s->u.tempo.str2 = getarena(strlen(str) + 1);
		strcpy(s->u.tempo.str2, str);
	}

	return 0;
inval:
	return "Invalid tempo";
}
static char *parse_tempo(char *p,
			 struct SYMBOL *s)
{
	char c, str[80];
	int i, l, n, top, bot;

	 
	if (*p == '"') {
		p = get_str(str, p, sizeof str);
		s->u.tempo.str1 = getarena(strlen(str) + 1);
		strcpy(s->u.tempo.str1, str);
	}

	 
	if (*p == 'C' || *p == 'c'
	 || *p == 'L' || *p == 'l') {
		s->u.tempo.beats[0] = ulen;
		if (parse.abc_vers >= (2 << 16))
			syntax("Deprecated Q: value", p);
		p++;
		while (isspace((unsigned char) *p))
			p++;
		if (*p != '=')
			goto inval;
		c = '=';
		p--;
	} else if (isdigit((unsigned char) *p)) {
		if (strchr(p, '/') != NULL) {
			i = 0;
			while (isdigit((unsigned char) *p)) {
				if (sscanf(p, "%d/%d%n", &top, &bot, &n) != 2
				 || bot <= 0)
					goto inval;
				l = (BASE_LEN * top) / bot;
				if (l <= 0
				 || i >= sizeof s->u.tempo.beats
						/ sizeof s->u.tempo.beats[0])
					goto inval;
				s->u.tempo.beats[i++] = l;
				p += n;
				while (isspace((unsigned char) *p))
					p++;
			}
			c = *p;
			if (c != '=')
				goto inval;
		} else {
			s->u.tempo.beats[0] = ulen;
			if (parse.abc_vers >= (2 << 16))
				syntax("Deprecated Q: value", p);
			c = '=';
			p--;
		}
	} else {
		c = '\0';
	}

	 
	if (c == '=') {
		p++;
		if (strncmp(p, "ca. ", 4) == 0) {
			s->u.tempo.circa = 1;
			p += 4;
		}
		if (sscanf(p, "%d/%d%n", &top, &bot, &n) == 2) {
			if (bot <= 0)
				goto inval;
			l = (BASE_LEN * top) / bot;
			if (l <= 0)
				goto inval;
			s->u.tempo.new_beat = l;
		} else {
			if (sscanf(p, "%d%n", &top, &n) != 1)
				goto inval;
			s->u.tempo.tempo = top;
		}
		p += n;
		while (isspace((unsigned char) *p))
			p++;
	}

	 
	if (*p == '"') {
		p = get_str(str, p, sizeof str);
		s->u.tempo.str2 = getarena(strlen(str) + 1);
		strcpy(s->u.tempo.str2, str);
	}

	return 0;
inval:
	return "Invalid tempo";
}