/* parse.c - parse a command line
 */

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "menucmd.h"

struct menu_command_s {			 /* menu command structure */
	char *name;			 /* full command name */
	menu_cmd_t func;		 /* command function */
	char nowprefix;			 /* 1 if can be prefixed with "NOW" */
	char subprefix;			 /* 1 if can be prefixed with "SUB" */
	char ifsuffix;			 /* 1 if can be suffixed with "IF" */
	char noskip;			 /* 1 if not skipped in !.IF */
};

struct menu_status_s menu_status_types[] = {
	{"ADD", MENU_STATUS_ADD, MENU_STATUS_READONLY},
	{"ANONYMOUS", MENU_STATUS_ANONYMOUS, 0},
	{"BARDELETE", MENU_STATUS_BARDELETE, MENU_STATUS_DELETE},
	{"BARINFO", MENU_STATUS_BARINFO, 0},
	{"BARMAIL", MENU_STATUS_BARMAIL, 0},
	{"BARPRINT", MENU_STATUS_BARPRINT, 0},
	{"BARSENDREPLY", MENU_STATUS_BARSENDRPLY, 0},
	{"CLEAR", MENU_STATUS_ADD, 0xFFFFFFFF},
	{"DELETE", MENU_STATUS_DELETE, MENU_STATUS_READONLY},
	{"EDIT", MENU_STATUS_EDIT, MENU_STATUS_READONLY},
	{"LOWPRIORITY", MENU_STATUS_LOWPRIORITY, 0},
	{"NOERRORS", MENU_STATUS_NOERRORS, 0},
	{"NOINDEX", MENU_STATUS_NOINDEX, 0},
	{"NOLAST", MENU_STATUS_NOLAST, 0},
	{"NOSCAN", MENU_STATUS_NOSCAN, 0},
	{"NOTIME", MENU_STATUS_NOTIME, 0},
	{"READONLY", MENU_STATUS_READONLY, MENU_STATUS_ADD |
	 MENU_STATUS_DELETE | MENU_STATUS_EDIT},
	{"XRATED", MENU_STATUS_XRATED, 0},
	{"HIDETITLE", MENU_STATUS_HIDETITLE, 0},
	{"BARLOG", MENU_STATUS_BARLOG, 0},
	{0, 0, 0}
};

char *menu_temp = 0;


/* Set up variables prior to menu command parsing.
 */
void menu_cmd_init(void)
{
	menu_f_skip = 0;
	menu_f_quit = 0;
	if (!menu_temp)
		menu_temp = malloc(1024);
}


/* Process the menu command starting at "buf", for menu "m", using "dfl" as
 * the default menu entry and "cur" as the current one.
 */
void menu_command(char *buf, menu_t * m, menuentry_t * dfl,
		  menuentry_t * cur)
{
	static struct menu_command_s menu_cmds[] = {
		{"COMMENTFILE", menu__commentfile, 0, 0, 1, 0},
		{"HEIGHT", 0, 0, 0, 1, 0},
		{"IF", menu__if, 0, 0, 0, 1},
		{"ELSE", menu__else, 0, 0, 0, 1},
		{"ENDIF", menu__endif, 0, 0, 0, 1},
		{"LINE", menu__line, 0, 0, 0, 0},
		{"LOG", menu__log, 1, 1, 1, 0},
		{"OPTIONS", 0, 0, 0, 1, 0},
		{"PATHNAME", menu__pathname, 0, 0, 1, 0},
		{"QUIT", menu__quit, 0, 0, 1, 0},
		{"SETENV", 0, 0, 0, 0, 0},
		{"STATUS", menu__status, 1, 1, 1, 0},
		{"TEXT", menu__text, 0, 0, 0, 0},
		{"TITLE", menu__title, 0, 0, 1, 0},
		{"VIEW", menu__view, 1, 0, 1, 0},
		{"VIEWALWAYS", menu__viewalways, 1, 0, 1, 0},
		{0, 0, 0, 0, 0, 0}
	};
	struct menu_cmddat_s dat;
	char *a;
	char *b;
	int j = -1;
	int i;

	if ((!buf) || (!m) || (!cur) || (!dfl) || (!isalpha(buf[0])))
		return;

	dat.menu = m;
	dat.cur = cur;
	dat.dfl = dfl;
	dat.nowprefix = 0;
	dat.subprefix = 0;
	dat.special = 0;

	a = strchr(buf, ' ');
	if (a) {
		a[0] = 0;
		a++;
	}
	dat.buf = a;

	if (strncasecmp("SUBSEQUENT", buf, strlen(buf)) == 0) {
		dat.subprefix = 1;
		buf = a;
		if (buf) {
			a = strchr(buf, ' ');
			if (a) {
				a[0] = 0;
				a++;
			}
			dat.buf = a;
		} else {
			buf = "OOPS";
		}
	}

	if (strncasecmp("NOW", buf, strlen(buf)) == 0) {
		dat.nowprefix = 1;
		buf = a;
		if (buf) {
			a = strchr(buf, ' ');
			if (a) {
				a[0] = 0;
				a++;
			}
			dat.buf = a;
		} else {
			buf = "OOPS";
		}
	}

	for (i = 0; (menu_cmds[i].name != 0) && j < 0; i++) {
		if (strncasecmp(menu_cmds[i].name, buf, strlen(buf)) == 0)
			j = i;
	}

	if (j < 0) {			    /* unknown command */
		if (menu_addentry(m))
			return;
		m->menu[m->num_entries - 1].type = 't';
		m->menu[m->num_entries - 1].title =
		    strdup("\035CR\035BERROR:\035b unknown command\035CA");
		return;
	}

	if ((menu_f_skip) && (menu_cmds[j].noskip == 0))
		return;			    /* skip */

	if ((menu_cmds[j].ifsuffix) && (a)) {	/* do " IF ..." suffix */
		a = strstr(dat.buf, " IF ");
		if (!a)
			a = strstr(dat.buf, " if ");
		if (!a)
			a = strstr(dat.buf, " iF ");
		if (!a)
			a = strstr(dat.buf, " If ");
		if (!a)
			a = (strncasecmp(dat.buf, "IF ", 3) ==
			     0) ? dat.buf - 1 : 0;
		if (a) {
			b = dat.buf;
			dat.buf = a + 4;
			dat.special = 1;
			if (menu__if(&dat) == 0)
				return;
			a[0] = 0;
			dat.buf = b;
			dat.special = 0;
		}
	}

	if (menu_cmds[j].func)
		menu_cmds[j].func(&dat);
}

/* EOF */
