Index: Makefile =================================================================== --- Makefile (revision 278421) +++ Makefile (working copy) @@ -5,7 +5,7 @@ PROG= calendar SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \ - ostern.c paskha.c pom.c sunpos.c calcpp.c + ostern.c paskha.c pom.c sunpos.c LIBADD= m INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \ hr_HR.ISO8859-2 hu_HU.ISO8859-2 pt_BR.ISO8859-1 \ Index: calcpp.c =================================================================== --- calcpp.c (revision 278421) +++ calcpp.c (working copy) @@ -1,232 +0,0 @@ -/*- - * Copyright (c) 2013 Diane Bruce - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -/* calendar fake cpp does a very limited cpp version */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "pathnames.h" -#include "calendar.h" - -#define MAXFPSTACK 50 -static FILE *fpstack[MAXFPSTACK]; -static int curfpi; -static void pushfp(FILE *fp); -static FILE *popfp(void); -static int tokenscpp(char *buf, char *string); - -#define T_INVALID -1 -#define T_INCLUDE 0 -#define T_DEFINE 1 -#define T_IFNDEF 2 -#define T_ENDIF 3 - -#define MAXSYMS 100 -static char *symtable[MAXSYMS]; -static void addsym(const char *name); -static int findsym(const char *name); - -FILE * -fincludegets(char *buf, int size, FILE *fp) -{ - char name[MAXPATHLEN]; - FILE *nfp=NULL; - char *p; - int ch; - - if (fp == NULL) - return(NULL); - - if (fgets(buf, size, fp) == NULL) { - *buf = '\0'; - fclose(fp); - fp = popfp(); - return (fp); - } - if ((p = strchr(buf, '\n')) != NULL) - *p = '\0'; - else { - /* Flush this line */ - while ((ch = fgetc(fp)) != '\n' && ch != EOF); - if (ch == EOF) { - *buf = '\0'; - fclose(fp); - fp = popfp(); - return(fp); - } - } - switch (tokenscpp(buf, name)) { - case T_INCLUDE: - *buf = '\0'; - if ((nfp = fopen(name, "r")) != NULL) { - pushfp(fp); - fp = nfp; - } - break; - case T_DEFINE: - addsym(name); - break; - case T_IFNDEF: - if (findsym(name)) { - fclose(fp); - fp = popfp(); - *buf = '\0'; - } - break; - case T_ENDIF: - *buf = '\0'; - break; - default: - break; - } - return (fp); -} - -static int -tokenscpp(char *buf, char *string) -{ - char *p; - char *s; - - if ((p = strstr(buf, "#define")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - s = p; - while(!isspace((unsigned char)*p)) - p++; - strlcpy(string, s, MAXPATHLEN); - return(T_DEFINE); - } else if ((p = strstr(buf, "#ifndef")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - s = p; - while(!isspace((unsigned char)*p)) - p++; - *p = '\0'; - strncpy(string, s, MAXPATHLEN); - return(T_IFNDEF); - } else if ((p = strstr(buf, "#endif")) != NULL) { - return(T_ENDIF); - } if ((p = strstr(buf, "#include")) != NULL) { - p += 8; - while (isspace((unsigned char)*p)) - p++; - if (*p == '<') { - s = p+1; - if ((p = strchr(s, '>')) != NULL) - *p = '\0'; - if (*s != '/') - snprintf (string, MAXPATHLEN, "%s/%s", - _PATH_INCLUDE, s); - else - strncpy(string, s, MAXPATHLEN); - } else if (*p == '(') { - s = p+1; - if ((p = strchr(p, '>')) != NULL) - *p = '\0'; - snprintf (string, MAXPATHLEN, "%s", s); - } - return(T_INCLUDE); - } - return(T_INVALID); -} - -static void -pushfp(FILE *fp) -{ - curfpi++; - if (curfpi == MAXFPSTACK) - errx(1, "Max #include reached"); - fpstack[curfpi] = fp; -} - -static -FILE *popfp(void) -{ - FILE *tmp; - - assert(curfpi >= 0); - tmp = fpstack[curfpi]; - curfpi--; - return(tmp); -} - -void -initcpp(void) -{ - int i; - - for (i=0; i < MAXSYMS; i++) - symtable[i] = NULL; - fpstack[0] = NULL; - curfpi = 0; -} - - -static void -addsym(const char *name) -{ - int i; - - if (!findsym(name)) - for (i=0; i < MAXSYMS; i++) { - if (symtable[i] == NULL) { - symtable[i] = strdup(name); - if (symtable[i] == NULL) - errx(1, "malloc error in addsym"); - return; - } - } - errx(1, "symbol table full\n"); -} - -static int -findsym(const char *name) -{ - int i; - - for (i=0; i < MAXSYMS; i++) - if (symtable[i] != NULL && strcmp(symtable[i],name) == 0) - return (1); - return (0); -} Index: calendar.h =================================================================== --- calendar.h (revision 278421) +++ calendar.h (working copy) @@ -168,10 +168,6 @@ FILE *opencalin(void); FILE *opencalout(void); -/* calcpp.c */ -void initcpp(void); -FILE *fincludegets(char *buf, int size, FILE *fp); - /* ostern.c / paskha.c */ int paskha(int); int easter(int); Index: io.c =================================================================== --- io.c (revision 278421) +++ io.c (working copy) @@ -51,14 +51,23 @@ #include #include #include +#include +#define _WITH_GETLINE #include #include #include +#include #include #include "pathnames.h" #include "calendar.h" +enum { + T_OK = 0, + T_ERR, + T_PROCESS, +}; + const char *calendarFile = "calendar"; /* default calendar file */ static const char *calendarHomes[] = {".calendar", _PATH_INCLUDE}; /* HOME */ static const char *calendarNoMail = "nomail";/* don't sent mail if file exist */ @@ -68,6 +77,147 @@ struct fixs neaster, npaskha, ncny, nfullmoon, nnewmoon; struct fixs nmarequinox, nsepequinox, njunsolstice, ndecsolstice; +static int cal_parse(FILE *in, FILE *out); + +static StringList *definitions = NULL; +static struct event *events[MAXCOUNT]; +static char *extradata[MAXCOUNT]; + +static void +trimlr(char **buf) +{ + char *walk = *buf; + + while (isspace(*walk)) + walk++; + while (isspace(walk[strlen(walk) -1])) + walk[strlen(walk) -1] = '\0'; + + *buf = walk; +} + +static FILE * +cal_fopen(const char *file) +{ + FILE *fp; + char *home = getenv("HOME"); + unsigned int i; + + if (home == NULL || *home == '\0') { + warnx("Cannot get home directory"); + return (NULL); + } + + if (chdir(home) != 0) { + warnx("Cannot enter home directory"); + return (NULL); + } + + for (i = 0; i < sizeof(calendarHomes) / sizeof(calendarHomes[0]) ; i++) { + if (chdir(calendarHomes[i]) != 0) + continue; + + if ((fp = fopen(file, "r")) != NULL) + return (fp); + } + + warnx("can't open calendar file \"%s\"", file); + + return (NULL); +} + +static int +token(char *line, FILE *out, bool *skip) +{ + char *walk, c, a; + + if (strncmp(line, "endif", 5) == 0) { + *skip = false; + return (T_OK); + } + + if (*skip) + return (T_OK); + + if (strncmp(line, "include", 7) == 0) { + walk = line + 7; + + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #include"); + return (T_ERR); + } + + if (*walk != '<' && *walk != '\"') { + warnx("Excecting '<' or '\"' after #include"); + return (T_ERR); + } + + a = *walk; + walk++; + c = walk[strlen(walk) - 1]; + + switch(c) { + case '>': + if (a != '<') { + warnx("Unterminated include expecting '\"'"); + return (T_ERR); + } + break; + case '\"': + if (a != '\"') { + warnx("Unterminated include expecting '>'"); + return (T_ERR); + } + break; + default: + warnx("Unterminated include expecting '%c'", + a == '<' ? '>' : '\"' ); + return (T_ERR); + } + walk[strlen(walk) - 1] = '\0'; + + if (cal_parse(cal_fopen(walk), out)) + return (T_ERR); + + return (T_OK); + } + + if (strncmp(line, "define", 6) == 0) { + if (definitions == NULL) + definitions = sl_init(); + walk = line + 6; + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #define"); + return (T_ERR); + } + + sl_add(definitions, strdup(walk)); + return (T_OK); + } + + if (strncmp(line, "ifndef", 6) == 0) { + walk = line + 6; + trimlr(&walk); + + if (*walk == '\0') { + warnx("Expecting arguments after #ifndef"); + return (T_ERR); + } + + if (definitions != NULL && sl_find(definitions, walk) != NULL) + *skip = true; + + return (T_OK); + } + + return (T_PROCESS); + +} + #define REPLACE(string, slen, struct_) \ if (strncasecmp(buf, (string), (slen)) == 0 && buf[(slen)]) { \ if (struct_.name != NULL) \ @@ -77,31 +227,26 @@ struct_.len = strlen(buf + (slen)); \ continue; \ } -void -cal(void) +static int +cal_parse(FILE *in, FILE *out) { - char *pp, p; - FILE *fpin; - FILE *fpout; - int l; - int count, i; + char *line = NULL; + char *buf; + size_t linecap = 0; + ssize_t linelen; + ssize_t l; + static int d_first = -1; + static int count = 0; + int i; int month[MAXCOUNT]; int day[MAXCOUNT]; int year[MAXCOUNT]; - char **extradata; /* strings of 20 length */ + bool skip = false; + char dbuf[80]; + char *pp, p; + struct tm tm; int flags; - static int d_first = -1; - char buf[2048 + 1]; - struct event *events[MAXCOUNT]; - struct tm tm; - char dbuf[80]; - initcpp(); - extradata = (char **)calloc(MAXCOUNT, sizeof(char *)); - for (i = 0; i < MAXCOUNT; i++) { - extradata[i] = (char *)calloc(1, 20); - } - /* Unused */ tm.tm_sec = 0; tm.tm_min = 0; @@ -108,20 +253,32 @@ tm.tm_hour = 0; tm.tm_wday = 0; - count = 0; - if ((fpin = opencalin()) == NULL) { - free(extradata); - return; - } - if ((fpout = opencalout()) == NULL) { - fclose(fpin); - free(extradata); - return; - } - while ((fpin = fincludegets(buf, sizeof(buf), fpin)) != NULL) { - if (*buf == '\0') + if (in == NULL) + return (1); + + while ((linelen = getline(&line, &linecap, in)) > 0) { + if (linelen == 0) continue; - for (l = strlen(buf); + + if (*line == '#') { + switch (token(line+1, out, &skip)) { + case T_ERR: + free(line); + return (1); + case T_OK: + continue; + case T_PROCESS: + break; + default: + break; + } + } + + if (skip) + continue; + + buf = line; + for (l = linelen; l > 0 && isspace((unsigned char)buf[l - 1]); l--) ; @@ -208,16 +365,41 @@ } } + free(line); + fclose(in); + + return (0); +} + +void +cal(void) +{ + FILE *fpin; + FILE *fpout; + int i; + + for (i = 0; i < MAXCOUNT; i++) + extradata[i] = (char *)calloc(1, 20); + + + if ((fpin = opencalin()) == NULL) + return; + + if ((fpout = opencalout()) == NULL) { + fclose(fpin); + return; + } + + if (cal_parse(fpin, fpout)) + return; + event_print_all(fpout); closecal(fpout); - free(extradata); } FILE * opencalin(void) { - size_t i; - int found; struct stat sbuf; FILE *fpin; @@ -231,22 +413,7 @@ if ((fpin = fopen(calendarFile, "r")) == NULL) return (NULL); } else { - char *home = getenv("HOME"); - if (home == NULL || *home == '\0') - errx(1, "cannot get home directory"); - if (chdir(home) != 0) - errx(1, "cannot enter home directory"); - for (found = i = 0; i < sizeof(calendarHomes) / - sizeof(calendarHomes[0]); i++) - if (chdir(calendarHomes[i]) == 0 && - (fpin = fopen(calendarFile, "r")) != NULL) { - found = 1; - break; - } - if (!found) - errx(1, - "can't open calendar file \"%s\": %s (%d)", - calendarFile, strerror(errno), errno); + fpin = cal_fopen(calendarFile); } } return (fpin);