static char *parse_decoline(char *p)
{
	struct SYMBOL *is;
	unsigned char t;
	int n;

	if ((is = deco_cont) == NULL)
		is = deco_start;
	else
		deco_cont = NULL;

	/* scan the decoration line */
	while (*p != '\0') {
		while (isspace((unsigned char) *p))
			p++;
		if (*p == '\0')
			break;
		switch (*p) {
		case '|':
			while (is && (is->abc_type != ABC_T_BAR
					|| is->u.bar.type == B_OBRA))
				is = is->abc_next;
			if (!is) {
				syntax("Not enough bar lines for deco line", p);
				return NULL;
			}
			is = is->abc_next;
			p++;
			continue;
		case '*':
			while (is && is->abc_type != ABC_T_NOTE)
				is = is->abc_next;
			if (!is) {
				syntax("Not enough notes for deco line", p);
				return NULL;
			}
			is = is->abc_next;
			p++;
			continue;
		case '\\':
			if (p[1] == '\0') {
				if (!is)
					return "Not enough notes for deco line";
				deco_cont = is;
				return NULL;
			}
			syntax("'\\' ignored", p);
			p++;
			continue;
		case '"':
			p = parse_gchord(p + 1);
			break;
		default:
			if (char_tb[(unsigned char) *p] == CHAR_DECOS)
				p = get_deco(p + 1, &t);
			else
				t = (unsigned char) *p++;
			break;
		}

		/* store the decoration and gchord/annotation in the next note */
		while (is && (is->abc_type != ABC_T_NOTE
				|| (is->flags & ABC_F_GRACE)))
			is = is->abc_next;
		if (!is)
			return "Not enough notes for deco line";

		if (gchord) {
			if (is->text) {
				char *gch;

				n = strlen(is->text);
				gch = getarena(n + strlen(gchord) + 2);
				strcpy(gch, is->text);
				gch[n] = '\n';
				strcpy(gch + n + 1, gchord);
				gchord = gch;
			}
			is->text = gchord;
			gchord = NULL;
		} else {
			n = is->u.note.dc.n;
			if (n >= MAXDC) {
				syntax("Too many decorations for the note", p);
			} else if (t != 0) {
				is->u.note.dc.tm[n].t = t;
				is->u.note.dc.tm[n].m = -1;
				is->u.note.dc.n = ++n;
			}
		}
		is = is->abc_next;
	}
	return NULL;
}
static char *parse_decoline(char *p)
{
	struct SYMBOL *is;
	unsigned char t;
	int n;

	if ((is = deco_cont) == NULL)
		is = deco_start;
	else
		deco_cont = NULL;

	 
	while (*p != '\0') {
		while (isspace((unsigned char) *p))
			p++;
		if (*p == '\0')
			break;
		switch (*p) {
		case '|':
			while (is && (is->abc_type != ABC_T_BAR
					|| is->u.bar.type == B_OBRA))
				is = is->abc_next;
			if (!is) {
				syntax("Not enough bar lines for deco line", p);
				return NULL;
			}
			is = is->abc_next;
			p++;
			continue;
		case '*':
			while (is && is->abc_type != ABC_T_NOTE)
				is = is->abc_next;
			if (!is) {
				syntax("Not enough notes for deco line", p);
				return NULL;
			}
			is = is->abc_next;
			p++;
			continue;
		case '\\':
			if (p[1] == '\0') {
				if (!is)
					return "Not enough notes for deco line";
				deco_cont = is;
				return NULL;
			}
			syntax("'\\' ignored", p);
			p++;
			continue;
		case '"':
			p = parse_gchord(p + 1);
			break;
		default:
			if (char_tb[(unsigned char) *p] == CHAR_DECOS)
				p = get_deco(p + 1, &t);
			else
				t = (unsigned char) *p++;
			break;
		}

		 
		while (is && (is->abc_type != ABC_T_NOTE
				|| (is->flags & ABC_F_GRACE)))
			is = is->abc_next;
		if (!is)
			return "Not enough notes for deco line";

		if (gchord) {
			if (is->text) {
				char *gch;

				n = strlen(is->text);
				gch = getarena(n + strlen(gchord) + 2);
				strcpy(gch, is->text);
				gch[n] = '\n';
				strcpy(gch + n + 1, gchord);
				gchord = gch;
			}
			is->text = gchord;
			gchord = NULL;
		} else {
			n = is->u.note.dc.n;
			if (n >= MAXDC) {
				syntax("Too many decorations for the note", p);
			} else if (t != 0) {
				is->u.note.dc.tm[n].t = t;
				is->u.note.dc.tm[n].m = -1;
				is->u.note.dc.n = ++n;
			}
		}
		is = is->abc_next;
	}
	return NULL;
}