[BACK]Return to util.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/util.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: util.c,v 1.46 1998/06/18 14:55:20 ddenholm Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - util.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37:
        !            38: #include "plot.h"
        !            39: #include "setshow.h"           /* for month names etc */
        !            40:
        !            41:
        !            42: /* TRUE if command just typed; becomes FALSE whenever we
        !            43:  * send some other output to screen.  If FALSE, the command line
        !            44:  * will be echoed to the screen before the ^ error message.
        !            45:  */
        !            46: TBOOLEAN screen_ok;
        !            47:
        !            48: static char *num_to_str __PROTO((double r));
        !            49: static void parse_esc __PROTO((char *instr));
        !            50:
        !            51: /*
        !            52:  * chr_in_str() compares the characters in the string of token number t_num
        !            53:  * with c, and returns TRUE if a match was found.
        !            54:  */
        !            55: int chr_in_str(t_num, c)
        !            56: int t_num;
        !            57: int c;
        !            58: {
        !            59:     register int i;
        !            60:
        !            61:     if (!token[t_num].is_token)
        !            62:        return (FALSE);         /* must be a value--can't be equal */
        !            63:     for (i = 0; i < token[t_num].length; i++) {
        !            64:        if (input_line[token[t_num].start_index + i] == c)
        !            65:            return (TRUE);
        !            66:     }
        !            67:     return FALSE;
        !            68: }
        !            69:
        !            70:
        !            71: /*
        !            72:  * equals() compares string value of token number t_num with str[], and
        !            73:  *   returns TRUE if they are identical.
        !            74:  */
        !            75: int equals(t_num, str)
        !            76: int t_num;
        !            77: char *str;
        !            78: {
        !            79:     register int i;
        !            80:
        !            81:     if (!token[t_num].is_token)
        !            82:        return (FALSE);         /* must be a value--can't be equal */
        !            83:     for (i = 0; i < token[t_num].length; i++) {
        !            84:        if (input_line[token[t_num].start_index + i] != str[i])
        !            85:            return (FALSE);
        !            86:     }
        !            87:     /* now return TRUE if at end of str[], FALSE if not */
        !            88:     return (str[i] == NUL);
        !            89: }
        !            90:
        !            91:
        !            92:
        !            93: /*
        !            94:  * almost_equals() compares string value of token number t_num with str[], and
        !            95:  *   returns TRUE if they are identical up to the first $ in str[].
        !            96:  */
        !            97: int almost_equals(t_num, str)
        !            98: int t_num;
        !            99: char *str;
        !           100: {
        !           101:     register int i;
        !           102:     register int after = 0;
        !           103:     register int start = token[t_num].start_index;
        !           104:     register int length = token[t_num].length;
        !           105:
        !           106:     if (!token[t_num].is_token)
        !           107:        return (FALSE);         /* must be a value--can't be equal */
        !           108:     for (i = 0; i < length + after; i++) {
        !           109:        if (str[i] != input_line[start + i]) {
        !           110:            if (str[i] != '$')
        !           111:                return (FALSE);
        !           112:            else {
        !           113:                after = 1;
        !           114:                start--;        /* back up token ptr */
        !           115:            }
        !           116:        }
        !           117:     }
        !           118:
        !           119:     /* i now beyond end of token string */
        !           120:
        !           121:     return (after || str[i] == '$' || str[i] == NUL);
        !           122: }
        !           123:
        !           124:
        !           125:
        !           126: int isstring(t_num)
        !           127: int t_num;
        !           128: {
        !           129:
        !           130:     return (token[t_num].is_token &&
        !           131:            (input_line[token[t_num].start_index] == '\'' ||
        !           132:             input_line[token[t_num].start_index] == '"'));
        !           133: }
        !           134:
        !           135:
        !           136: int isanumber(t_num)
        !           137: int t_num;
        !           138: {
        !           139:     return (!token[t_num].is_token);
        !           140: }
        !           141:
        !           142:
        !           143: int isletter(t_num)
        !           144: int t_num;
        !           145: {
        !           146:     return (token[t_num].is_token &&
        !           147:            ((isalpha((int)input_line[token[t_num].start_index])) ||
        !           148:             (input_line[token[t_num].start_index] == '_')));
        !           149: }
        !           150:
        !           151:
        !           152: /*
        !           153:  * is_definition() returns TRUE if the next tokens are of the form
        !           154:  *   identifier =
        !           155:  *              -or-
        !           156:  *   identifier ( identifer {,identifier} ) =
        !           157:  */
        !           158: int is_definition(t_num)
        !           159: int t_num;
        !           160: {
        !           161:     /* variable? */
        !           162:     if (isletter(t_num) && equals(t_num + 1, "="))
        !           163:        return 1;
        !           164:
        !           165:     /* function? */
        !           166:     /* look for dummy variables */
        !           167:     if (isletter(t_num) && equals(t_num + 1, "(") && isletter(t_num + 2)) {
        !           168:        t_num += 3;             /* point past first dummy */
        !           169:        while (equals(t_num, ",")) {
        !           170:            if (!isletter(++t_num))
        !           171:                return 0;
        !           172:            t_num += 1;
        !           173:        }
        !           174:        return (equals(t_num, ")") && equals(t_num + 1, "="));
        !           175:     }
        !           176:     /* neither */
        !           177:     return 0;
        !           178: }
        !           179:
        !           180:
        !           181:
        !           182: /*
        !           183:  * copy_str() copies the string in token number t_num into str, appending
        !           184:  *   a null.  No more than max chars are copied (including \0).
        !           185:  */
        !           186: void copy_str(str, t_num, max)
        !           187: char str[];
        !           188: int t_num;
        !           189: int max;
        !           190: {
        !           191:     register int i = 0;
        !           192:     register int start = token[t_num].start_index;
        !           193:     register int count;
        !           194:
        !           195:     if ((count = token[t_num].length) >= max) {
        !           196:        count = max - 1;
        !           197:        FPRINTF((stderr, "str buffer overflow in copy_str"));
        !           198:     }
        !           199:     do {
        !           200:        str[i++] = input_line[start++];
        !           201:     } while (i != count);
        !           202:     str[i] = NUL;
        !           203: }
        !           204:
        !           205: /* length of token string */
        !           206: int token_len(t_num)
        !           207: int t_num;
        !           208: {
        !           209:     return (token[t_num].length);
        !           210: }
        !           211:
        !           212: /*
        !           213:  * quote_str() does the same thing as copy_str, except it ignores the
        !           214:  *   quotes at both ends.  This seems redundant, but is done for
        !           215:  *   efficency.
        !           216:  */
        !           217: void quote_str(str, t_num, max)
        !           218: char str[];
        !           219: int t_num;
        !           220: int max;
        !           221: {
        !           222:     register int i = 0;
        !           223:     register int start = token[t_num].start_index + 1;
        !           224:     register int count;
        !           225:
        !           226:     if ((count = token[t_num].length - 2) >= max) {
        !           227:        count = max - 1;
        !           228:        FPRINTF((stderr, "str buffer overflow in quote_str"));
        !           229:     }
        !           230:     if (count > 0) {
        !           231:        do {
        !           232:            str[i++] = input_line[start++];
        !           233:        } while (i != count);
        !           234:     }
        !           235:     str[i] = NUL;
        !           236:     /* convert \t and \nnn (octal) to char if in double quotes */
        !           237:     if (input_line[token[t_num].start_index] == '"')
        !           238:        parse_esc(str);
        !           239: }
        !           240:
        !           241:
        !           242: /*
        !           243:  * capture() copies into str[] the part of input_line[] which lies between
        !           244:  * the begining of token[start] and end of token[end].
        !           245:  */
        !           246: void capture(str, start, end, max)
        !           247: char str[];
        !           248: int start, end;
        !           249: int max;
        !           250: {
        !           251:     register int i, e;
        !           252:
        !           253:     e = token[end].start_index + token[end].length;
        !           254:     if (e - token[start].start_index >= max) {
        !           255:        e = token[start].start_index + max - 1;
        !           256:        FPRINTF((stderr, "str buffer overflow in capture"));
        !           257:     }
        !           258:     for (i = token[start].start_index; i < e && input_line[i] != NUL; i++)
        !           259:        *str++ = input_line[i];
        !           260:     *str = NUL;
        !           261: }
        !           262:
        !           263:
        !           264: /*
        !           265:  * m_capture() is similar to capture(), but it mallocs storage for the
        !           266:  * string.
        !           267:  */
        !           268: void m_capture(str, start, end)
        !           269: char **str;
        !           270: int start, end;
        !           271: {
        !           272:     register int i, e;
        !           273:     register char *s;
        !           274:
        !           275:     if (*str)                  /* previous pointer to malloc'd memory there */
        !           276:        free(*str);
        !           277:     e = token[end].start_index + token[end].length;
        !           278:     *str = gp_alloc((unsigned long) (e - token[start].start_index + 1), "string");
        !           279:     s = *str;
        !           280:     for (i = token[start].start_index; i < e && input_line[i] != NUL; i++)
        !           281:        *s++ = input_line[i];
        !           282:     *s = NUL;
        !           283: }
        !           284:
        !           285:
        !           286: /*
        !           287:  *    m_quote_capture() is similar to m_capture(), but it removes
        !           288:  quotes from either end if the string.
        !           289:  */
        !           290: void m_quote_capture(str, start, end)
        !           291: char **str;
        !           292: int start, end;
        !           293: {
        !           294:     register int i, e, escflag = 0;
        !           295:     register char *s;
        !           296:
        !           297:     if (*str)                  /* previous pointer to malloc'd memory there */
        !           298:        free(*str);
        !           299:     e = token[end].start_index + token[end].length - 1;
        !           300:     *str = gp_alloc((unsigned long) (e - token[start].start_index + 1), "string");
        !           301:     s = *str;
        !           302:     for (i = token[start].start_index + 1; i < e && input_line[i] != NUL; i++)
        !           303:        if ((*s++ = input_line[i]) == '\\') ++escflag;
        !           304:     *s = NUL;
        !           305:     if (escflag) parse_esc(*str);
        !           306: }
        !           307:
        !           308:
        !           309: void convert(val_ptr, t_num)
        !           310: struct value *val_ptr;
        !           311: int t_num;
        !           312: {
        !           313:     *val_ptr = token[t_num].l_val;
        !           314: }
        !           315:
        !           316: static char *num_to_str(r)
        !           317: double r;
        !           318: {
        !           319:     static int i = 0;
        !           320:     static char s[4][25];
        !           321:     int j = i++;
        !           322:
        !           323:     if (i > 3)
        !           324:        i = 0;
        !           325:
        !           326:     sprintf(s[j], "%.15g", r);
        !           327:     if (strchr(s[j], '.') == NULL &&
        !           328:        strchr(s[j], 'e') == NULL &&
        !           329:        strchr(s[j], 'E') == NULL)
        !           330:        strcat(s[j], ".0");
        !           331:
        !           332:     return s[j];
        !           333: }
        !           334:
        !           335: void disp_value(fp, val)
        !           336: FILE *fp;
        !           337: struct value *val;
        !           338: {
        !           339:     switch (val->type) {
        !           340:     case INTGR:
        !           341:        fprintf(fp, "%d", val->v.int_val);
        !           342:        break;
        !           343:     case CMPLX:
        !           344:        if (val->v.cmplx_val.imag != 0.0)
        !           345:            fprintf(fp, "{%s, %s}",
        !           346:                    num_to_str(val->v.cmplx_val.real),
        !           347:                    num_to_str(val->v.cmplx_val.imag));
        !           348:        else
        !           349:            fprintf(fp, "%s",
        !           350:                    num_to_str(val->v.cmplx_val.real));
        !           351:        break;
        !           352:     default:
        !           353:        int_error("unknown type in disp_value()", NO_CARET);
        !           354:     }
        !           355: }
        !           356:
        !           357:
        !           358: double real(val)               /* returns the real part of val */
        !           359: struct value *val;
        !           360: {
        !           361:     switch (val->type) {
        !           362:     case INTGR:
        !           363:        return ((double) val->v.int_val);
        !           364:     case CMPLX:
        !           365:        return (val->v.cmplx_val.real);
        !           366:     }
        !           367:     int_error("unknown type in real()", NO_CARET);
        !           368:     /* NOTREACHED */
        !           369:     return ((double) 0.0);
        !           370: }
        !           371:
        !           372:
        !           373: double imag(val)               /* returns the imag part of val */
        !           374: struct value *val;
        !           375: {
        !           376:     switch (val->type) {
        !           377:     case INTGR:
        !           378:        return (0.0);
        !           379:     case CMPLX:
        !           380:        return (val->v.cmplx_val.imag);
        !           381:     }
        !           382:     int_error("unknown type in imag()", NO_CARET);
        !           383:     /* NOTREACHED */
        !           384:     return ((double) 0.0);
        !           385: }
        !           386:
        !           387:
        !           388:
        !           389: double magnitude(val)          /* returns the magnitude of val */
        !           390: struct value *val;
        !           391: {
        !           392:     switch (val->type) {
        !           393:     case INTGR:
        !           394:        return ((double) abs(val->v.int_val));
        !           395:     case CMPLX:
        !           396:        return (sqrt(val->v.cmplx_val.real *
        !           397:                     val->v.cmplx_val.real +
        !           398:                     val->v.cmplx_val.imag *
        !           399:                     val->v.cmplx_val.imag));
        !           400:     }
        !           401:     int_error("unknown type in magnitude()", NO_CARET);
        !           402:     /* NOTREACHED */
        !           403:     return ((double) 0.0);
        !           404: }
        !           405:
        !           406:
        !           407:
        !           408: double angle(val)              /* returns the angle of val */
        !           409: struct value *val;
        !           410: {
        !           411:     switch (val->type) {
        !           412:     case INTGR:
        !           413:        return ((val->v.int_val >= 0) ? 0.0 : Pi);
        !           414:     case CMPLX:
        !           415:        if (val->v.cmplx_val.imag == 0.0) {
        !           416:            if (val->v.cmplx_val.real >= 0.0)
        !           417:                return (0.0);
        !           418:            else
        !           419:                return (Pi);
        !           420:        }
        !           421:        return (atan2(val->v.cmplx_val.imag,
        !           422:                      val->v.cmplx_val.real));
        !           423:     }
        !           424:     int_error("unknown type in angle()", NO_CARET);
        !           425:     /* NOTREACHED */
        !           426:     return ((double) 0.0);
        !           427: }
        !           428:
        !           429:
        !           430: struct value *
        !           431:  Gcomplex(a, realpart, imagpart)
        !           432: struct value *a;
        !           433: double realpart, imagpart;
        !           434: {
        !           435:     a->type = CMPLX;
        !           436:     a->v.cmplx_val.real = realpart;
        !           437:     a->v.cmplx_val.imag = imagpart;
        !           438:     return (a);
        !           439: }
        !           440:
        !           441:
        !           442: struct value *
        !           443:  Ginteger(a, i)
        !           444: struct value *a;
        !           445: int i;
        !           446: {
        !           447:     a->type = INTGR;
        !           448:     a->v.int_val = i;
        !           449:     return (a);
        !           450: }
        !           451:
        !           452:
        !           453: void os_error(str, t_num)
        !           454: char str[];
        !           455: int t_num;
        !           456: {
        !           457: #ifdef VMS
        !           458:     static status[2] =
        !           459:     {1, 0};                    /* 1 is count of error msgs */
        !           460: #endif /* VMS */
        !           461:
        !           462:     register int i;
        !           463:
        !           464:     /* reprint line if screen has been written to */
        !           465:
        !           466:     if (t_num != NO_CARET) {   /* put caret under error */
        !           467:        if (!screen_ok)
        !           468:            fprintf(stderr, "\n%s%s\n", PROMPT, input_line);
        !           469:
        !           470:        for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           471:            (void) putc(' ', stderr);
        !           472:        for (i = 0; i < token[t_num].start_index; i++) {
        !           473:            (void) putc((input_line[i] == '\t') ? '\t' : ' ', stderr);
        !           474:        }
        !           475:        (void) putc('^', stderr);
        !           476:        (void) putc('\n', stderr);
        !           477:     }
        !           478:     for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           479:        (void) putc(' ', stderr);
        !           480:     fputs(str, stderr);
        !           481:     putc('\n', stderr);
        !           482:
        !           483:     for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           484:        (void) putc(' ', stderr);
        !           485:     if (!interactive) {
        !           486:        if (infile_name != NULL)
        !           487:            fprintf(stderr, "\"%s\", line %d: ", infile_name, inline_num);
        !           488:        else
        !           489:            fprintf(stderr, "line %d: ", inline_num);
        !           490:     }
        !           491:
        !           492:
        !           493: #ifdef VMS
        !           494:     status[1] = vaxc$errno;
        !           495:     sys$putmsg(status);
        !           496:     (void) putc('\n', stderr);
        !           497: #else /* VMS */
        !           498:     fprintf(stderr, "(%s)\n\n", strerror(errno));
        !           499: #endif /* VMS */
        !           500:
        !           501:     bail_to_command_line();
        !           502: }
        !           503:
        !           504:
        !           505: void int_error(str, t_num)
        !           506: char str[];
        !           507: int t_num;
        !           508: {
        !           509:     register int i;
        !           510:
        !           511:     /* reprint line if screen has been written to */
        !           512:
        !           513:     if (t_num != NO_CARET) {   /* put caret under error */
        !           514:        if (!screen_ok)
        !           515:            fprintf(stderr, "\n%s%s\n", PROMPT, input_line);
        !           516:
        !           517:        for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           518:            (void) putc(' ', stderr);
        !           519:        for (i = 0; i < token[t_num].start_index; i++) {
        !           520:            (void) putc((input_line[i] == '\t') ? '\t' : ' ', stderr);
        !           521:        }
        !           522:        (void) putc('^', stderr);
        !           523:        (void) putc('\n', stderr);
        !           524:     }
        !           525:     for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           526:        (void) putc(' ', stderr);
        !           527:     if (!interactive) {
        !           528:        if (infile_name != NULL)
        !           529:            fprintf(stderr, "\"%s\", line %d: ", infile_name, inline_num);
        !           530:        else
        !           531:            fprintf(stderr, "line %d: ", inline_num);
        !           532:     }
        !           533:     fputs(str, stderr);
        !           534:     fputs("\n\n", stderr);
        !           535:
        !           536:     bail_to_command_line();
        !           537: }
        !           538:
        !           539: /* Warn without bailing out to command line. Not a user error */
        !           540: void int_warn(str, t_num)
        !           541: char str[];
        !           542: int t_num;
        !           543: {
        !           544:     register int i;
        !           545:
        !           546:     /* reprint line if screen has been written to */
        !           547:
        !           548:     if (t_num != NO_CARET) {   /* put caret under error */
        !           549:        if (!screen_ok)
        !           550:            fprintf(stderr, "\n%s%s\n", PROMPT, input_line);
        !           551:
        !           552:        for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           553:            (void) putc(' ', stderr);
        !           554:        for (i = 0; i < token[t_num].start_index; i++) {
        !           555:            (void) putc((input_line[i] == '\t') ? '\t' : ' ', stderr);
        !           556:        }
        !           557:        (void) putc('^', stderr);
        !           558:        (void) putc('\n', stderr);
        !           559:     }
        !           560:     for (i = 0; i < sizeof(PROMPT) - 1; i++)
        !           561:        (void) putc(' ', stderr);
        !           562:     if (!interactive) {
        !           563:        if (infile_name != NULL)
        !           564:            fprintf(stderr, "\"%s\", line %d: ", infile_name, inline_num);
        !           565:        else
        !           566:            fprintf(stderr, "line %d: ", inline_num);
        !           567:     }
        !           568:     fprintf(stderr, "warning: %s\n", str);
        !           569:
        !           570: }                              /* int_warn */
        !           571:
        !           572: /* Lower-case the given string (DFK) */
        !           573: /* Done in place. */
        !           574: void lower_case(s)
        !           575: char *s;
        !           576: {
        !           577:     register char *p = s;
        !           578:
        !           579:     while (*p != NUL) {
        !           580:        if (isupper((int)*p))
        !           581:            *p = tolower(*p);
        !           582:        p++;
        !           583:     }
        !           584: }
        !           585:
        !           586: /* Squash spaces in the given string (DFK) */
        !           587: /* That is, reduce all multiple white-space chars to single spaces */
        !           588: /* Done in place. */
        !           589: void squash_spaces(s)
        !           590: char *s;
        !           591: {
        !           592:     register char *r = s;      /* reading point */
        !           593:     register char *w = s;      /* writing point */
        !           594:     TBOOLEAN space = FALSE;    /* TRUE if we've already copied a space */
        !           595:
        !           596:     for (w = r = s; *r != NUL; r++) {
        !           597:        if (isspace((int)*r)) {
        !           598:            /* white space; only copy if we haven't just copied a space */
        !           599:            if (!space) {
        !           600:                space = TRUE;
        !           601:                *w++ = ' ';
        !           602:            }                   /* else ignore multiple spaces */
        !           603:        } else {
        !           604:            /* non-space character; copy it and clear flag */
        !           605:            *w++ = *r;
        !           606:            space = FALSE;
        !           607:        }
        !           608:     }
        !           609:     *w = NUL;                  /* null terminate string */
        !           610: }
        !           611:
        !           612:
        !           613: static void parse_esc(instr)
        !           614: char *instr;
        !           615: {
        !           616:     char *s = instr, *t = instr;
        !           617:
        !           618:     /* the string will always get shorter, so we can do the
        !           619:      * conversion in situ
        !           620:      */
        !           621:
        !           622:     while (*s != NUL) {
        !           623:        if (*s == '\\') {
        !           624:            s++;
        !           625:            if (*s == '\\') {
        !           626:                *t++ = '\\';
        !           627:                s++;
        !           628:            } else if (*s == 'n') {
        !           629:                *t++ = '\n';
        !           630:                s++;
        !           631:            } else if (*s == 'r') {
        !           632:                *t++ = '\r';
        !           633:                s++;
        !           634:            } else if (*s == 't') {
        !           635:                *t++ = '\t';
        !           636:                s++;
        !           637:            } else if (*s == '\"') {
        !           638:                *t++ = '\"';
        !           639:                s++;
        !           640:            } else if (*s >= '0' && *s <= '7') {
        !           641:                int i, n;
        !           642:                if (sscanf(s, "%o%n", &i, &n) > 0) {
        !           643:                    *t++ = i;
        !           644:                    s += n;
        !           645:                } else {
        !           646:                    /* int_error("illegal octal number ", c_token); */
        !           647:                    *t++ = '\\';
        !           648:                    *t++ = *s++;
        !           649:                }
        !           650:            }
        !           651:        } else {
        !           652:            *t++ = *s++;
        !           653:        }
        !           654:     }
        !           655:     *t = NUL;
        !           656: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>