home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / cook.C < prev    next >
C/C++ Source or Header  |  1998-10-23  |  5KB  |  303 lines

  1. // $Id: cook.C,v 1.13 1998/10/23 13:08:42 zeller Exp $
  2. // Turn a string into C representation and back again
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of the ICE Library.
  8. // 
  9. // The ICE Library is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU Library General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // The ICE Library is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU Library General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU Library General Public
  20. // License along with the ICE Library -- see the file COPYING.LIB.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // ICE is the incremental configuration environment.
  25. // For details, see the ICE World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ice/',
  27. // or send a mail to the ICE developers <ice@ips.cs.tu-bs.de>.
  28.  
  29. char cook_rcsid[] =
  30.     "$Id: cook.C,v 1.13 1998/10/23 13:08:42 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include <ctype.h>
  37. #include <strstream.h>
  38. #include <iomanip.h>
  39.  
  40. #include "bool.h"
  41. #include "cook.h"
  42.  
  43. // Transform RAW into C string
  44. string _cook(const string& raw, bool for_postscript)
  45. {
  46.     ostrstream cooked;
  47.     const char *raw_s = (char *)raw;
  48.  
  49.     for (unsigned i = 0; i < raw.length(); i++)
  50.     {
  51.     char cc = raw_s[i];
  52.     unsigned char c = (unsigned char)cc;
  53.  
  54.     switch(c) 
  55.     {
  56.     case '\a':
  57.         cooked << "\\a";
  58.         break;
  59.  
  60.     case '\b':
  61.         cooked << "\\b";
  62.         break;
  63.  
  64. #if 0                // This encoding is not ISO C
  65.     case '\033':
  66.         cooked << "\\e";
  67.         break;
  68. #endif
  69.  
  70.     case '\f':
  71.         cooked << "\\f";
  72.         break;
  73.  
  74.     case '\n':
  75.         cooked << "\\n";
  76.         break;
  77.  
  78.     case '\r':
  79.         cooked << "\\r";
  80.         break;
  81.  
  82.     case '\t':
  83.         cooked << "\\t";
  84.         break;
  85.  
  86.     case '\v':
  87.         cooked << "\\v";
  88.         break;
  89.  
  90.     case '\0':
  91.         cooked << "\\0";
  92.         break;
  93.         
  94.     case '(':
  95.     case ')':
  96.         if (!for_postscript)
  97.         goto standard;
  98.         goto quote;
  99.  
  100.     quote:
  101.     case '\"':
  102.     case '\'':
  103.     case '\\':
  104.         cooked << "\\";
  105.         cooked << c;
  106.         break;
  107.  
  108.     standard:
  109.     default:
  110.         if (isascii(c) && isprint(c))
  111.         cooked << c;
  112.         else
  113.         cooked << "\\" << oct << setw(3) << setfill('0') << int(c);
  114.         break;
  115.     }
  116.     }
  117.  
  118.     return string(cooked);
  119. }
  120.  
  121. // Return the digit represented by C
  122. static int digit(char c)
  123. {
  124.     switch(c)
  125.     {
  126.     case '0':
  127.     return 0;
  128.  
  129.     case '1':
  130.     return 1;
  131.  
  132.     case '2':
  133.     return 2;
  134.  
  135.     case '3':
  136.     return 3;
  137.  
  138.     case '4':
  139.     return 4;
  140.  
  141.     case '5':
  142.     return 5;
  143.  
  144.     case '6':
  145.     return 6;
  146.  
  147.     case '7':
  148.     return 7;
  149.  
  150.     case '8':
  151.     return 8;
  152.  
  153.     case '9':
  154.     return 9;
  155.  
  156.     case 'a':
  157.     case 'A':
  158.     return 10;
  159.  
  160.     case 'b':
  161.     case 'B':
  162.     return 11;
  163.  
  164.     case 'c':
  165.     case 'C':
  166.     return 12;
  167.  
  168.     case 'd':
  169.     case 'D':
  170.     return 13;
  171.  
  172.     case 'e':
  173.     case 'E':
  174.     return 14;
  175.  
  176.     case 'f':
  177.     case 'F':
  178.     return 15;
  179.  
  180.     default:
  181.     return -1;
  182.     }
  183. }
  184.  
  185. // Transform COOKED into C string
  186. string uncook(const string& cooked)
  187. {
  188.     ostrstream uncooked;
  189.     int n;
  190.     int count;
  191.  
  192.     char *i = cooked;
  193.     while (*i != '\0')
  194.     {
  195.     if (*i == '\\')
  196.     {
  197.         switch (*++i)
  198.         {
  199.         case '\n':
  200.         i++;
  201.         break;
  202.  
  203.         case 'a':
  204.         uncooked << '\a';
  205.         i++;
  206.         break;
  207.  
  208.         case 'b':
  209.         uncooked << '\b';
  210.         i++;
  211.         break;
  212.  
  213.         case 'e':        // GNU C extension
  214.         uncooked << '\033';
  215.         i++;
  216.         break;
  217.  
  218.         case 'f':
  219.         uncooked << '\f';
  220.         i++;
  221.         break;
  222.  
  223.         case 'n':
  224.         uncooked << '\n';
  225.         i++;
  226.         break;
  227.  
  228.         case 'r':
  229.         uncooked << '\r';
  230.         i++;
  231.         break;
  232.  
  233.         case 't':
  234.         uncooked << '\t';
  235.         i++;
  236.         break;
  237.  
  238.         case 'v':
  239.         uncooked << '\v';
  240.         i++;
  241.         break;
  242.  
  243.         case '0':
  244.         if (*(i + 1) == 'x')
  245.         {
  246.             i++;
  247.             goto hex;
  248.         }
  249.         // FALL THROUGH
  250.  
  251.         case '1': 
  252.         case '2': 
  253.         case '3':
  254.         case '4': 
  255.         case '5': 
  256.         case '6': 
  257.         case '7':
  258.         n = 0;
  259.         count = 0;
  260.         while (count++ < 3)
  261.         {
  262.             int d = digit(*i);
  263.             if (d < 0 || d >= 8)
  264.             break;
  265.  
  266.             n = (n << 3) + d;
  267.             i++;
  268.         }
  269.         uncooked << char(n);
  270.         break;
  271.  
  272.         hex:
  273.         case 'x':
  274.         n = 0;
  275.         count = 0;
  276.         i++;
  277.         while (count++ < 2)
  278.         {
  279.             int d = digit(*i);
  280.             if (d < 0 || d >= 16)
  281.             break;
  282.  
  283.             n = (n << 4) + d;
  284.             i++;
  285.         }
  286.         uncooked << char(n);
  287.         break;
  288.  
  289.         case '\"':
  290.         case '\'':
  291.         case '\\':
  292.         default:
  293.         uncooked << *i++;
  294.         break;
  295.         }
  296.     }
  297.     else
  298.         uncooked << *i++;
  299.     }
  300.  
  301.     return uncooked;
  302. }
  303.