static int today_day_func(int do_set, Value *val) { int y, m, d; val->type = INT_TYPE; FromJulian(JulianToday, &y, &m, &d); val->v.val = d; return OK; }
static int trig_year_func(int do_set, Value *val) { int y, m, d; val->type = INT_TYPE; if (!LastTrigValid) { val->v.val = -1; return OK; } FromJulian(LastTriggerDate, &y, &m, &d); val->v.val = y; return OK; }
int MoonPhase(int date, int time) { int utcd, utct; int y, m, d; double jd, mp; /* Convert from local to UTC */ LocalToUTC(date, time, &utcd, &utct); /* Convert from Remind representation to year/mon/day */ FromJulian(utcd, &y, &m, &d); /* Convert to a true Julian date -- sorry for the name clashes! */ jd = jtime(y, m, d, (utct / 60), (utct % 60), 0); /* Calculate moon phase */ mp = 360.0 * phase(jd, NULL, NULL, NULL, NULL, NULL, NULL); return (int) mp; }
static void WriteSimpleEntries(int col, int jul) { CalEntry *e = CalColumn[col]; CalEntry *n; int y, m, d; FromJulian(jul, &y, &m, &d); while(e) { if (DoPrefixLineNo) printf("# fileinfo %d %s\n", e->lineno, e->filename); printf("%04d/%02d/%02d", y, m+1, d); if (e->passthru[0]) { printf(" %s", e->passthru); } else { printf(" *"); } if (*DBufValue(&(e->tags))) { printf(" %s ", DBufValue(&(e->tags))); } else { printf(" * "); } if (e->duration != NO_TIME) { printf("%d ", e->duration); } else { printf("* "); } if (e->time != NO_TIME) { printf("%d ", e->time); } else { printf("* "); } printf("%s\n", e->text); free((void *)e->text); free((void *)e->filename); #ifdef REM_USE_WCHAR if (e->wc_text) free((void *)e->wc_text); #endif n = e->next; free(e); e = n; } CalColumn[col] = NULL; }
static void WriteCalHeader(void) { char buf[80]; int y, m, d; FromJulian(JulianToday, &y, &m, &d); sprintf(buf, "%s %d", MonthName[m], y); WriteTopCalLine(); gon(); DRAW(tb); goff(); PrintCentered(buf, CalWidth-2, " "); gon(); DRAW(tb); goff(); PutChar('\n'); WritePostHeaderLine(); WriteCalDays(); WriteIntermediateCalLine(); }
void ProduceCalendar(void) { int y, m, d; if (UseUTF8Chars) { linestruct = &UTF8Drawing; } else if (UseVTChars) { linestruct = &VT100Drawing; } else { linestruct = &NormalDrawing; } ShouldCache = 1; ColSpaces = (CalWidth - 9) / 7; CalWidth = 7*ColSpaces + 8; if (CalMonths) { FromJulian(JulianToday, &y, &m, &d); JulianToday = Julian(y, m, 1); while (CalMonths--) DoCalendarOneMonth(); return; } else { if (MondayFirst) JulianToday -= (JulianToday%7); else JulianToday -= ((JulianToday+1)%7); if (!DoSimpleCalendar) { WriteWeekHeaderLine(); WriteCalDays(); WriteIntermediateCalLine(); } while (CalWeeks--) DoCalendarOneWeek(CalWeeks); return; } }
void HuntPhase(int startdate, int starttim, int phas, int *date, int *time) { int utcd, utct; int y, m, d; int h, min, s; int d1, t1; double k1, k2, jd, jdorig; double nt1, nt2; /* Convert from local to UTC */ LocalToUTC(startdate, starttim, &utcd, &utct); /* Convert from Remind representation to year/mon/day */ FromJulian(utcd, &y, &m, &d); /* Convert to a true Julian date -- sorry for the name clashes! */ jdorig = jtime(y, m, d, (utct / 60), (utct % 60), 0); jd = jdorig - 45.0; nt1 = meanphase(jd, 0.0, &k1); while(1) { jd += synmonth; nt2 = meanphase(jd, 0.0, &k2); if (nt1 <= jdorig && nt2 > jdorig) break; nt1 = nt2; k1 = k2; } jd = truephase(k1, phas/4.0); if (jd < jdorig) jd = truephase(k2, phas/4.0); /* Convert back to Remind format */ jyear(jd, &y, &m, &d); jhms(jd, &h, &min, &s); d1 = Julian(y, m, d); t1 = h*60 + min; UTCToLocal(d1, t1, date, time); }
static int NextSimpleTrig(int startdate, Trigger *trig, int *err) { int typ = 0; int d, m, y, j, d2, m2, y2; *err = 0; FromJulian(startdate, &y, &m, &d); d2 = d; m2 = m; y2 = y; if (trig->d != NO_DAY) typ |= GOT_DAY; if (trig->m != NO_MON) typ |= GOT_MON; if (trig->y != NO_YR) typ |= GOT_YR; if (trig->wd != NO_WD) typ |= GOT_WD; switch(typ) { case 0: case GOT_WD: if (trig->wd != NO_WD) while(! (trig->wd & (1 << (startdate%7)))) startdate++; return startdate; case GOT_DAY: if (d > trig->d) { m++; if (m == 12) { m = 0; y++; } } while (trig->d > DaysInMonth(m, trig->y)) m++; j = Julian(y, m, trig->d); return j; case GOT_MON: if (m == trig->m) return startdate; else if (m > trig->m) return Julian(y+1, trig->m, 1); else return Julian(y, trig->m, 1); case GOT_YR: if (y == trig->y) return startdate; else if (y < trig->y) return Julian(trig->y, 0, 1); else return -1; case GOT_DAY+GOT_MON: if (m > trig->m || (m == trig->m && d > trig->d)) y++; if (trig->d > MonthDays[trig->m]) { *err = E_BAD_DATE; return -1; } /* Take care of Feb. 29 */ while (trig->d > DaysInMonth(trig->m, y)) y++; return Julian(y, trig->m, trig->d); case GOT_DAY+GOT_YR: if (y < trig->y) return Julian(trig->y, 0, trig->d); else if (y > trig->y) return -1; if (d > trig->d) { m++; if (m == 12) return -1; } while (trig->d > DaysInMonth(m, trig->y)) m++; return Julian(trig->y, m, trig->d); case GOT_MON+GOT_YR: if (y > trig->y || (y == trig->y && m > trig->m)) return -1; if (y < trig->y) return Julian(trig->y, trig->m, 1); if (m == trig->m) return startdate; return Julian(trig->y, trig->m, 1); case GOT_DAY+GOT_MON+GOT_YR: if (trig->d > DaysInMonth(trig->m, trig->y)) { *err = E_BAD_DATE; return -1; } return Julian(trig->y, trig->m, trig->d); case GOT_YR+GOT_WD: if (y > trig->y) return -1; if (y < trig->y) j = Julian(trig->y, 0, 1); else j = startdate; while(! (trig->wd & (1 << (j%7)))) j++; if (JYear(j) > trig->y) return -1; return j; case GOT_MON+GOT_WD: if (m == trig->m) { j = startdate; while(! (trig->wd & (1 << (j%7)))) j++; if (JMonth(j) == trig->m) return j; } if (m >= trig->m) j = Julian(y+1, trig->m, 1); else j = Julian(y, trig->m, 1); while(! (trig->wd & (1 << (j%7)))) j++; return j; /* Guaranteed to be within the month */ case GOT_DAY+GOT_WD: if (m !=0 || y > BASE) { m2 = m-1; if (m2 < 0) { y2 = y-1; m2 = 11; } /* If there are fewer days in previous month, no match */ if (trig->d <= DaysInMonth(m2, y2)) { j = Julian(y2, m2, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; } } /* Try this month */ if (trig->d <= DaysInMonth(m, y)) { j = Julian(y, m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; } /* Argh! Try next avail. month */ m2 = m+1; if (m2 > 11) { m2 = 0; y++; } while (trig->d > DaysInMonth(m2, y)) m2++; j = Julian(y, m2, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; return j; case GOT_WD+GOT_YR+GOT_DAY: if (y > trig->y+1 || (y > trig->y && m>0)) return -1; if (y > trig->y) { j = Julian(trig->y, 11, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; } else if (y < trig->y) { j = Julian(trig->y, 0, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; return j; } else { /* Try last month */ if (m > 0) { m2 = m-1; while (trig->d > DaysInMonth(m2, trig->y)) m2--; j = Julian(trig->y, m2, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; } } /* Try this month */ if (trig->d <= DaysInMonth(m, trig->y)) { j = Julian(trig->y, m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; } /* Must be next month */ if (m == 11) return -1; m++; while (trig->d > DaysInMonth(m, trig->d)) m++; j = Julian(trig->y, m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; return j; case GOT_DAY+GOT_MON+GOT_WD: if (trig->d > MonthDays[trig->m]) { *err = E_BAD_DATE; return -1; } /* Back up a year in case we'll cross a year boundary*/ if (y > BASE) { y--; } /* Move up to the first valid year */ while (trig->d > DaysInMonth(trig->m, y)) y++; /* Try last year */ j = Julian(y, trig->m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; /* Try this year */ y++; j = Julian(y, trig->m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; if (j >= startdate) return j; /* Must be next year */ y++; while (trig->d > DaysInMonth(trig->m, y)) y++; j = Julian(y, trig->m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; return j; case GOT_WD+GOT_MON+GOT_YR: if (y > trig->y || (y == trig->y && m > trig->m)) return -1; if (trig->y > y || (trig->y == y && trig->m > m)) { j = Julian(trig->y, trig->m, 1); while(! (trig->wd & (1 << (j%7)))) j++; return j; } else { j = startdate; while(! (trig->wd & (1 << (j%7)))) j++; FromJulian(j, &y2, &m2, &d2); if (m2 == trig->m) return j; else return -1; } case GOT_WD+GOT_DAY+GOT_MON+GOT_YR: if (trig->d > DaysInMonth(trig->m, trig->y)) { *err = E_BAD_DATE; return -1; } j = Julian(trig->y, trig->m, trig->d); while(! (trig->wd & (1 << (j%7)))) j++; return j; default: Eprint("NextSimpleTrig %s %d", ErrMsg[E_SWERR], typ); *err = E_SWERR; return -1; } }
int ComputeTrigger(int today, Trigger *trig, int *err, int save_in_globals) { int nattempts = 0, start = today, nextstart = 0, y, m, d, omit, result; trig->expired = 0; if (save_in_globals) { LastTrigValid = 0; } /* Assume everything works */ *err = OK; /* But check for obvious problems... */ if (trig->localomit == 1 + 2 + 4 + 8 + 16 + 32 + 64) { *err = E_2MANY_LOCALOMIT; return -1; } if (trig->rep != NO_REP && (trig->d == NO_DAY || trig->m == NO_MON || trig->y == NO_YR)) { Eprint("%s", ErrMsg[E_REP_FULSPEC]); *err = E_REP_FULSPEC; return -1; } while (nattempts++ < TRIG_ATTEMPTS) { result = GetNextTriggerDate(trig, start, err, &nextstart); /* If there's an error, die immediately */ if (*err) return -1; if (result == -1) { trig->expired = 1; if (DebugFlag & DB_PRTTRIG) { fprintf(ErrFp, "%s(%d): %s\n", FileName, LineNo, ErrMsg[E_EXPIRED]); } return -1; } /* If result is >= today, great! */ if (trig->skip == SKIP_SKIP) { *err = IsOmitted(result, trig->localomit, trig->omitfunc, &omit); if (*err) return -1; } else { omit = 0; } if (result >= today && (trig->skip != SKIP_SKIP || !omit)) { if (save_in_globals) { LastTriggerDate = result; /* Save in global var */ LastTrigValid = 1; } if (DebugFlag & DB_PRTTRIG) { FromJulian(result, &y, &m, &d); fprintf(ErrFp, "%s(%d): Trig = %s, %d %s, %d\n", FileName, LineNo, DayName[result % 7], d, MonthName[m], y); } return result; } /* If it's a simple trigger, no point in rescanning */ if (trig->back == NO_BACK && trig->skip == NO_SKIP && trig->rep == NO_REP) { trig->expired = 1; if (DebugFlag & DB_PRTTRIG) { fprintf(ErrFp, "%s(%d): %s\n", FileName, LineNo, ErrMsg[E_EXPIRED]); } if (result != -1) { if (save_in_globals) { LastTriggerDate = result; LastTrigValid = 1; } } return -1; } if (trig->skip == SKIP_SKIP && omit && nextstart <= start && result >= start) { nextstart = result + 1; } /* Keep scanning... unless there's no point in doing it.*/ if (nextstart <= start) { if (result != -1) { if (save_in_globals) { LastTriggerDate = result; LastTrigValid = 1; } } trig->expired = 1; if (DebugFlag & DB_PRTTRIG) { fprintf(ErrFp, "%s(%d): %s\n", FileName, LineNo, ErrMsg[E_EXPIRED]); } return -1; } else start = nextstart; } /* We failed - too many attempts or trigger has expired*/ *err = E_CANT_TRIG; return -1; }
static int JYear(int jul) { int y, m, d; FromJulian(jul, &y, &m, &d); return y; }
static int JMonth(int jul) { int y, m, d; FromJulian(jul, &y, &m, &d); return m; }
static int WriteCalendarRow(void) { int y, m, d, wd, i, l; int done; char buf[81]; int OrigJul = JulianToday; int LinesWritten = 0; int moreleft; /* Get the date of the first day */ FromJulian(JulianToday, &y, &m, &d); if (!MondayFirst) wd = (JulianToday + 1) % 7; else wd = JulianToday % 7; /* Fill in the column entries */ for (i=wd; i<7; i++) { if (d+i-wd > DaysInMonth(m, y)) break; GenerateCalEntries(i); JulianToday++; } /* Output the entries */ /* If it's "Simple Calendar" format, do it simply... */ if (DoSimpleCalendar) { for (i=wd; i<7 && d+i-wd<=DaysInMonth(m, y); i++) { WriteSimpleEntries(i, OrigJul+i-wd); } return (d+7-wd <= DaysInMonth(m, y)); } /* Here come the first few lines... */ gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { if (i < wd || d+i-wd>DaysInMonth(m, y)) PrintLeft("", ColSpaces, ' '); else { sprintf(buf, "%d", d+i-wd); PrintLeft(buf, ColSpaces, ' '); } gon(); DRAW(tb); goff(); } PutChar('\n'); for (l=0; l<CalPad; l++) { gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { PrintLeft("", ColSpaces, ' '); gon(); DRAW(tb); goff(); } PutChar('\n'); } /* Write the body lines */ done = 0; while (!done) { done = WriteOneCalLine(); LinesWritten++; } /* Write any blank lines required */ while (LinesWritten++ < CalLines) { gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { PrintLeft("", ColSpaces, ' '); gon(); DRAW(tb); goff(); } PutChar('\n'); } moreleft = (d+7-wd <= DaysInMonth(m, y)); if (moreleft) { WriteIntermediateCalLine(); } else { WriteBottomCalLine(); } /* Return non-zero if we have not yet finished */ return moreleft; }
static void DoCalendarOneWeek(nleft) { int y, m, d, done, i, l, wd; char buf[81]; int LinesWritten = 0; int OrigJul = JulianToday; /* Fill in the column entries */ for (i=0; i<7; i++) { GenerateCalEntries(i); JulianToday++; } /* Output the entries */ /* If it's "Simple Calendar" format, do it simply... */ if (DoSimpleCalendar) { if (MondayFirst) wd = JulianToday % 7; else wd = (JulianToday + 1) % 7; for (i=0; i<7; i++) { WriteSimpleEntries(i, OrigJul+i-wd); } return; } /* Here come the first few lines... */ gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { FromJulian(OrigJul+i, &y, &m, &d); sprintf(buf, "%d %c%c%c ", d, MonthName[m][0], MonthName[m][1], MonthName[m][2]); if (OrigJul+i == RealToday) PrintLeft(buf, ColSpaces, '*'); else PrintLeft(buf, ColSpaces, ' '); gon(); DRAW(tb); goff(); } PutChar('\n'); for (l=0; l<CalPad; l++) { gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { PrintLeft("", ColSpaces, ' '); gon(); DRAW(tb); goff(); } PutChar('\n'); } /* Write the body lines */ done = 0; while (!done) { done = WriteOneCalLine(); LinesWritten++; } /* Write any blank lines required */ while (LinesWritten++ < CalLines) { gon(); DRAW(tb); goff(); for (i=0; i<7; i++) { PrintLeft("", ColSpaces, ' '); gon(); DRAW(tb); goff(); } PutChar('\n'); } /* Write the final line */ if (nleft) { WriteIntermediateCalLine(); } else { WriteBottomCalLine(); } }