home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
misc
/
volume17
/
remind
/
part03
/
omits.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-19
|
11KB
|
331 lines
/***************************************************************/
/* */
/* OMITS.C */
/* */
/* By David Skoll - 12 February 1991 */
/* */
/* Handle all code related to global OMITs */
/* */
/***************************************************************/
#include <stdio.h>
#ifndef UNIX
#include <stdlib.h>
#endif
#ifndef NO_MALLOC_H
#include <malloc.h>
#endif
#include "defines.h"
#include "protos.h"
#include "globals.h"
/* Define an OMIT stack buffer */
typedef struct omit_stack {
struct omit_stack *next;
int NumFullOmit;
int NumPartOmit;
int Omits[1];
} OmitBuffer;
/* Variables that we only want visible here */
static OmitBuffer *OmitStack = (OmitBuffer *) NULL;
/***************************************************************/
/* */
/* int DoGlobalOmit(char **s) */
/* */
/* Add an entry to the global ommissions array. Either */
/* a fully-specified date, or a mm-yy type date. */
/* Return 0 if OK, -1 if date is in past, -2 if problem. */
/* */
/***************************************************************/
#ifdef __STDC__
int DoGlobalOmit(char **s)
#else
int DoGlobalOmit(s)
char **s;
#endif
{
int d = -1, m = -1, y = -1;
int omit;
int *ptr;
Token tok;
char *olds = *s;
tok.type = Unknown_t;
while(tok.type != Eol_t && tok.type != Run_t && tok.type != Msg_t) {
tok = ParseToken(s);
switch (tok.type) {
case Year_t: y = tok.val; break;
case Month_t: m = tok.val; break;
case Day_t: d = tok.val; break;
case Delta_t:
case Eol_t:
case Msg_t:
case Run_t: break;
default: Eprint("Invalid token '%s' for OMIT command.\n", tok.str);
return -2;
}
}
if (d == -1 || m == -1 || CheckDate(d, m, y)) {
Eprint("Invalid date specification.\n");
return -2;
}
if (y == -1) { /* Only mm-dd specified */
if (NumPartOmit == POMITSIZE) {
Eprint("Too many partially-specified OMITs.\n");
return -2;
}
omit = (m << 5) + d;
ptr = PartOmitArray + NumPartOmit;
NumPartOmit++;
while (ptr > PartOmitArray && *(ptr-1) > omit) {
*ptr = *(ptr-1);
ptr--;
}
*ptr = omit;
/* Check if the bonehead already has it - if so, delete it */
if (ptr > PartOmitArray && *(ptr-1) == *ptr) {
if (Debug) Eprint("Duplicated partially-specified OMIT.\n");
NumPartOmit--;
while (ptr < NumPartOmit+PartOmitArray) {
*ptr = *(ptr + 1);
ptr++;
}
}
/* If we got a DELTA, a MSG or a RUN, then execute DoRem */
if (tok.type == Delta_t || tok.type == Run_t || tok.type == Msg_t)
return DoRem(&olds);
} else { /* All three specified */
if (NumFullOmit == FOMITSIZE) {
Eprint("Too many fully-specified OMITs.\n");
return -2;
}
omit = Julian(d, m, y);
ptr = FullOmitArray + NumFullOmit;
NumFullOmit++;
while (ptr > FullOmitArray && *(ptr-1) > omit) {
*ptr = *(ptr-1);
ptr--;
}
*ptr = omit;
/* Check if the bonehead already has it - if so, delete it */
if (ptr > FullOmitArray && *(ptr-1) == *ptr) {
if (Debug) Eprint("Duplicated fully-specified OMIT.\n");
NumFullOmit--;
while (ptr < NumFullOmit+FullOmitArray) {
*ptr = *(ptr + 1);
ptr++;
}
}
if (omit < JulianToday) {
if (Debug) Eprint("Omit has expired.\n");
return -1;
}
/* If we got a DELTA, a MSG or a RUN, then execute DoRem */
if (tok.type == Delta_t || tok.type == Run_t || tok.type == Msg_t)
return DoRem(&olds);
}
return 0;
}
/***************************************************************/
/* */
/* PushOmitContext */
/* */
/* Push the Global OMIT context onto a stack. */
/* */
/* Returns 0 for success, 1 for failure. */
/* */
/***************************************************************/
#ifdef __STDC__
int PushOmitContext(void)
#else
int PushOmitContext()
#endif
{
OmitBuffer *new = (OmitBuffer *) malloc( sizeof(OmitBuffer) +
(NumFullOmit + NumPartOmit - 1) * sizeof(int));
if (!new) {
Eprint("Unable to allocate memory for PUSH-OMIT-CONTEXT.\n");
return 1;
}
new->NumFullOmit = NumFullOmit;
new->NumPartOmit = NumPartOmit;
CopyInts(FullOmitArray, &(new->Omits[0]), NumFullOmit);
CopyInts(PartOmitArray, &(new->Omits[NumFullOmit]), NumPartOmit);
new->next = OmitStack;
OmitStack = new;
return 0;
}
/***************************************************************/
/* */
/* PopOmitContext */
/* */
/* Restore the OMIT context from the stack. */
/* */
/* Returns 0 for success, 1 for failure. */
/* */
/***************************************************************/
#ifdef __STDC__
int PopOmitContext(void)
#else
int PopOmitContext()
#endif
{
OmitBuffer *temp;
if (!OmitStack) {
Eprint("No saved contexts for POP-OMIT-CONTEXT.\n");
return 1;
}
NumFullOmit = OmitStack->NumFullOmit;
NumPartOmit = OmitStack->NumPartOmit;
CopyInts(&(OmitStack->Omits[0]), FullOmitArray, NumFullOmit);
CopyInts(&(OmitStack->Omits[NumFullOmit]), PartOmitArray, NumPartOmit);
temp = OmitStack->next;
free(OmitStack);
OmitStack = temp;
return 0;
}
/***************************************************************/
/* */
/* ClearOmitContext */
/* */
/* Get rid of all global OMITS. */
/* */
/***************************************************************/
#ifdef __STDC__
void ClearOmitContext(void)
#else
void ClearOmitContext()
#endif
{
NumFullOmit = NumPartOmit = 0;
}
/***************************************************************/
/* */
/* CopyInts */
/* */
/* Copy integer values from one array to another. */
/* */
/***************************************************************/
#ifdef __STDC__
void CopyInts(int *from, int *to, int count)
#else
void CopyInts(from, to, count)
int *from, *to, count;
#endif
{
while (count--) *to++ = *from++;
}
/***************************************************************/
/* */
/* FreeStackedOmits */
/* */
/* Get rid of all the stacked OMIT contexts */
/* */
/***************************************************************/
#ifdef __STDC__
void FreeStackedOmits(void)
#else
void FreeStackedOmits()
#endif
{
OmitBuffer *current = OmitStack, *next;
if (current && Debug) Eprint("Warning - more PUSH-OMIT-CONTEXTs than POP-OMIT-CONTEXTs\n");
while (current) {
next = current->next;
free(current);
current = next;
}
OmitStack = (OmitBuffer *) NULL;
}
/***************************************************************/
/* */
/* IsOmitted */
/* */
/* Returns non-zero if the julian date should be omitted, 0 */
/* otherwise. */
/* */
/***************************************************************/
#ifdef __STDC__
int IsOmitted(int jul, int localomit)
#else
int IsOmitted(jul, localomit)
int jul, localomit;
#endif
{
int d, m, y;
/* Check if we should omit because of local omit */
if (localomit & 1 << (jul % 7)) return 1;
/* Check if we should omit because of fully-specified global omit */
if (NumFullOmit && my_bsearch(jul, FullOmitArray, NumFullOmit)) return 1;
/* Check if we should omit because of partially-specified global omits */
if (NumPartOmit) {
FromJulian(jul, &d, &m, &y);
if (my_bsearch((m << 5)+d, PartOmitArray, NumPartOmit)) return 1;
}
/* Looks cool - don't omit */
return 0;
}
/***************************************************************/
/* */
/* my_bsearch */
/* */
/* A simplified version of bsearch() for people whose library */
/* does not have the full version. This only works when */
/* searching a sorted array of integers. */
/* */
/***************************************************************/
#ifdef __STDC__
int *my_bsearch(int key, int *array, int number)
#else
int *my_bsearch(key, array, number)
int key, *array, number;
#endif
{
int top = number - 1;
int bot = 0;
int mid;
while (top >= bot) {
mid = (top+bot)/2;
if (*(array+mid) == key) return array+mid;
else if (*(array+mid) > key) top = mid-1;
else bot = mid+1;
}
/* Oh, well - unsuccessful search. Return NULL */
return NULL;
}