Annotation of gdb/valprint.c, revision 1.1.1.2

1.1       root        1: /* Print values for GNU debugger gdb.
                      2:    Copyright (C) 1986 Free Software Foundation, Inc.
                      3: 
                      4: GDB is distributed in the hope that it will be useful, but WITHOUT ANY
                      5: WARRANTY.  No author or distributor accepts responsibility to anyone
                      6: for the consequences of using it or for whether it serves any
                      7: particular purpose or works at all, unless he says so in writing.
                      8: Refer to the GDB General Public License for full details.
                      9: 
                     10: Everyone is granted permission to copy, modify and redistribute GDB,
                     11: but only under the conditions described in the GDB General Public
                     12: License.  A copy of this license is supposed to have been given to you
                     13: along with GDB so you can know your rights and responsibilities.  It
                     14: should be in a file named COPYING.  Among other things, the copyright
                     15: notice and this notice must be preserved on all copies.
                     16: 
                     17: In other words, go ahead and share GDB, but don't try to stop
                     18: anyone else from sharing it farther.  Help stamp out software hoarding!
                     19: */
                     20: 
                     21: #include <stdio.h>
                     22: #include "defs.h"
                     23: #include "initialize.h"
                     24: #include "symtab.h"
                     25: #include "value.h"
                     26: 
                     27: /* Maximum number of chars to print for a string pointer value
                     28:    or vector contents.  */
                     29: 
                     30: static int print_max;
                     31: 
                     32: static void type_print_varspec_suffix ();
                     33: static void type_print_varspec_prefix ();
                     34: static void type_print_base ();
                     35: 
                     36: START_FILE
                     37: 
                     38: char **unsigned_type_table;
                     39: char **signed_type_table;
                     40: char **float_type_table;
                     41: 
                     42: /* Print the value VAL in C-ish syntax on stream STREAM.
                     43:    If the object printed is a string pointer, returns
                     44:    the number of string bytes printed.  */
                     45: 
                     46: value_print (val, stream)
                     47:      value val;
                     48:      FILE *stream;
                     49: {
                     50:   register int i, n, typelen;
                     51: 
                     52:   /* A "repeated" value really contains several values in a row.
                     53:      They are made by the @ operator.
                     54:      Print such values as if they were arrays.  */
                     55: 
                     56:   if (VALUE_REPEATED (val))
                     57:     {
                     58:       n = VALUE_REPETITIONS (val);
                     59:       typelen = TYPE_LENGTH (VALUE_TYPE (val));
                     60:       fputc ('{', stream);
                     61:       /* Print arrays of characters using string syntax.  */
                     62:       if (VALUE_TYPE (val) == builtin_type_char
                     63:          || VALUE_TYPE (val) == builtin_type_unsigned_char)
                     64:        {
                     65:          fputc ('"', stream);
                     66:          for (i = 0; i < n && i < print_max; i++)
                     67:            {
                     68:              QUIT;
                     69:              printchar (VALUE_CONTENTS (val)[i], stream);
                     70:            }
                     71:          if (i < n)
                     72:            fprintf (stream, "...");
                     73:          fputc ('"', stream);
                     74:        }
                     75:       else
                     76:        {
                     77:          for (i = 0; i < n && i < print_max; i++)
                     78:            {
                     79:              if (i)
                     80:                fprintf (stream, ", ");
                     81:              val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i,
                     82:                         VALUE_ADDRESS (val) + typelen * i, stream);
                     83:            }
                     84:          if (i < n)
                     85:            fprintf (stream, "...");
                     86:        }
                     87:       fputc ('}', stream);
                     88:     }
                     89:   else
                     90:     {
                     91:       /* A simple (nonrepeated) value */
                     92:       /* If it is a pointer, indicate what it points to.  */
                     93:       if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR)
                     94:        {
                     95:          fprintf (stream, "(");
                     96:          type_print (VALUE_TYPE (val), "", stream, -1);
                     97:          fprintf (stream, ") ");
                     98:        }
                     99:       return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
                    100:                        VALUE_ADDRESS (val), stream);
                    101:     }
                    102: }
                    103: 
                    104: /* Print on STREAM data stored in debugger at address VALADDR
                    105:    according to the format of type TYPE.
                    106:    ADDRESS is the location in the inferior that the data
                    107:    is supposed to have come from.
                    108: 
                    109:    If the data are a string pointer, returns the number of
                    110:    sting characters printed.  */
                    111: 
                    112: int
                    113: val_print (type, valaddr, address, stream)
                    114:      struct type *type;
                    115:      char *valaddr;
                    116:      CORE_ADDR address;
                    117:      FILE *stream;
                    118: {
                    119:   register int i;
                    120:   int len;
                    121:   struct type *elttype;
                    122:   int eltlen;
                    123:   int val;
                    124:   unsigned char c;
                    125: 
                    126:   QUIT;
                    127: 
                    128:   switch (TYPE_CODE (type))
                    129:     {
                    130:     case TYPE_CODE_ARRAY:
                    131:       if (TYPE_LENGTH (type) >= 0)
                    132:        {
                    133:          elttype = TYPE_TARGET_TYPE (type);
                    134:          eltlen = TYPE_LENGTH (elttype);
                    135:          len = TYPE_LENGTH (type) / eltlen;
                    136:          fprintf (stream, "{");
                    137:          /* For an array of chars, print with string syntax.  */
                    138:          if (elttype == builtin_type_char
                    139:              || elttype == builtin_type_unsigned_char)
                    140:            {
                    141:              fputc ('"', stream);
                    142:              for (i = 0; i < len && i < print_max; i++)
                    143:                {
                    144:                  QUIT;
                    145:                  printchar (valaddr[i], stream);
                    146:                }
                    147:              if (i < len)
                    148:                fprintf (stream, "...");
                    149:              fputc ('"', stream);
                    150:            }
                    151:          else
                    152:            {
                    153:              for (i = 0; i < len && i < print_max; i++)
                    154:                {
                    155:                  if (i) fprintf (stream, ", ");
                    156:                  val_print (elttype, valaddr + i * eltlen,
                    157:                             0, stream);
                    158:                }
                    159:              if (i < len)
                    160:                fprintf (stream, "...");
                    161:            }
                    162:          fprintf (stream, "}");
                    163:          break;
                    164:        }
                    165:       /* Array of unspecified length: treat like pointer.  */
                    166: 
                    167:     case TYPE_CODE_PTR:
                    168:       fprintf (stream, "0x%x", * (int *) valaddr);
                    169:       /* For a pointer to char or unsigned char,
                    170:         also print the string pointed to, unless pointer is null.  */
                    171:       if ((TYPE_TARGET_TYPE (type) == builtin_type_char
                    172:           || TYPE_TARGET_TYPE (type) == builtin_type_unsigned_char)
                    173:          && unpack_long (type, valaddr) != 0)
                    174:        {
                    175:          fputc (' ', stream);
                    176:          fputc ('"', stream);
                    177:          for (i = 0; i < print_max; i++)
                    178:            {
                    179:              QUIT;
                    180:              read_memory (unpack_long (type, valaddr) + i, &c, 1);
                    181:              if (c == 0)
                    182:                break;
                    183:              printchar (c, stream);
                    184:            }
                    185:          fputc ('"', stream);
                    186:          if (i == print_max)
                    187:            fprintf (stream, "...");
                    188:          fflush (stream);
                    189:          /* Return number of characters printed, plus one for the
                    190:             terminating null if we have "reached the end".  */
                    191:          return i + (i != print_max);
                    192:        }
                    193:       break;
                    194: 
                    195:     case TYPE_CODE_STRUCT:
                    196:     case TYPE_CODE_UNION:
                    197:       fprintf (stream, "{");
                    198:       len = TYPE_NFIELDS (type);
                    199:       for (i = 0; i < len; i++)
                    200:        {
                    201:          if (i) fprintf (stream, ", ");
                    202:          fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
                    203:          if (TYPE_FIELD_PACKED (type, i))
                    204:            {
                    205:              val = unpack_field_as_long (type, valaddr, i);
                    206:              val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream);
                    207:            }
                    208:          else
                    209:            val_print (TYPE_FIELD_TYPE (type, i), 
                    210:                       valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
                    211:                       0, stream);
                    212:        }
                    213:       fprintf (stream, "}");
                    214:       break;
                    215: 
                    216:     case TYPE_CODE_ENUM:
                    217:       len = TYPE_NFIELDS (type);
                    218:       val = unpack_long (builtin_type_int, valaddr);
                    219:       for (i = 0; i < len; i++)
                    220:        {
                    221:          QUIT;
                    222:          if (val == TYPE_FIELD_VALUE (type, i))
                    223:            break;
                    224:        }
                    225:       if (i < len)
                    226:        fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
                    227:       else
                    228:        fprintf (stream, "%d", val);
                    229:       break;
                    230: 
                    231:     case TYPE_CODE_FUNC:
                    232:       fprintf (stream, "{");
                    233:       type_print (type, "", stream, -1);
                    234:       fprintf (stream, "} ");
                    235:       fprintf (stream, "0x%x", address);
                    236:       break;
                    237: 
                    238:     case TYPE_CODE_INT:
                    239:       fprintf (stream,
                    240:               TYPE_UNSIGNED (type) ? "%u" : "%d",
                    241:               unpack_long (type, valaddr));
                    242:       if (type == builtin_type_char
                    243:          || type == builtin_type_unsigned_char)
                    244:        {
                    245:          fprintf (stream, " '");
                    246:          printchar (unpack_long (type, valaddr), stream);
                    247:          fputc ('\'', stream);
                    248:        }
                    249:       break;
                    250: 
                    251:     case TYPE_CODE_FLT:
1.1.1.2 ! root      252: #ifdef IEEE_FLOAT
        !           253:       if (is_nan (unpack_double (type, valaddr)))
        !           254:        {
        !           255:          fprintf (stream, "Nan");
        !           256:          break;
        !           257:        }
        !           258: #endif
1.1       root      259:       fprintf (stream, "%g", unpack_double (type, valaddr));
                    260:       break;
                    261: 
                    262:     case TYPE_CODE_VOID:
                    263:       fprintf (stream, "void");
                    264:       break;
                    265: 
                    266:     default:
                    267:       error ("Invalid type code in symbol table.");
                    268:     }
                    269:   fflush (stream);
                    270: }
                    271: 
1.1.1.2 ! root      272: #ifdef IEEE_FLOAT
        !           273: 
        !           274: union ieee {
        !           275:   int i[2];
        !           276:   double d;
        !           277: };
        !           278: 
        !           279: /* Nonzero if ARG (a double) is a NAN.  */
        !           280: 
        !           281: int
        !           282: is_nan (arg)
        !           283:      union ieee arg;
        !           284: {
        !           285:   int lowhalf, highhalf;
        !           286:   union { int i; char c; } test;
        !           287: 
        !           288:   /* Separate the high and low words of the double.
        !           289:      Distinguish big and little-endian machines.  */
        !           290:   test.i = 1;
        !           291:   if (test.c != 1)
        !           292:     /* Big-endian machine */
        !           293:     lowhalf = arg.i[1], highhalf = arg.i[0];
        !           294:   else
        !           295:     lowhalf = arg.i[0], highhalf = arg.i[1];
        !           296: 
        !           297:   /* Nan: exponent is the maximum possible, and fraction is nonzero.  */
        !           298:   return (((highhalf>>20) & 0x7ff) == 0x7ff
        !           299:          &&
        !           300:          ! ((highhalf & 0xfffff == 0) && (lowhalf == 0)));
        !           301: }
        !           302: #endif
        !           303: 
1.1       root      304: /* Print a description of a type TYPE
                    305:    in the form of a declaration of a variable named VARSTRING.
                    306:    Output goes to STREAM (via stdio).
                    307:    If SHOW is positive, we show the contents of the outermost level
                    308:    of structure even if there is a type name that could be used instead.
                    309:    If SHOW is negative, we never show the details of elements' types.  */
                    310: 
                    311: type_print (type, varstring, stream, show)
                    312:      struct type *type;
                    313:      char *varstring;
                    314:      FILE *stream;
                    315:      int show;
                    316: {
                    317:   type_print_1 (type, varstring, stream, show, 0);
                    318: }
                    319: 
                    320: /* LEVEL is the depth to indent lines by.  */
                    321: 
                    322: type_print_1 (type, varstring, stream, show, level)
                    323:      struct type *type;
                    324:      char *varstring;
                    325:      FILE *stream;
                    326:      int show;
                    327:      int level;
                    328: {
                    329:   register enum type_code code;
                    330:   type_print_base (type, stream, show, level);
                    331:   code = TYPE_CODE (type);
                    332:   if ((varstring && *varstring)
                    333:       ||
                    334:       /* Need a space if going to print stars or brackets;
                    335:         but not if we will print just a type name.  */
                    336:       ((show > 0 || TYPE_NAME (type) == 0)
                    337:        &&
                    338:        (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
                    339:        || code == TYPE_CODE_ARRAY)))
                    340:     fprintf (stream, " ");
                    341:   type_print_varspec_prefix (type, stream, show, 0);
                    342:   fprintf (stream, "%s", varstring);
                    343:   type_print_varspec_suffix (type, stream, show, 0);
                    344: }
                    345: 
                    346: /* Print any asterisks or open-parentheses needed before the
                    347:    variable name (to describe its type).
                    348: 
                    349:    On outermost call, pass 0 for PASSED_A_PTR.
                    350:    On outermost call, SHOW > 0 means should ignore
                    351:    any typename for TYPE and show its details.
                    352:    SHOW is always zero on recursive calls.  */
                    353: 
                    354: static void
                    355: type_print_varspec_prefix (type, stream, show, passed_a_ptr)
                    356:      struct type *type;
                    357:      FILE *stream;
                    358:      int show;
                    359:      int passed_a_ptr;
                    360: {
                    361:   if (TYPE_NAME (type) && show <= 0)
                    362:     return;
                    363: 
                    364:   QUIT;
                    365: 
                    366:   switch (TYPE_CODE (type))
                    367:     {
                    368:     case TYPE_CODE_PTR:
                    369:       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
                    370:       fputc ('*', stream);
                    371:       break;
                    372: 
                    373:     case TYPE_CODE_FUNC:
1.1.1.2 ! root      374:     case TYPE_CODE_ARRAY:
        !           375:       type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0);
1.1       root      376:       if (passed_a_ptr)
                    377:        fputc ('(', stream);
                    378:       break;
                    379:     }
                    380: }
                    381: 
                    382: /* Print any array sizes, function arguments or close parentheses
                    383:    needed after the variable name (to describe its type).
                    384:    Args work like type_print_varspec_prefix.  */
                    385: 
                    386: static void
                    387: type_print_varspec_suffix (type, stream, show, passed_a_ptr)
                    388:      struct type *type;
                    389:      FILE *stream;
                    390:      int show;
                    391:      int passed_a_ptr;
                    392: {
                    393:   if (TYPE_NAME (type) && show <= 0)
                    394:     return;
                    395: 
                    396:   QUIT;
                    397: 
                    398:   switch (TYPE_CODE (type))
                    399:     {
                    400:     case TYPE_CODE_ARRAY:
1.1.1.2 ! root      401:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
        !           402:       if (passed_a_ptr)
        !           403:        fprintf (stream, ")");
1.1       root      404:       fprintf (stream, "[");
                    405:       if (TYPE_LENGTH (type) >= 0)
                    406:        fprintf (stream, "%d",
                    407:                 TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
                    408:       fprintf (stream, "]");
                    409:       break;
                    410: 
                    411:     case TYPE_CODE_PTR:
                    412:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
                    413:       break;
                    414: 
                    415:     case TYPE_CODE_FUNC:
1.1.1.2 ! root      416:       type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
1.1       root      417:       if (passed_a_ptr)
                    418:        fprintf (stream, ")");
                    419:       fprintf (stream, "()");
                    420:       break;
                    421:     }
                    422: }
                    423: 
                    424: /* Print the name of the type (or the ultimate pointer target,
                    425:    function value or array element), or the description of a
                    426:    structure or union.
                    427: 
                    428:    SHOW nonzero means don't print this type as just its name;
                    429:    show its real definition even if it has a name.
                    430:    SHOW zero means print just typename or struct tag if there is one
                    431:    SHOW negative means abbreviate structure elements.
                    432:    SHOW is decremented for printing of structure elements.
                    433: 
                    434:    LEVEL is the depth to indent by.
                    435:    We increase it for some recursive calls.  */
                    436: 
                    437: static void
                    438: type_print_base (type, stream, show, level)
                    439:      struct type *type;
                    440:      FILE *stream;
                    441:      int show;
                    442:      int level;
                    443: {
                    444:   char *name;
                    445:   register int i;
                    446:   register int len;
                    447:   register int lastval;
                    448: 
                    449:   QUIT;
                    450: 
                    451:   if (TYPE_NAME (type) && show <= 0)
                    452:     {
                    453:       fprintf (stream, TYPE_NAME (type));
                    454:       return;
                    455:     }
                    456: 
                    457:   switch (TYPE_CODE (type))
                    458:     {
                    459:     case TYPE_CODE_ARRAY:
                    460:     case TYPE_CODE_PTR:
                    461:     case TYPE_CODE_FUNC:
                    462:       type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
                    463:       break;
                    464: 
                    465:     case TYPE_CODE_STRUCT:
                    466:       fprintf (stream, "struct ");
                    467:       goto struct_union;
                    468: 
                    469:     case TYPE_CODE_UNION:
                    470:       fprintf (stream, "union ");
                    471:     struct_union:
                    472:       if (TYPE_NAME (type) && (name = TYPE_NAME (type)))
                    473:        {
                    474:          while (*name != ' ') name++;
                    475:          fprintf (stream, "%s ", name + 1);
                    476:        }
                    477:       if (show < 0)
                    478:        fprintf (stream, "{...}");
                    479:       else
                    480:        {
                    481:          fprintf (stream, "{");
                    482:          len = TYPE_NFIELDS (type);
                    483:          fprintf (stream, "\n");
                    484:          for (i = 0; i < len; i++)
                    485:            {
                    486:              QUIT;
                    487:              print_spaces (level + 4, stream);
1.1.1.2 ! root      488: 
        !           489:              /* If this is a bit-field and there is a gap before it,
        !           490:                 print a nameless field to account for the gap.  */
        !           491: 
        !           492:              if (TYPE_FIELD_PACKED (type, i))
        !           493:                {
        !           494:                  int gap = (TYPE_FIELD_BITPOS (type, i)
        !           495:                             - (i > 0
        !           496:                                ? (TYPE_FIELD_BITPOS (type, i - 1)
        !           497:                                   + (TYPE_FIELD_PACKED (type, i - 1)
        !           498:                                      ? TYPE_FIELD_BITSIZE (type, i - 1)
        !           499:                                      : TYPE_LENGTH (TYPE_FIELD_TYPE (type, i - 1)) * 8))
        !           500:                                : 0));
        !           501:                  if (gap != 0)
        !           502:                    {
        !           503:                      fprintf (stream, "int : %d;\n", gap);
        !           504:                      print_spaces (level + 4, stream);
        !           505:                    }
        !           506:                }
        !           507: 
        !           508:              /* Print the declaration of this field.  */
        !           509: 
1.1       root      510:              type_print_1 (TYPE_FIELD_TYPE (type, i),
                    511:                            TYPE_FIELD_NAME (type, i),
                    512:                            stream, show - 1, level + 4);
1.1.1.2 ! root      513: 
        !           514:              /* Print the field width.  */
        !           515: 
1.1       root      516:              if (TYPE_FIELD_PACKED (type, i))
1.1.1.2 ! root      517:                fprintf (stream, " : %d", TYPE_FIELD_BITSIZE (type, i));
        !           518: 
1.1       root      519:              fprintf (stream, ";\n");
                    520:            }
                    521:          print_spaces (level, stream);
                    522:          fputc ('}', stream);
                    523:        }
                    524:       break;
                    525: 
                    526:     case TYPE_CODE_ENUM:
                    527:       fprintf (stream, "enum ");
                    528:       if (TYPE_NAME (type))
                    529:        {
                    530:          name = TYPE_NAME (type);
                    531:          while (*name != ' ') name++;
                    532:          fprintf (stream, "%s ", name + 1);
                    533:        }
                    534:       if (show < 0)
                    535:        fprintf (stream, "{...}");
                    536:       else
                    537:        {
                    538:          fprintf (stream, "{");
                    539:          len = TYPE_NFIELDS (type);
                    540:          lastval = 0;
                    541:          for (i = 0; i < len; i++)
                    542:            {
                    543:              QUIT;
                    544:              if (i) fprintf (stream, ", ");
                    545:              fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
                    546:              if (lastval != TYPE_FIELD_VALUE (type, i))
                    547:                {
                    548:                  fprintf (stream, " : %d", TYPE_FIELD_VALUE (type, i));
                    549:                  lastval = TYPE_FIELD_VALUE (type, i);
                    550:                }
                    551:              lastval++;
                    552:            }
                    553:          fprintf (stream, "}");
                    554:        }
                    555:       break;
                    556: 
                    557:     case TYPE_CODE_INT:
                    558:       if (TYPE_UNSIGNED (type))
                    559:        name = unsigned_type_table[TYPE_LENGTH (type)];
                    560:       else
                    561:        name = signed_type_table[TYPE_LENGTH (type)];
                    562:       fprintf (stream, "%s", name);
                    563:       break;
                    564: 
                    565:     case TYPE_CODE_FLT:
                    566:       name = float_type_table[TYPE_LENGTH (type)];
                    567:       fprintf (stream, "%s", name);
                    568:       break;
                    569: 
                    570:     case TYPE_CODE_VOID:
                    571:       fprintf (stream, "void");
                    572:       break;
                    573: 
                    574:     case 0:
                    575:       fprintf (stream, "struct unknown");
                    576:       break;
                    577: 
                    578:     default:
                    579:       error ("Invalid type code in symbol table.");
                    580:     }
                    581: }
                    582: 
                    583: static void
                    584: set_maximum_command (arg)
                    585:      char *arg;
                    586: {
                    587:   if (!arg) error_no_arg ("value for maximum elements to print");
                    588:   print_max = atoi (arg);
                    589: }
                    590: 
                    591: static
                    592: initialize ()
                    593: {
                    594:   add_com ("set-maximum", class_vars, set_maximum_command,
                    595:           "Set NUMBER as limit on string chars or array elements to print.");
                    596: 
                    597:   print_max = 200;
                    598: 
                    599:   unsigned_type_table
                    600:     = (char **) xmalloc ((1 + sizeof (unsigned long)) * sizeof (char *));
                    601:   bzero (unsigned_type_table, (1 + sizeof (unsigned long)));
                    602:   unsigned_type_table[sizeof (unsigned char)] = "unsigned char";
                    603:   unsigned_type_table[sizeof (unsigned short)] = "unsigned short";
                    604:   unsigned_type_table[sizeof (unsigned long)] = "unsigned long";
                    605:   unsigned_type_table[sizeof (unsigned int)] = "unsigned int";
                    606: 
                    607:   signed_type_table
                    608:     = (char **) xmalloc ((1 + sizeof (long)) * sizeof (char *));
                    609:   bzero (signed_type_table, (1 + sizeof (long)));
                    610:   signed_type_table[sizeof (char)] = "char";
                    611:   signed_type_table[sizeof (short)] = "short";
                    612:   signed_type_table[sizeof (long)] = "long";
                    613:   signed_type_table[sizeof (int)] = "int";
                    614: 
                    615:   float_type_table
                    616:     = (char **) xmalloc ((1 + sizeof (double)) * sizeof (char *));
                    617:   bzero (float_type_table, (1 + sizeof (double)));
                    618:   float_type_table[sizeof (float)] = "float";
                    619:   float_type_table[sizeof (double)] = "double";
                    620: }
                    621: 
                    622: END_FILE

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.