home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / rexx / library2 / gbmrexx / gbm / gbmxbm.c < prev    next >
C/C++ Source or Header  |  1993-09-12  |  13KB  |  541 lines

  1. /*
  2.  
  3. GBMXBM.C  X Windows Bitmap support
  4.  
  5. Reads and writes most X bitmaps
  6.  
  7. */
  8.  
  9. /*...sincludes:0:*/
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <stddef.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <memory.h>
  16. #include <malloc.h>
  17. #ifdef AIX
  18. #include <unistd.h>
  19. #else
  20. #include <io.h>
  21. #endif
  22. #include <fcntl.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include "standard.h"
  26. #include "gbm.h"
  27.  
  28. /*...vgbm\46\h:0:*/
  29. /*...e*/
  30.  
  31. static GBMFT xbm_gbmft =
  32.     {
  33.     "XBitmap",
  34.     "X Windows Bitmap",
  35.     "XBM",
  36.     GBM_FT_R1|
  37.     GBM_FT_W1,
  38.     };
  39.  
  40. #define    GBM_ERR_XBM_EXP_ID    ((GBM_ERR) 1300)
  41. #define    GBM_ERR_XBM_UNEXP_EOF    ((GBM_ERR) 1301)
  42. #define    GBM_ERR_XBM_EXP_CHAR    ((GBM_ERR) 1302)
  43. #define    GBM_ERR_XBM_EXP_LSQR    ((GBM_ERR) 1303)
  44. #define    GBM_ERR_XBM_EXP_RSQR    ((GBM_ERR) 1304)
  45. #define    GBM_ERR_XBM_EXP_EQUALS    ((GBM_ERR) 1305)
  46. #define    GBM_ERR_XBM_EXP_LCUR    ((GBM_ERR) 1306)
  47. #define    GBM_ERR_XBM_EXP_RCUR    ((GBM_ERR) 1307)
  48. #define    GBM_ERR_XBM_EXP_COMMA    ((GBM_ERR) 1308)
  49. #define    GBM_ERR_XBM_EXP_NUMBER    ((GBM_ERR) 1309)
  50. #define    GBM_ERR_XBM_EXP_SEMI    ((GBM_ERR) 1310)
  51.  
  52. #define    MAX_BUF    1024
  53. #define    MAX_ID    100
  54.  
  55. typedef struct
  56.     {
  57.     int fd;
  58.     int inx, cnt;
  59.     byte buf [MAX_BUF];
  60.     byte id [MAX_ID+1];
  61.     int number;
  62.     int size;
  63.     } XBM_PRIV;
  64.  
  65. /*...srev:0:*/
  66. static byte rev [0x100] =
  67.     {
  68.     0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
  69.     0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
  70.     0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
  71.     0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
  72.     0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
  73.     0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
  74.     0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
  75.     0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
  76.     0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
  77.     0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
  78.     0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
  79.     0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
  80.     0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
  81.     0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
  82.     0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
  83.     0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
  84.     0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
  85.     0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
  86.     0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
  87.     0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
  88.     0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
  89.     0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
  90.     0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
  91.     0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
  92.     0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
  93.     0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
  94.     0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
  95.     0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
  96.     0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
  97.     0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
  98.     0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
  99.     0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
  100.     };
  101. /*...e*/
  102. /*...sbuffered text read:0:*/
  103. static int nextbuf(XBM_PRIV *xbm_priv)
  104.     {
  105.     int cnt;
  106.  
  107.     if ( (cnt = read(xbm_priv -> fd, xbm_priv -> buf, MAX_BUF)) <= 0 )
  108.         return ( -1 );
  109.     xbm_priv -> cnt = cnt;
  110.     xbm_priv -> inx = 1;
  111.     return ( xbm_priv -> buf [0] );
  112.     }
  113.  
  114. #define    nextchar(x) ( ((x)->inx<(x)->cnt) ? \
  115.     (int) (unsigned int) ((x)->buf[((x)->inx)++]) : nextbuf(x) )
  116.  
  117. static void pushchar(XBM_PRIV *xbm_priv, int c)
  118.     {
  119.     if ( c != -1 )
  120.         xbm_priv -> buf [--(xbm_priv -> inx)] = (byte) c;
  121.     }
  122.  
  123. typedef byte SYM;
  124. #define    S_DEFINE    ((SYM)  1)
  125. #define    S_ID        ((SYM)  2)
  126. #define    S_NUMBER    ((SYM)  3)
  127. #define    S_STATIC    ((SYM)  4)
  128. #define    S_CHAR        ((SYM)  5)
  129. #define    S_SHORT        ((SYM)  6)
  130. #define    S_LSQR        ((SYM)  7)
  131. #define    S_RSQR        ((SYM)  8)
  132. #define    S_LCUR        ((SYM)  9)
  133. #define    S_RCUR        ((SYM) 10)
  134. #define    S_COMMA        ((SYM) 11)
  135. #define    S_SEMI        ((SYM) 12)
  136. #define    S_EQUALS    ((SYM) 13)
  137. #define    S_EOF        ((SYM) 14)
  138. #define    S_ERROR_COMMENT    ((SYM) 15)
  139. #define    S_ERROR_ID    ((SYM) 16)
  140. #define    S_ERROR_MINUS    ((SYM) 17)
  141. #define    S_ERROR_NUMBER    ((SYM) 18)
  142.  
  143. static int valof(char c)
  144.     {
  145.     if ( c >= 'a' && c <= 'f' )
  146.         return ( c - 'a' + 10 );
  147.     if ( c >= 'A' && c <= 'F' )
  148.         return ( c - 'A' + 10 );
  149.     return ( c - '0' );
  150.     }
  151.  
  152. static SYM nextsym(XBM_PRIV *xbm_priv)
  153.     {
  154.     int c, i, sign = 1;
  155.  
  156.     for ( ;; )
  157.         {
  158.         while ( (c = nextchar(xbm_priv)) != -1 && isspace(c) )
  159.             ;
  160.         if ( c == -1 )
  161.             return ( S_EOF );
  162.  
  163.         if ( c != '/' )
  164.             break;
  165.  
  166.         if ( (c = nextchar(xbm_priv)) != '*' )
  167.             return ( S_ERROR_COMMENT );
  168.  
  169.         if ( (c = nextchar(xbm_priv)) == -1 )
  170.             return ( S_EOF );
  171.  
  172.         do
  173.             while ( c != '*' )
  174.                 if ( (c = nextchar(xbm_priv)) == -1 )
  175.                     return ( S_EOF );
  176.         while ( (c = nextchar(xbm_priv)) != -1 && c != '/' );
  177.         if ( c == -1 )
  178.             return ( S_EOF );
  179.         }
  180.  
  181.     switch ( c )
  182.         {
  183.         case '[':    return ( S_LSQR   );
  184.         case ']':    return ( S_RSQR   );
  185.         case '{':    return ( S_LCUR   );
  186.         case '}':    return ( S_RCUR   );
  187.         case ',':    return ( S_COMMA  );
  188.         case ';':    return ( S_SEMI   );
  189.         case '=':    return ( S_EQUALS );
  190.         }
  191.  
  192.     if ( isdigit(c) || c == '-' )
  193.         {
  194.         if ( c == '-' )
  195.             {
  196.             sign = -1;
  197.             if ( (c = nextchar(xbm_priv)) == -1 )
  198.                 return ( S_ERROR_MINUS );
  199.             if ( !isdigit(c) )
  200.                 return ( S_ERROR_NUMBER );
  201.             }
  202.         if ( c == '0' )
  203.             {
  204.             xbm_priv -> number = 0;
  205.             if ( (c = nextchar(xbm_priv)) == 'x' || c == 'X' )
  206.                 /* Hex number */
  207.                 {
  208.                 while ( (c = nextchar(xbm_priv)) != -1 && isxdigit(c) )
  209.                     {
  210.                     xbm_priv -> number <<= 4;
  211.                     xbm_priv -> number += valof(c);
  212.                     }
  213.                 }
  214.             else
  215.                 /* Octal number */
  216.                 while ( c != -1 && c >= '0' && c <= '7' )
  217.                     {
  218.                     xbm_priv -> number <<= 3;
  219.                     xbm_priv -> number += ( c - '0' );
  220.                     c = nextchar(xbm_priv);
  221.                     }
  222.             }
  223.         else
  224.             {
  225.             xbm_priv -> number = ( c - '0' );
  226.             while ( (c = nextchar(xbm_priv)) != -1 && isdigit(c) )
  227.                 {
  228.                 xbm_priv -> number *= 10;
  229.                 xbm_priv -> number += ( c - '0' );
  230.                 }
  231.             }
  232.  
  233.         xbm_priv -> number *= sign;
  234.  
  235.         pushchar(xbm_priv, c);
  236.         return ( S_NUMBER );
  237.         }
  238.  
  239.     i = 0;
  240.     do
  241.         xbm_priv -> id [i++] = c;
  242.     while ( (c = nextchar(xbm_priv)) != -1 && (isalnum(c) || c == '_') && i < MAX_ID );
  243.     xbm_priv -> id [i] = '\0';
  244.  
  245.     pushchar(xbm_priv, c);
  246.  
  247.     if ( !strcmp(xbm_priv -> id, "#define") ) return ( S_DEFINE );
  248.     if ( !strcmp(xbm_priv -> id, "static" ) ) return ( S_STATIC );
  249.     if ( !strcmp(xbm_priv -> id, "char"   ) ) return ( S_CHAR   );
  250.     if ( !strcmp(xbm_priv -> id, "short"  ) ) return ( S_SHORT  );
  251.  
  252.     if ( !isalnum(xbm_priv -> id [0]) )
  253.         return ( S_ERROR_ID );
  254.  
  255.     return ( S_ID );
  256.     }
  257. /*...e*/
  258.  
  259. /*...sxbm_qft:0:*/
  260. GBM_ERR xbm_qft(GBMFT *gbmft)
  261.     {
  262.     *gbmft = xbm_gbmft;
  263.     return ( GBM_ERR_OK );
  264.     }
  265. /*...e*/
  266. /*...sxbm_rhdr:0:*/
  267. GBM_ERR xbm_rhdr(char *fn, int fd, GBM *gbm, char *opt)
  268.     {
  269.     XBM_PRIV *xbm_priv = (XBM_PRIV *) gbm -> priv;
  270.     SYM sym;
  271.  
  272.     fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
  273.  
  274.     lseek(fd, 0L, SEEK_SET);
  275.  
  276.     xbm_priv -> fd  = fd;
  277.     xbm_priv -> inx = 0;
  278.     xbm_priv -> cnt = 0;
  279.  
  280.     gbm -> w   = -1;
  281.     gbm -> h   = -1;
  282.     gbm -> bpp = 1;
  283.  
  284.     while ( (sym = nextsym(xbm_priv)) == S_DEFINE )
  285.         {
  286.         char *p;
  287.  
  288.         if ( (sym = nextsym(xbm_priv)) != S_ID )
  289.             return ( GBM_ERR_XBM_EXP_ID );
  290.         if ( (p = strrchr(xbm_priv -> id, '_')) != NULL )
  291.             p++;
  292.         else
  293.             p = (char *) (xbm_priv -> id);
  294.  
  295.         if ( !strcmp(p, "width") )
  296.             {
  297.             if ( (sym = nextsym(xbm_priv)) != S_NUMBER )
  298.                 return ( GBM_ERR_XBM_EXP_NUMBER );
  299.             gbm -> w = xbm_priv -> number;
  300.             }
  301.         else if ( !strcmp(p, "height") )
  302.             {
  303.             if ( (sym = nextsym(xbm_priv)) != S_NUMBER )
  304.                 return ( GBM_ERR_XBM_EXP_NUMBER );
  305.             gbm -> h = xbm_priv -> number;
  306.             }
  307.         else
  308.             {
  309.             if ( (sym = nextsym(xbm_priv)) != S_NUMBER )
  310.                 return ( GBM_ERR_XBM_EXP_NUMBER );
  311.             }
  312.  
  313.         }
  314.  
  315.     if ( gbm -> w == -1 || gbm -> h == -1 )
  316.         return ( GBM_ERR_BAD_SIZE );
  317.  
  318.     if ( sym == S_STATIC )
  319.         sym = nextsym(xbm_priv);
  320.  
  321.     if ( sym == S_EOF )
  322.         return ( GBM_ERR_XBM_UNEXP_EOF );
  323.  
  324.     switch ( sym )
  325.         {
  326.         case S_CHAR:
  327.             xbm_priv -> size = 8;
  328.             break;
  329.         case S_SHORT:
  330.             xbm_priv -> size = 16;
  331.             break;
  332.         default:
  333.             return ( GBM_ERR_XBM_EXP_CHAR );
  334.         }
  335.  
  336.     if ( nextsym(xbm_priv) != S_ID )
  337.         return ( GBM_ERR_XBM_EXP_ID );
  338.  
  339.     if ( nextsym(xbm_priv) != S_LSQR )
  340.         return ( GBM_ERR_XBM_EXP_LSQR );
  341.  
  342.     if ( nextsym(xbm_priv) != S_RSQR )
  343.         return ( GBM_ERR_XBM_EXP_RSQR );
  344.  
  345.     if ( nextsym(xbm_priv) != S_EQUALS )
  346.         return ( GBM_ERR_XBM_EXP_EQUALS );
  347.  
  348.     if ( nextsym(xbm_priv) != S_LCUR )
  349.         return ( GBM_ERR_XBM_EXP_LCUR );
  350.  
  351.     return ( GBM_ERR_OK );
  352.     }
  353. /*...e*/
  354. /*...sxbm_rpal:0:*/
  355. GBM_ERR xbm_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
  356.     {
  357.     fd=fd; gbm=gbm; /* Suppress 'unref arg' compiler warnings */
  358.  
  359.     gbmrgb [0].r = 0xff;
  360.     gbmrgb [0].g = 0xff;
  361.     gbmrgb [0].b = 0xff; /* White background */
  362.     gbmrgb [1].r = 0x00;
  363.     gbmrgb [1].g = 0x00;
  364.     gbmrgb [1].b = 0x00; /* Black background */
  365.     return ( GBM_ERR_OK );
  366.     }
  367. /*...e*/
  368. /*...sxbm_rdata:0:*/
  369. GBM_ERR xbm_rdata(int fd, GBM *gbm, byte *data)
  370.     {
  371.     XBM_PRIV *xbm_priv = (XBM_PRIV *) gbm -> priv;
  372.     int stride = ( ( gbm -> w * gbm -> bpp + 31 ) / 32 ) * 4;
  373.     int x, y;
  374.     SYM sym;
  375.     BOOLEAN keep_going = TRUE;
  376.  
  377.     fd=fd; /* Suppres 'unref arg' compiler warning */
  378.  
  379.     memset(data, 0, gbm -> h * stride);
  380.     data += ( (gbm -> h - 1) * stride );
  381.  
  382.     switch ( xbm_priv -> size )
  383.         {
  384. /*...s8:16:*/
  385. case 8:
  386.     for ( y = gbm -> h - 1; keep_going && y >= 0; y--, data -= stride )
  387.         for ( x = 0; keep_going && x < ((gbm -> w + 7) >> 3); x++ )
  388.             if ( (sym = nextsym(xbm_priv)) == S_RCUR )
  389.                 keep_going = FALSE;
  390.             else if ( sym != S_NUMBER )
  391.                 return ( GBM_ERR_XBM_EXP_NUMBER );
  392.             else
  393.                 {
  394.                 data [x] = rev [xbm_priv -> number];
  395.  
  396.                 sym = nextsym(xbm_priv);
  397.                 if ( sym == S_RCUR )
  398.                     keep_going = FALSE;
  399.                 else if ( sym != S_COMMA )
  400.                     return ( GBM_ERR_XBM_EXP_COMMA );
  401.                 }
  402.     break;
  403. /*...e*/
  404. /*...s16:16:*/
  405. case 16:
  406.     for ( y = gbm -> h - 1; keep_going && y >= 0; y--, data -= stride )
  407.         for ( x = 0; keep_going && x < ((gbm -> w + 15) >> 4); x++ )
  408.             if ( (sym = nextsym(xbm_priv)) == S_RCUR )
  409.                 keep_going = FALSE;
  410.             else if ( sym != S_NUMBER )
  411.                 return ( GBM_ERR_XBM_EXP_NUMBER );
  412.             else
  413.                 {
  414.                 data [x * 2    ] = rev [xbm_priv -> number & 0xff];
  415.                 data [x * 2 + 1] = rev [xbm_priv -> number >> 8  ];
  416.  
  417.                 sym = nextsym(xbm_priv);
  418.                 if ( sym == S_RCUR )
  419.                     keep_going = FALSE;
  420.                 else if ( sym != S_COMMA )
  421.                     return ( GBM_ERR_XBM_EXP_COMMA );
  422.                 }
  423.     break;
  424. /*...e*/
  425.         }
  426.  
  427.     if ( keep_going )
  428.         if ( nextsym(xbm_priv) != S_RCUR )
  429.             return ( GBM_ERR_XBM_EXP_RCUR );
  430.  
  431.     if ( nextsym(xbm_priv) != S_SEMI )
  432.         return ( GBM_ERR_XBM_EXP_SEMI );
  433.  
  434.     return ( GBM_ERR_OK );
  435.     }
  436. /*...e*/
  437. /*...sxbm_w:0:*/
  438. /*
  439. Write darkest colour as 1s, lightest colour with 0s.
  440. */
  441.  
  442. GBM_ERR xbm_w(char *fn, int fd, GBM *gbm, GBMRGB *gbmrgb, byte *data, char *opt)
  443.     {
  444.     int stride = ((gbm -> w * gbm -> bpp + 31) / 32) * 4;
  445.     int x, y, col = 0;
  446.     char s [100+1], name [100+1], *dot, *p;
  447.     int k0, k1, xor;
  448.  
  449.     opt=opt; /* Suppress 'unref arg' compiler warning */
  450.  
  451.     /* Normally palette entry 0 brightest is usual */
  452.     /* If not reverse all the bits */
  453.  
  454.     k0 = gbmrgb [0].r * 77 + gbmrgb [0].g * 151 + gbmrgb [0].b * 28;
  455.     k1 = gbmrgb [1].r * 77 + gbmrgb [1].g * 151 + gbmrgb [1].b * 28;
  456.  
  457.     xor = ( k0 > k1 ) ? 0 : 0xff;
  458.  
  459.     /* Make the name from the filename, without the extension */
  460.  
  461.     strncpy(name, fn, 100);
  462.     if ( (dot = strrchr(name, '.')) != NULL )
  463.         *dot = '\0';
  464.  
  465.     /* Nobble any potentially nasty characters */
  466.  
  467.     if ( !isalpha(*name) )
  468.         *name = '_';
  469.     for ( p = name + 1; *p; p++ )
  470.         if ( !isalnum(*p) )
  471.             *p = '_';
  472.  
  473.     sprintf(s, "#define %s_width %d\r\n" , name, gbm -> w);
  474.     if ( write(fd, s, strlen(s)) != strlen(s) )
  475.         return ( GBM_ERR_WRITE );
  476.     sprintf(s, "#define %s_height %d\r\n", name, gbm -> h);
  477.     if ( write(fd, s, strlen(s)) != strlen(s) )
  478.         return ( GBM_ERR_WRITE );
  479.     sprintf(s, "static char %s_bits[] = {\r\n", name);
  480.     if ( write(fd, s, strlen(s)) != strlen(s) )
  481.         return ( GBM_ERR_WRITE );
  482.  
  483.     data += (gbm -> h - 1) * stride;
  484.     for ( y = gbm -> h - 1; y >= 0; y--, data -= stride )
  485.         for ( x = 0; x < ((gbm -> w + 7) >> 3); x++ )
  486.             {
  487.             sprintf(s, "0x%02x,", rev [data [x]] ^ xor);
  488.             col += 5;
  489.             if ( col > 70 )
  490.                 {
  491.                 strcat(s, "\r\n");
  492.                 col = 0;
  493.                 }
  494.             if ( write(fd, s, strlen(s)) != strlen(s) )
  495.                 return ( GBM_ERR_WRITE );
  496.             }
  497.  
  498.     if ( col )
  499.         {
  500.         if ( write(fd, "\r\n", 2) != 2 )
  501.             return ( GBM_ERR_WRITE );
  502.         }        
  503.  
  504.     if ( write(fd, "};\r\n", 4) != 4 )
  505.         return ( GBM_ERR_WRITE );
  506.  
  507.     return ( GBM_ERR_OK );
  508.     }
  509. /*...e*/
  510. /*...sxbm_err:0:*/
  511. char *xbm_err(GBM_ERR rc)
  512.     {
  513.     switch ( (int) rc )
  514.         {
  515.         case GBM_ERR_XBM_EXP_ID:
  516.             return ( "expected identifier" );
  517.         case GBM_ERR_XBM_UNEXP_EOF:
  518.             return ( "unexpected end of file" );
  519.         case GBM_ERR_XBM_EXP_CHAR:
  520.             return ( "expected char or short" );
  521.         case GBM_ERR_XBM_EXP_LSQR:
  522.             return ( "expected [" );
  523.         case GBM_ERR_XBM_EXP_RSQR:
  524.             return ( "expected ]" );
  525.         case GBM_ERR_XBM_EXP_EQUALS:
  526.             return ( "expected =" );
  527.         case GBM_ERR_XBM_EXP_LCUR:
  528.             return ( "expected {" );
  529.         case GBM_ERR_XBM_EXP_RCUR:
  530.             return ( "expected }" );
  531.         case GBM_ERR_XBM_EXP_COMMA:
  532.             return ( "expected ," );
  533.         case GBM_ERR_XBM_EXP_NUMBER:
  534.             return ( "expected number" );
  535.         case GBM_ERR_XBM_EXP_SEMI:
  536.             return ( "expected ;" );
  537.         }
  538.     return ( NULL );
  539.     }
  540. /*...e*/
  541.