free(ev1->ldesc); if (asprintf(&ev1->ldesc, "%s\n%s", ev1->ldesc,
if (asprintf(&p, "%s\n%s", ev1->ldesc,
cal(void){	int ch, l, i, bodun = 0, bodun_maybe = 0, var, printing;	struct event *events, *cur_evt, *ev1, *tmp;	char buf[2048 + 1], *prefix = NULL, *p;	struct match *m;	size_t nlen;	FILE *fp;	events = NULL;	cur_evt = NULL;	if ((fp = opencal()) == NULL)		return;	for (printing = 0; fgets(buf, sizeof(buf), stdin) != NULL;) {		if ((p = strchr(buf, '\n')) != NULL)			*p = '\0';		else			while ((ch = getchar()) != '\n' && ch != EOF);		for (l = strlen(buf); l > 0 && isspace(buf[l - 1]); l--)			;		buf[l] = '\0';		if (buf[0] == '\0')			continue;		if (strncmp(buf, "LANG=", 5) == 0) {			(void) setlocale(LC_ALL, buf + 5);			setnnames();			if (!strcmp(buf + 5, "ru_RU.KOI8-R") ||			    !strcmp(buf + 5, "uk_UA.KOI8-U") ||			    !strcmp(buf + 5, "by_BY.KOI8-B")) {				bodun_maybe++;				bodun = 0;				if (prefix)					free(prefix);				prefix = NULL;			} else				bodun_maybe = 0;			continue;		} else if (strncmp(buf, "CALENDAR=", 9) == 0) {			char *ep;			if (buf[9] == '\0')				calendar = 0;			else if (!strcasecmp(buf + 9, "julian")) {				calendar = JULIAN;				errno = 0;				julian = strtoul(buf + 14, &ep, 10);				if (buf[0] == '\0' || *ep != '\0')					julian = 13;				if ((errno == ERANGE && julian == ULONG_MAX) ||				    julian > 14)					errx(1, "Julian calendar offset is too large");			} else if (!strcasecmp(buf + 9, "gregorian"))				calendar = GREGORIAN;			else if (!strcasecmp(buf + 9, "lunar"))				calendar = LUNAR;		} else if (bodun_maybe && strncmp(buf, "BODUN=", 6) == 0) {			bodun++;			if (prefix)				free(prefix);			if ((prefix = strdup(buf + 6)) == NULL)				err(1, NULL);			continue;		}		/* User defined names for special events */		if ((p = strchr(buf, '='))) {			for (i = 0; i < NUMEV; i++) {				if (strncasecmp(buf, spev[i].name,				    spev[i].nlen) == 0 &&				    (p - buf == spev[i].nlen) &&				    buf[spev[i].nlen + 1]) {					p++;					if (spev[i].uname != NULL)						free(spev[i].uname);					if ((spev[i].uname = strdup(p)) == NULL)						err(1, NULL);					spev[i].ulen = strlen(p);					i = NUMEV + 1;				}			}			if (i > NUMEV)				continue;		}		if (buf[0] != '\t') {			printing = (m = isnow(buf, bodun)) ? 1 : 0;			if ((p = strchr(buf, '\t')) == NULL) {				printing = 0;				continue;			}			/* Need the following to catch hardwired "variable"			 * dates */			if (p > buf && p[-1] == '*')				var = 1;			else				var = 0;			if (printing) {				struct match *foo;								ev1 = NULL;				while (m) {					cur_evt = malloc(sizeof(struct event));					if (cur_evt == NULL)						err(1, NULL);						cur_evt->when = m->when;					snprintf(cur_evt->print_date,					    sizeof(cur_evt->print_date), "%s%c",					    m->print_date, (var + m->var) ? '*' : ' ');					if (ev1) {						cur_evt->desc = ev1->desc;						cur_evt->ldesc = NULL;					} else {						if (m->bodun && prefix) {							if (asprintf(&cur_evt->ldesc,							    "\t%s %s", prefix,							    p + 1) == -1)								err(1, NULL);						} else if ((cur_evt->ldesc =						    strdup(p)) == NULL)							err(1, NULL);						cur_evt->desc = &(cur_evt->ldesc);						ev1 = cur_evt;					}					insert(&events, cur_evt);					foo = m;					m = m->next;					free(foo);				}			}		} else if (printing) {			free(ev1->ldesc);			if (asprintf(&ev1->ldesc, "%s\n%s", ev1->ldesc,			    buf) == -1)				err(1, NULL);				}	}	tmp = events;	while (tmp) {		(void)fprintf(fp, "%s%s\n", tmp->print_date, *(tmp->desc));		tmp = tmp->next;	}	tmp = events;	while (tmp) {		events = tmp;		if (tmp->ldesc)			free(tmp->ldesc);		tmp = tmp->next;		free(events);	}	closecal(fp);}