~ubuntu-branches/ubuntu/breezy/remind/breezy

« back to all changes in this revision

Viewing changes to src/omit.c

  • Committer: Bazaar Package Importer
  • Author(s): Javier Fernandez-Sanguino Pen~a
  • Date: 1999-02-19 13:36:15 UTC
  • Revision ID: james.westby@ubuntu.com-19990219133615-ovob95sord67b0ks
Tags: 03.00.22-1
* NMU upload, maintainer seems to be missing.
* Changed to main (now GPL) (Closes: #42402)
* New upstream version (Closes: #59447)
* Moved to use debconf.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************/
 
2
/*                                                             */
 
3
/*  OMIT.C                                                     */
 
4
/*                                                             */
 
5
/*  This file handles all global OMIT commands, and maintains  */
 
6
/*  the data structures for OMITted dates.                     */
 
7
/*                                                             */
 
8
/*  This file is part of REMIND.                               */
 
9
/*  Copyright (C) 1992-1998 by David F. Skoll                  */
 
10
/*  Copyright (C) 1999-2000 by Roaring Penguin Software Inc.   */
 
11
/*                                                             */
 
12
/***************************************************************/
 
13
 
 
14
#include "config.h"
 
15
static char const RCSID[] = "$Id: omit.c,v 1.6 2000/02/18 03:46:03 dfs Exp $";
 
16
 
 
17
#include <stdio.h>
 
18
 
 
19
#ifdef HAVE_STDLIB_H
 
20
#include <stdlib.h>
 
21
#endif
 
22
 
 
23
#ifdef HAVE_MALLOC_H
 
24
#include <malloc.h>
 
25
#endif
 
26
 
 
27
#include "types.h"
 
28
#include "protos.h"
 
29
#include "globals.h"
 
30
#include "err.h"
 
31
 
 
32
PRIVATE int BexistsIntArray ARGS ((int array[], int num, int key));
 
33
PRIVATE void InsertIntoSortedArray ARGS ((int *array, int num, int key));
 
34
 
 
35
/* Arrays for the global omits */
 
36
static int FullOmitArray[MAX_FULL_OMITS];
 
37
static int PartialOmitArray[MAX_PARTIAL_OMITS];
 
38
 
 
39
/* How many of each omit types do we have? */
 
40
static int NumFullOmits, NumPartialOmits;
 
41
 
 
42
/* The structure for saving and restoring OMIT contexts */
 
43
typedef struct omitcontext {
 
44
    struct omitcontext *next;
 
45
    int numfull, numpart;
 
46
    int *fullsave;
 
47
    int *partsave;
 
48
} OmitContext;
 
49
 
 
50
/* The stack of saved omit contexts */
 
51
static OmitContext *SavedOmitContexts = NULL;
 
52
 
 
53
/***************************************************************/
 
54
/*                                                             */
 
55
/*  ClearGlobalOmits                                           */
 
56
/*                                                             */
 
57
/*  Clear all the global OMIT context.                         */
 
58
/*                                                             */
 
59
/***************************************************************/
 
60
#ifdef HAVE_PROTOS
 
61
PUBLIC int ClearGlobalOmits(void)
 
62
#else
 
63
int ClearGlobalOmits()
 
64
#endif
 
65
{
 
66
    NumFullOmits = NumPartialOmits = 0;
 
67
    return OK;
 
68
}
 
69
 
 
70
/***************************************************************/
 
71
/*                                                             */
 
72
/*  DoClear                                                    */
 
73
/*                                                             */
 
74
/*  The command-line function CLEAR-OMIT-CONTEXT               */
 
75
/*                                                             */
 
76
/***************************************************************/
 
77
#ifdef HAVE_PROTOS
 
78
PUBLIC int DoClear(ParsePtr p)
 
79
#else
 
80
int DoClear(p)
 
81
ParsePtr p;
 
82
#endif
 
83
{
 
84
    ClearGlobalOmits();
 
85
    return VerifyEoln(p);
 
86
}
 
87
 
 
88
/***************************************************************/
 
89
/*                                                             */
 
90
/*  DestroyOmitContexts                                        */
 
91
/*                                                             */
 
92
/*  Free all the memory used by saved OMIT contexts.           */
 
93
/*  As a side effect, return the number of OMIT contexts       */
 
94
/*  destroyed.                                                 */
 
95
/*                                                             */
 
96
/***************************************************************/
 
97
#ifdef HAVE_PROTOS
 
98
PUBLIC int DestroyOmitContexts(void)
 
99
#else
 
100
int DestroyOmitContexts()
 
101
#endif
 
102
{
 
103
    OmitContext *c = SavedOmitContexts;
 
104
    OmitContext *d;
 
105
    int num = 0;
 
106
 
 
107
    while (c) {
 
108
        num++;
 
109
        if (c->fullsave) free(c->fullsave);
 
110
        if (c->partsave) free(c->partsave);
 
111
        d = c->next;
 
112
        free(c);
 
113
        c = d;
 
114
    }
 
115
    SavedOmitContexts = NULL;
 
116
    return num;
 
117
}
 
118
 
 
119
/***************************************************************/
 
120
/*                                                             */
 
121
/*  PushOmitContext                                            */
 
122
/*                                                             */
 
123
/*  Push the OMIT context on to the stack.                     */
 
124
/*                                                             */
 
125
/***************************************************************/
 
126
#ifdef HAVE_PROTOS
 
127
PUBLIC int PushOmitContext(ParsePtr p)
 
128
#else
 
129
int PushOmitContext(p)
 
130
ParsePtr p;
 
131
#endif
 
132
{
 
133
    register int i;
 
134
    OmitContext *context;
 
135
 
 
136
/* Create the saved context */
 
137
    context = NEW(OmitContext);
 
138
    if (!context) return E_NO_MEM;
 
139
 
 
140
    context->numfull = NumFullOmits;
 
141
    context->numpart = NumPartialOmits;
 
142
    context->fullsave = (int *) malloc(NumFullOmits * sizeof(int));
 
143
    if (NumFullOmits && !context->fullsave) {
 
144
        free(context);
 
145
        return E_NO_MEM;
 
146
    }
 
147
    context->partsave = (int *) malloc(NumPartialOmits * sizeof(int));
 
148
    if (NumPartialOmits && !context->partsave) {
 
149
        free(context->fullsave);
 
150
        free(context);
 
151
        return E_NO_MEM;
 
152
    }
 
153
      
 
154
/* Copy the context over */
 
155
    for (i=0; i<NumFullOmits; i++)
 
156
        *(context->fullsave + i) = FullOmitArray[i];
 
157
 
 
158
    for (i=0; i<NumPartialOmits; i++)
 
159
        *(context->partsave + i) = PartialOmitArray[i];
 
160
 
 
161
/* Add the context to the stack */
 
162
    context->next = SavedOmitContexts;
 
163
    SavedOmitContexts = context;
 
164
    return VerifyEoln(p);
 
165
}
 
166
 
 
167
/***************************************************************/
 
168
/*                                                             */
 
169
/*  PopOmitContext                                             */
 
170
/*                                                             */
 
171
/*  Pop the OMIT context off of the stack.                     */
 
172
/*                                                             */
 
173
/***************************************************************/
 
174
#ifdef HAVE_PROTOS
 
175
PUBLIC int PopOmitContext(ParsePtr p)
 
176
#else
 
177
int PopOmitContext(p)
 
178
ParsePtr p;
 
179
#endif
 
180
{
 
181
 
 
182
    register int i;
 
183
    OmitContext *c = SavedOmitContexts;
 
184
 
 
185
    if (!c) return E_POP_NO_PUSH;
 
186
    NumFullOmits = c->numfull;
 
187
    NumPartialOmits = c->numpart;
 
188
 
 
189
/* Copy the context over */
 
190
    for (i=0; i<NumFullOmits; i++)
 
191
        FullOmitArray[i] = *(c->fullsave + i);
 
192
 
 
193
    for (i=0; i<NumPartialOmits; i++)
 
194
        PartialOmitArray[i] = *(c->partsave + i);
 
195
 
 
196
/* Remove the context from the stack */
 
197
    SavedOmitContexts = c->next;
 
198
 
 
199
/* Free memory used by the saved context */
 
200
    if (c->partsave) free(c->partsave);
 
201
    if (c->fullsave) free(c->fullsave);
 
202
    free(c);
 
203
 
 
204
    return VerifyEoln(p);
 
205
}
 
206
 
 
207
/***************************************************************/
 
208
/*                                                             */
 
209
/*  IsOmitted                                                  */
 
210
/*                                                             */
 
211
/*  Return non-zero if date is OMITted, zero if it is not.     */
 
212
/*                                                             */
 
213
/***************************************************************/
 
214
#ifdef HAVE_PROTOS
 
215
PUBLIC int IsOmitted(int jul, int localomit)
 
216
#else
 
217
int IsOmitted(jul, localomit)
 
218
int jul, localomit;
 
219
#endif
 
220
{
 
221
    int y, m, d;
 
222
 
 
223
    /* Is it omitted because of local omits? */
 
224
    if (localomit & (1 << (jul % 7))) return 1;
 
225
 
 
226
    /* Is it omitted because of fully-specified omits? */
 
227
    if (BexistsIntArray(FullOmitArray, NumFullOmits, jul)) return 1;
 
228
 
 
229
    /* Get the syndrome */
 
230
    FromJulian(jul, &y, &m, &d);
 
231
    if (BexistsIntArray(PartialOmitArray, NumPartialOmits, (m << 5) + d))
 
232
        return 1;
 
233
 
 
234
    /* Not omitted */
 
235
    return 0;
 
236
}
 
237
 
 
238
/***************************************************************/
 
239
/*                                                             */
 
240
/*  BexistsIntArray                                            */
 
241
/*                                                             */
 
242
/*  Perform a binary search on an integer array.  Return 1 if  */
 
243
/*  element is found, 0 otherwise.                             */
 
244
/*                                                             */
 
245
/***************************************************************/
 
246
#ifdef HAVE_PROTOS
 
247
PRIVATE int BexistsIntArray(int array[], int num, int key)
 
248
#else
 
249
static int BexistsIntArray(array, num, key)
 
250
int array[], num, key;
 
251
#endif
 
252
{
 
253
    int top=num-1, bot=0, mid;
 
254
 
 
255
    while (top >= bot) {
 
256
        mid = (top+bot)/2;
 
257
        if (array[mid] == key) return 1;
 
258
        else if (array[mid] > key) top = mid-1;
 
259
        else bot=mid+1;
 
260
    }
 
261
    return 0;
 
262
}
 
263
 
 
264
/***************************************************************/
 
265
/*                                                             */
 
266
/*  InsertIntoSortedArray                                      */
 
267
/*                                                             */
 
268
/*  Insert a key into a sorted array.  We assume that there is */
 
269
/*  room in the array for it.                                  */
 
270
/*                                                             */
 
271
/***************************************************************/
 
272
#ifdef HAVE_PROTOS
 
273
PRIVATE void InsertIntoSortedArray(int *array, int num, int key)
 
274
#else
 
275
static void InsertIntoSortedArray(array, num, key)
 
276
int *array, num, key;
 
277
#endif
 
278
{
 
279
    /* num is number of elements CURRENTLY in the array. */
 
280
    int *cur = array+num;
 
281
 
 
282
    while (cur > array && *(cur-1) > key) {
 
283
        *cur = *(cur-1);
 
284
        cur--;
 
285
    }
 
286
    *cur = key;
 
287
}
 
288
 
 
289
/***************************************************************/
 
290
/*                                                             */
 
291
/*  DoOmit                                                     */
 
292
/*                                                             */
 
293
/*  Do a global OMIT command.                                  */
 
294
/*                                                             */
 
295
/***************************************************************/
 
296
#ifdef HAVE_PROTOS
 
297
PUBLIC int DoOmit(ParsePtr p)
 
298
#else
 
299
int DoOmit(p)
 
300
ParsePtr p;
 
301
#endif
 
302
{
 
303
    int y = NO_YR, m = NO_MON, d = NO_DAY, r;
 
304
    Token tok;
 
305
    int parsing=1;
 
306
    int syndrome;
 
307
 
 
308
    DynamicBuffer buf;
 
309
    DBufInit(&buf);
 
310
 
 
311
/* Parse the OMIT.  We need a month and day; year is optional. */
 
312
    while(parsing) {
 
313
        if ( (r=ParseToken(p, &buf)) ) return r;
 
314
        FindToken(DBufValue(&buf), &tok);
 
315
        switch (tok.type) {
 
316
        case T_Year:
 
317
            DBufFree(&buf);
 
318
            if (y != NO_YR) return E_YR_TWICE;
 
319
            y = tok.val;
 
320
            break;
 
321
 
 
322
        case T_Month:
 
323
            DBufFree(&buf);
 
324
            if (m != NO_MON) return E_MON_TWICE;
 
325
            m = tok.val;
 
326
            break;
 
327
 
 
328
        case T_Day:
 
329
            DBufFree(&buf);
 
330
            if (d != NO_DAY) return E_DAY_TWICE;
 
331
            d = tok.val;
 
332
            break;
 
333
         
 
334
        case T_Delta:
 
335
            DBufFree(&buf);
 
336
            break;
 
337
 
 
338
        case T_Empty:
 
339
        case T_Comment:
 
340
        case T_RemType:
 
341
        case T_Priority:
 
342
        case T_Tag:
 
343
        case T_Duration:
 
344
            DBufFree(&buf);
 
345
            parsing = 0;
 
346
            break;
 
347
 
 
348
        default:
 
349
            Eprint("%s: `%s' (OMIT)", ErrMsg[E_UNKNOWN_TOKEN],
 
350
                   DBufValue(&buf));
 
351
            DBufFree(&buf);
 
352
            return E_UNKNOWN_TOKEN;
 
353
        }
 
354
    }
 
355
    if (m == NO_MON || d == NO_DAY) return E_SPEC_MON_DAY;
 
356
 
 
357
    if (y == NO_YR) {
 
358
        if (NumPartialOmits == MAX_PARTIAL_OMITS) return E_2MANY_PART;
 
359
 
 
360
        if (d > MonthDays[m]) return E_BAD_DATE;
 
361
        syndrome = (m<<5) + d;
 
362
        if (!BexistsIntArray(PartialOmitArray, NumPartialOmits, syndrome)) {
 
363
            InsertIntoSortedArray(PartialOmitArray, NumPartialOmits, syndrome);
 
364
            NumPartialOmits++;
 
365
        }
 
366
    } else {
 
367
        if (NumFullOmits == MAX_FULL_OMITS) return E_2MANY_FULL;
 
368
 
 
369
        if (d > DaysInMonth(m, y)) return E_BAD_DATE;
 
370
        syndrome = Julian(y, m, d);
 
371
        if (!BexistsIntArray(FullOmitArray, NumFullOmits, syndrome)) {
 
372
            InsertIntoSortedArray(FullOmitArray, NumFullOmits, syndrome);
 
373
            NumFullOmits++;
 
374
        }
 
375
    }
 
376
    if (tok.type == T_RemType || tok.type == T_Priority) return E_PARSE_AS_REM;
 
377
    return OK;
 
378
 
 
379
}