Merge from vendor branch LIBSTDC++:
[dragonfly.git] / contrib / bc / dc / eval.c
1 /* 
2  * evaluate the dc language, from a FILE* or a string
3  *
4  * Copyright (C) 1994, 1997, 1998, 2000 Free Software Foundation, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you can either send email to this
18  * program's author (see below) or write to:
19  *   The Free Software Foundation, Inc.
20  *   59 Temple Place, Suite 330
21  *   Boston, MA 02111 USA
22  */
23
24 /* This is the only module which knows about the dc input language */
25
26 #include "config.h"
27
28 #include <stdio.h>
29 #ifdef HAVE_STRING_H
30 # include <string.h>    /* memchr */
31 #else
32 # ifdef HAVE_MEMORY_H
33 #  include <memory.h>   /* memchr, maybe */
34 # else
35 #  ifdef HAVE_STRINGS_H
36 #   include <strings.h> /* memchr, maybe */
37 #  endif
38 #endif
39 #endif
40 #include "dc.h"
41 #include "dc-proto.h"
42
43 typedef enum {DC_FALSE, DC_TRUE} dc_boolean;
44
45 typedef enum {
46         DC_OKAY = DC_SUCCESS, /* no further intervention needed for this command */
47         DC_EATONE,              /* caller needs to eat the lookahead char */
48         DC_QUIT,                /* quit out of unwind_depth levels of evaluation */
49
50         /* with the following return values, the caller does not have to 
51          * fret about stdin_lookahead's value
52          */
53         DC_INT,                 /* caller needs to parse a dc_num from input stream */
54         DC_STR,                 /* caller needs to parse a dc_str from input stream */
55         DC_SYSTEM,              /* caller needs to run a system() on next input line */
56         DC_COMMENT,             /* caller needs to skip to the next input line */
57         DC_NEGCMP,              /* caller needs to re-call dc_func() with `negcmp' set */
58
59         DC_EOF_ERROR    /* unexpected end of input; abort current eval */
60 } dc_status;
61
62 static int dc_ibase=10;         /* input base, 2 <= dc_ibase <= DC_IBASE_MAX */
63 static int dc_obase=10;         /* output base, 2 <= dc_obase */
64 static int dc_scale=0;          /* scale (see user documentaton) */
65
66 /* for Quitting evaluations */
67 static int unwind_depth=0;
68
69 /* if true, active Quit will not exit program */
70 static dc_boolean unwind_noexit=DC_FALSE;
71
72 /*
73  * Used to synchronize lookahead on stdin for '?' command.
74  * If set to EOF then lookahead is used up.
75  */
76 static int stdin_lookahead=EOF;
77
78 \f
79 /* input_fil and input_str are passed as arguments to dc_getnum */
80
81 /* used by the input_* functions: */
82 static FILE *input_fil_fp;
83 static const char *input_str_string;
84
85 /* Since we have a need for two characters of pushback, and
86  * ungetc() only guarantees one, we place the second pushback here
87  */
88 static int input_pushback;
89
90 /* passed as an argument to dc_getnum */
91 static int
92 input_fil DC_DECLVOID()
93 {
94         if (input_pushback != EOF){
95                 int c = input_pushback;
96                 input_pushback = EOF;
97                 return c;
98         }
99         return getc(input_fil_fp);
100 }
101
102 /* passed as an argument to dc_getnum */
103 static int
104 input_str DC_DECLVOID()
105 {
106         if (!*input_str_string)
107                 return EOF;
108         return *input_str_string++;
109 }
110
111 \f
112
113 /* takes a string and evals it; frees the string when done */
114 /* Wrapper around dc_evalstr to avoid duplicating the free call
115  * at all possible return points.
116  */
117 static int
118 dc_eval_and_free_str DC_DECLARG((string))
119         dc_data string DC_DECLEND
120 {
121         dc_status status;
122
123         status = dc_evalstr(string);
124         if (string.dc_type == DC_STRING)
125                 dc_free_str(&string.v.string);
126         return status;
127 }
128
129 \f
130 /* dc_func does the grunt work of figuring out what each input
131  * character means; used by both dc_evalstr and dc_evalfile
132  *
133  * c -> the "current" input character under consideration
134  * peekc -> the lookahead input character
135  * negcmp -> negate comparison test (for <,=,> commands)
136  */
137 static dc_status
138 dc_func DC_DECLARG((c, peekc, negcmp))
139         int c DC_DECLSEP
140         int peekc DC_DECLSEP
141         int negcmp DC_DECLEND
142 {
143         /* we occasionally need these for temporary data */
144         /* Despite the GNU coding standards, it is much easier
145          * to have these declared once here, since this function
146          * is just one big switch statement.
147          */
148         dc_data datum;
149         int tmpint;
150
151         switch (c){
152         case '_': case '.':
153         case '0': case '1': case '2': case '3':
154         case '4': case '5': case '6': case '7':
155         case '8': case '9': case 'A': case 'B':
156         case 'C': case 'D': case 'E': case 'F':
157                 return DC_INT;
158         case ' ':
159         case '\t':
160         case '\n':
161                 /* standard command separators */
162                 break;
163
164         case '+':       /* add top two stack elements */
165                 dc_binop(dc_add, dc_scale);
166                 break;
167         case '-':       /* subtract top two stack elements */
168                 dc_binop(dc_sub, dc_scale);
169                 break;
170         case '*':       /* multiply top two stack elements */
171                 dc_binop(dc_mul, dc_scale);
172                 break;
173         case '/':       /* divide top two stack elements */
174                 dc_binop(dc_div, dc_scale);
175                 break;
176         case '%':
177                 /* take the remainder from division of the top two stack elements */
178                 dc_binop(dc_rem, dc_scale);
179                 break;
180         case '~':
181                 /* Do division on the top two stack elements.  Return the
182                  * quotient as next-to-top of stack and the remainder as
183                  * top-of-stack.
184                  */
185                 dc_binop2(dc_divrem, dc_scale);
186                 break;
187         case '|':
188                 /* Consider the top three elements of the stack as (base, exp, mod),
189                  * where mod is top-of-stack, exp is next-to-top, and base is
190                  * second-from-top. Mod must be non-zero, exp must be non-negative,
191                  * and all three must be integers. Push the result of raising
192                  * base to the exp power, reduced modulo mod. If we had base in
193                  * register b, exp in register e, and mod in register m then this
194                  * is conceptually equivalent to "lble^lm%", but it is implemented
195                  * in a more efficient manner, and can handle arbritrarily large
196                  * values for exp.
197                  */
198                 dc_triop(dc_modexp, dc_scale);
199                 break;
200         case '^':       /* exponientiation of the top two stack elements */
201                 dc_binop(dc_exp, dc_scale);
202                 break;
203         case '<':
204                 /* eval register named by peekc if
205                  * less-than holds for top two stack elements
206                  */
207                 if (peekc == EOF)
208                         return DC_EOF_ERROR;
209                 if ( (dc_cmpop() <  0) == !negcmp )
210                         if (dc_register_get(peekc, &datum) == DC_SUCCESS)
211                                 if (dc_eval_and_free_str(datum) == DC_QUIT)
212                                         return DC_QUIT;
213                 return DC_EATONE;
214         case '=':
215                 /* eval register named by peekc if
216                  * equal-to holds for top two stack elements
217                  */
218                 if (peekc == EOF)
219                         return DC_EOF_ERROR;
220                 if ( (dc_cmpop() == 0) == !negcmp )
221                         if (dc_register_get(peekc, &datum) == DC_SUCCESS)
222                                 if (dc_eval_and_free_str(datum) == DC_QUIT)
223                                         return DC_QUIT;
224                 return DC_EATONE;
225         case '>':
226                 /* eval register named by peekc if
227                  * greater-than holds for top two stack elements
228                  */
229                 if (peekc == EOF)
230                         return DC_EOF_ERROR;
231                 if ( (dc_cmpop() >  0) == !negcmp )
232                         if (dc_register_get(peekc, &datum) == DC_SUCCESS)
233                                 if (dc_eval_and_free_str(datum) == DC_QUIT)
234                                         return DC_QUIT;
235                 return DC_EATONE;
236         case '?':       /* read a line from standard-input and eval it */
237                 if (stdin_lookahead != EOF){
238                         ungetc(stdin_lookahead, stdin);
239                         stdin_lookahead = EOF;
240                 }
241                 if (dc_eval_and_free_str(dc_readstring(stdin, '\n', '\n')) == DC_QUIT)
242                         return DC_QUIT;
243                 return DC_OKAY;
244         case '[':       /* read to balancing ']' into a dc_str */
245                 return DC_STR;
246         case '!':       /* read to newline and call system() on resulting string */
247                 if (peekc == '<' || peekc == '=' || peekc == '>')
248                         return DC_NEGCMP;
249                 return DC_SYSTEM;
250         case '#':       /* comment; skip remainder of current line */
251                 return DC_COMMENT;
252
253         case 'a':       /* Convert top of stack to an ascii character. */
254                 if (dc_pop(&datum) == DC_SUCCESS){
255                         char tmps;
256                         if (datum.dc_type == DC_NUMBER){
257                                 tmps = (char) dc_num2int(datum.v.number, DC_TOSS);
258                         }else if (datum.dc_type == DC_STRING){
259                                 tmps = *dc_str2charp(datum.v.string);
260                                 dc_free_str(&datum.v.string);
261                         }else{
262                                 dc_garbage("at top of stack", -1);
263                         }
264                         dc_push(dc_makestring(&tmps, 1));
265                 }
266                 break;
267         case 'c':       /* clear whole stack */
268                 dc_clear_stack();
269                 break;
270         case 'd':       /* duplicate the datum on the top of stack */
271                 if (dc_top_of_stack(&datum) == DC_SUCCESS)
272                         dc_push(dc_dup(datum));
273                 break;
274         case 'f':       /* print list of all stack items */
275                 dc_printall(dc_obase);
276                 break;
277         case 'i':       /* set input base to value on top of stack */
278                 if (dc_pop(&datum) == DC_SUCCESS){
279                         tmpint = 0;
280                         if (datum.dc_type == DC_NUMBER)
281                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
282                         if ( ! (2 <= tmpint  &&  tmpint <= DC_IBASE_MAX) )
283                                 fprintf(stderr,
284                                                 "%s: input base must be a number \
285 between 2 and %d (inclusive)\n",
286                                                 progname, DC_IBASE_MAX);
287                         else
288                                 dc_ibase = tmpint;
289                 }
290                 break;
291         case 'k':       /* set scale to value on top of stack */
292                 if (dc_pop(&datum) == DC_SUCCESS){
293                         tmpint = -1;
294                         if (datum.dc_type == DC_NUMBER)
295                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
296                         if ( ! (tmpint >= 0) )
297                                 fprintf(stderr,
298                                                 "%s: scale must be a nonnegative number\n",
299                                                 progname);
300                         else
301                                 dc_scale = tmpint;
302                 }
303                 break;
304         case 'l':       /* "load" -- push value on top of register stack named
305                                  * by peekc onto top of evaluation stack; does not
306                                  * modify the register stack
307                                  */
308                 if (peekc == EOF)
309                         return DC_EOF_ERROR;
310                 if (dc_register_get(peekc, &datum) == DC_SUCCESS)
311                         dc_push(datum);
312                 return DC_EATONE;
313         case 'n':       /* print the value popped off of top-of-stack;
314                                  * do not add a trailing newline
315                                  */
316                 if (dc_pop(&datum) == DC_SUCCESS)
317                         dc_print(datum, dc_obase, DC_NONL, DC_TOSS);
318                 break;
319         case 'o':       /* set output base to value on top of stack */
320                 if (dc_pop(&datum) == DC_SUCCESS){
321                         tmpint = 0;
322                         if (datum.dc_type == DC_NUMBER)
323                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
324                         if ( ! (tmpint > 1) )
325                                 fprintf(stderr,
326                                                 "%s: output base must be a number greater than 1\n",
327                                                 progname);
328                         else
329                                 dc_obase = tmpint;
330                 }
331                 break;
332         case 'p':       /* print the datum on the top of stack,
333                                  * with a trailing newline
334                                  */
335                 if (dc_top_of_stack(&datum) == DC_SUCCESS)
336                         dc_print(datum, dc_obase, DC_WITHNL, DC_KEEP);
337                 break;
338         case 'q':       /* quit two levels of evaluation, posibly exiting program */
339                 unwind_depth = 1; /* the return below is the first level of returns */
340                 unwind_noexit = DC_FALSE;
341                 return DC_QUIT;
342         case 'r':       /* rotate (swap) the top two elements on the stack
343                                  */
344                 if (dc_pop(&datum) == DC_SUCCESS) {
345                         dc_data datum2;
346                         int two_status;
347                         two_status = dc_pop(&datum2);
348                         dc_push(datum);
349                         if (two_status == DC_SUCCESS)
350                                 dc_push(datum2);
351                 }
352                 break;
353         case 's':       /* "store" -- replace top of register stack named
354                                  * by peekc with the value popped from the top
355                                  * of the evaluation stack
356                                  */
357                 if (peekc == EOF)
358                         return DC_EOF_ERROR;
359                 if (dc_pop(&datum) == DC_SUCCESS)
360                         dc_register_set(peekc, datum);
361                 return DC_EATONE;
362         case 'v':       /* replace top of stack with its square root */
363                 if (dc_pop(&datum) == DC_SUCCESS){
364                         dc_num tmpnum;
365                         if (datum.dc_type != DC_NUMBER){
366                                 fprintf(stderr,
367                                                 "%s: square root of nonnumeric attempted\n",
368                                                 progname);
369                         }else if (dc_sqrt(datum.v.number, dc_scale, &tmpnum) == DC_SUCCESS){
370                                 dc_free_num(&datum.v.number);
371                                 datum.v.number = tmpnum;
372                                 dc_push(datum);
373                         }
374                 }
375                 break;
376         case 'x':       /* eval the datum popped from top of stack */
377                 if (dc_pop(&datum) == DC_SUCCESS){
378                         if (datum.dc_type == DC_STRING){
379                                 if (dc_eval_and_free_str(datum) == DC_QUIT)
380                                         return DC_QUIT;
381                         }else if (datum.dc_type == DC_NUMBER){
382                                 dc_push(datum);
383                         }else{
384                                 dc_garbage("at top of stack", -1);
385                         }
386                 }
387                 break;
388         case 'z':       /* push the current stack depth onto the top of stack */
389                 dc_push(dc_int2data(dc_tell_stackdepth()));
390                 break;
391
392         case 'I':       /* push the current input base onto the stack */
393                 dc_push(dc_int2data(dc_ibase));
394                 break;
395         case 'K':       /* push the current scale onto the stack */
396                 dc_push(dc_int2data(dc_scale));
397                 break;
398         case 'L':       /* pop a value off of register stack named by peekc
399                                  * and push it onto the evaluation stack
400                                  */
401                 if (peekc == EOF)
402                         return DC_EOF_ERROR;
403                 if (dc_register_pop(peekc, &datum) == DC_SUCCESS)
404                         dc_push(datum);
405                 return DC_EATONE;
406         case 'O':       /* push the current output base onto the stack */
407                 dc_push(dc_int2data(dc_obase));
408                 break;
409         case 'P':
410                 /* Pop the value off the top of a stack.  If it is
411                  * a number, dump out the integer portion of its
412                  * absolute value as a "base UCHAR_MAX+1" byte stream;
413                  * if it is a string, just print it.
414                  * In either case, do not append a trailing newline.
415                  */
416                 if (dc_pop(&datum) == DC_SUCCESS){
417                         if (datum.dc_type == DC_NUMBER)
418                                 dc_dump_num(datum.v.number, DC_TOSS);
419                         else if (datum.dc_type == DC_STRING)
420                                 dc_out_str(datum.v.string, DC_NONL, DC_TOSS);
421                         else
422                                 dc_garbage("at top of stack", -1);
423                 }
424                 break;
425         case 'Q':       /* quit out of top-of-stack nested evals;
426                                  * pops value from stack;
427                                  * does not exit program (stops short if necessary)
428                                  */
429                 if (dc_pop(&datum) == DC_SUCCESS){
430                         unwind_depth = 0;
431                         unwind_noexit = DC_TRUE;
432                         if (datum.dc_type == DC_NUMBER)
433                                 unwind_depth = dc_num2int(datum.v.number, DC_TOSS);
434                         if (unwind_depth-- > 0)
435                                 return DC_QUIT;
436                         unwind_depth = 0;       /* paranoia */
437                         fprintf(stderr,
438                                         "%s: Q command requires a number >= 1\n",
439                                         progname);
440                 }
441                 break;
442 #if 0
443         case 'R':       /* pop a value off of the evaluation stack,;
444                                  * rotate the top
445                                  remaining stack elements that many
446                                  * places forward (negative numbers mean rotate
447                                  * backward).
448                                  */
449                 if (dc_pop(&datum) == DC_SUCCESS){
450                         tmpint = 0;
451                         if (datum.dc_type == DC_NUMBER)
452                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
453                         dc_stack_rotate(tmpint);
454                 }
455                 break;
456 #endif
457         case 'S':       /* pop a value off of the evaluation stack
458                                  * and push it onto the register stack named by peekc
459                                  */
460                 if (peekc == EOF)
461                         return DC_EOF_ERROR;
462                 if (dc_pop(&datum) == DC_SUCCESS)
463                         dc_register_push(peekc, datum);
464                 return DC_EATONE;
465         case 'X':       /* replace the number on top-of-stack with its scale factor */
466                 if (dc_pop(&datum) == DC_SUCCESS){
467                         tmpint = 0;
468                         if (datum.dc_type == DC_NUMBER)
469                                 tmpint = dc_tell_scale(datum.v.number, DC_TOSS);
470                         dc_push(dc_int2data(tmpint));
471                 }
472                 break;
473         case 'Z':       /* replace the datum on the top-of-stack with its length */
474                 if (dc_pop(&datum) == DC_SUCCESS)
475                         dc_push(dc_int2data(dc_tell_length(datum, DC_TOSS)));
476                 break;
477
478         case ':':       /* store into array */
479                 if (peekc == EOF)
480                         return DC_EOF_ERROR;
481                 if (dc_pop(&datum) == DC_SUCCESS){
482                         tmpint = -1;
483                         if (datum.dc_type == DC_NUMBER)
484                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
485                         if (dc_pop(&datum) == DC_SUCCESS){
486                                 if (tmpint < 0)
487                                         fprintf(stderr,
488                                                         "%s: array index must be a nonnegative integer\n",
489                                                         progname);
490                                 else
491                                         dc_array_set(peekc, tmpint, datum);
492                         }
493                 }
494                 return DC_EATONE;
495         case ';':       /* retreive from array */
496                 if (peekc == EOF)
497                         return DC_EOF_ERROR;
498                 if (dc_pop(&datum) == DC_SUCCESS){
499                         tmpint = -1;
500                         if (datum.dc_type == DC_NUMBER)
501                                 tmpint = dc_num2int(datum.v.number, DC_TOSS);
502                         if (tmpint < 0)
503                                 fprintf(stderr,
504                                                 "%s: array index must be a nonnegative integer\n",
505                                                 progname);
506                         else
507                                 dc_push(dc_array_get(peekc, tmpint));
508                 }
509                 return DC_EATONE;
510
511         default:        /* What did that user mean? */
512                 fprintf(stderr, "%s: ", progname);
513                 dc_show_id(stdout, c, " unimplemented\n");
514                 break;
515         }
516         return DC_OKAY;
517 }
518
519 \f
520 /* takes a string and evals it */
521 int
522 dc_evalstr DC_DECLARG((string))
523         dc_data string DC_DECLEND
524 {
525         const char *s;
526         const char *end;
527         const char *p;
528         size_t len;
529         int c;
530         int peekc;
531         int count;
532         int negcmp;
533         int next_negcmp = 0;
534
535         if (string.dc_type != DC_STRING){
536                 fprintf(stderr,
537                                 "%s: eval called with non-string argument\n",
538                                 progname);
539                 return DC_OKAY;
540         }
541         s = dc_str2charp(string.v.string);
542         end = s + dc_strlen(string.v.string);
543         while (s < end){
544                 c = *(const unsigned char *)s++;
545                 peekc = EOF;
546                 if (s < end)
547                         peekc = *(const unsigned char *)s;
548                 negcmp = next_negcmp;
549                 next_negcmp = 0;
550                 switch (dc_func(c, peekc, negcmp)){
551                 case DC_OKAY:
552                         break;
553                 case DC_EATONE:
554                         if (peekc != EOF)
555                                 ++s;
556                         break;
557                 case DC_QUIT:
558                         if (unwind_depth > 0){
559                                 --unwind_depth;
560                                 return DC_QUIT;
561                         }
562                         return DC_OKAY;
563
564                 case DC_INT:
565                         input_str_string = s - 1;
566                         dc_push(dc_getnum(input_str, dc_ibase, &peekc));
567                         s = input_str_string;
568                         if (peekc != EOF)
569                                 --s;
570                         break;
571                 case DC_STR:
572                         count = 1;
573                         for (p=s; p<end && count>0; ++p)
574                                 if (*p == ']')
575                                         --count;
576                                 else if (*p == '[')
577                                         ++count;
578                         len = p - s;
579                         dc_push(dc_makestring(s, len-1));
580                         s = p;
581                         break;
582                 case DC_SYSTEM:
583                         s = dc_system(s);
584                 case DC_COMMENT:
585                         s = memchr(s, '\n', (size_t)(end-s));
586                         if (!s)
587                                 s = end;
588                         else
589                                 ++s;
590                         break;
591                 case DC_NEGCMP:
592                         next_negcmp = 1;
593                         break;
594
595                 case DC_EOF_ERROR:
596                         fprintf(stderr, "%s: unexpected EOS\n", progname);
597                         return DC_OKAY;
598                 }
599         }
600         return DC_OKAY;
601 }
602
603 \f
604 /* This is the main function of the whole DC program.
605  * Reads the file described by fp, calls dc_func to do
606  * the dirty work, and takes care of dc_func's shortcomings.
607  */
608 int
609 dc_evalfile DC_DECLARG((fp))
610         FILE *fp DC_DECLEND
611 {
612         int c;
613         int peekc;
614         int negcmp;
615         int next_negcmp = 0;
616         dc_data datum;
617
618         stdin_lookahead = EOF;
619         for (c=getc(fp); c!=EOF; c=peekc){
620                 peekc = getc(fp);
621                 /*
622                  * The following if() is the only place where ``stdin_lookahead''
623                  * might be set to other than EOF:
624                  */
625                 if (fp == stdin)
626                         stdin_lookahead = peekc;
627                 negcmp = next_negcmp;
628                 next_negcmp = 0;
629                 switch (dc_func(c, peekc, negcmp)){
630                 case DC_OKAY:
631                         if (stdin_lookahead != peekc  &&  fp == stdin)
632                                 peekc = getc(fp);
633                         break;
634                 case DC_EATONE:
635                         peekc = getc(fp);
636                         break;
637                 case DC_QUIT:
638                         if (unwind_noexit != DC_TRUE)
639                                 return DC_SUCCESS;
640                         fprintf(stderr,
641                                         "%s: Q command argument exceeded string execution depth\n",
642                                         progname);
643                         if (stdin_lookahead != peekc  &&  fp == stdin)
644                                 peekc = getc(fp);
645                         break;
646
647                 case DC_INT:
648                         input_fil_fp = fp;
649                         input_pushback = c;
650                         ungetc(peekc, fp);
651                         dc_push(dc_getnum(input_fil, dc_ibase, &peekc));
652                         break;
653                 case DC_STR:
654                         ungetc(peekc, fp);
655                         datum = dc_readstring(fp, '[', ']');
656                         dc_push(datum);
657                         peekc = getc(fp);
658                         break;
659                 case DC_SYSTEM:
660                         ungetc(peekc, fp);
661                         datum = dc_readstring(stdin, '\n', '\n');
662                         (void)dc_system(dc_str2charp(datum.v.string));
663                         dc_free_str(&datum.v.string);
664                         peekc = getc(fp);
665                         break;
666                 case DC_COMMENT:
667                         while (peekc!=EOF && peekc!='\n')
668                                 peekc = getc(fp);
669                         if (peekc != EOF)
670                                 peekc = getc(fp);
671                         break;
672                 case DC_NEGCMP:
673                         next_negcmp = 1;
674                         break;
675
676                 case DC_EOF_ERROR:
677                         fprintf(stderr, "%s: unexpected EOF\n", progname);
678                         return DC_FAIL;
679                 }
680         }
681         return DC_SUCCESS;
682 }