options&(RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) && translate)
/* Fetch the next character in the uncompiled pattern---translating it 
   if necessary.  Also cast from a signed character in the constant
   string passed to us by the user to an unsigned char that we can use
   as an array index (in, e.g., `translate').  */
#define PATFETCH(c)							\
  do {if (p == pend) goto end_of_pattern;				\
    c = (unsigned char) *p++; 						\
    if (TRANSLATE_P()) c = (unsigned char)translate[c];	\
  } while (0)

/* Fetch the next character in the uncompiled pattern, with no
   translation.  */
#define PATFETCH_RAW(c)							\
  do {if (p == pend) goto end_of_pattern;				\
    c = (unsigned char)*p++; 						\
  } while (0)

/* Go backwards one character in the pattern.  */
#define PATUNFETCH p--

#define MBC2WC(c, p)							\
  do {									\
    if (current_mbctype == MBCTYPE_UTF8) {				\
      int n = mbclen(c) - 1;						\
      c &= (1<<(BYTEWIDTH-2-n)) - 1;					\
      while (n--) {							\
	c = c << 6 | (*p++ & ((1<<6)-1));				\
      }									\
    }									\
    else {								\
      c <<= 8;								\
      c |= (unsigned char)*(p)++;					\
    }									\
  } while (0)

#define PATFETCH_MBC(c)							\
  do {									\
    if (p + mbclen(c) - 1 >= pend) goto end_of_pattern;			\
    MBC2WC(c, p);							\
  } while(0)

#define WC2MBC1ST(c)							\
 ((current_mbctype != MBCTYPE_UTF8) ? ((c<0x100) ? (c) : (((c)>>8)&0xff)) : utf8_firstbyte(c))

static unsigned int
utf8_firstbyte(c)
     unsigned long c;
{
  if (c < 0x80) return c;
  if (c <= 0x7ff) return ((c>>6)&0xff)|0xc0;
  if (c <= 0xffff) return ((c>>12)&0xff)|0xe0;
  if (c <= 0x1fffff) return ((c>>18)&0xff)|0xf0;
  if (c <= 0x3ffffff) return ((c>>24)&0xff)|0xf8;
  if (c <= 0x7fffffff) return ((c>>30)&0xff)|0xfc;
#if SIZEOF_INT > 4
  if (c <= 0xfffffffff) return 0xfe;
#else
  return 0xfe;
#endif
}

static void
print_mbc(c)
     unsigned int c;
{
  if (current_mbctype == MBCTYPE_UTF8) {
    if (c < 0x80)
      printf("%c", (int)c);
    else if (c <= 0x7ff)
      printf("%c%c", (int)utf8_firstbyte(c), (int)(c & 0x3f));
    else if (c <= 0xffff)
      printf("%c%c%c", (int)utf8_firstbyte(c), (int)((c >> 6) & 0x3f),
	     (int)(c & 0x3f));
    else if (c <= 0x1fffff) 
      printf("%c%c%c%c", (int)utf8_firstbyte(c), (int)((c >> 12) & 0x3f),
	     (int)((c >> 6) & 0x3f), (int)(c & 0x3f));
    else if (c <= 0x3ffffff)
      printf("%c%c%c%c%c", (int)utf8_firstbyte(c), (int)((c >> 18) & 0x3f),
	     (int)((c >> 12) & 0x3f), (int)((c >> 6) & 0x3f), (int)(c & 0x3f));
    else if (c <= 0x7fffffff)
      printf("%c%c%c%c%c%c", (int)utf8_firstbyte(c), (int)((c >> 24) & 0x3f),
	     (int)((c >> 18) & 0x3f), (int)((c >> 12) & 0x3f),
	     (int)((c >> 6) & 0x3f), (int)(c & 0x3f));
  }
  else if (c < 0xff) {
    printf("\\%o", (int)c);
  }
  else {
    printf("%c%c", (int)(c >> BYTEWIDTH), (int)(c &0xff));
  }
}

/* If the buffer isn't allocated when it comes in, use this.  */
#define INIT_BUF_SIZE  28

/* Make sure we have at least N more bytes of space in buffer.  */
#define GET_BUFFER_SPACE(n)						\
  do {								        \
    while (b - bufp->buffer + (n) >= bufp->allocated)			\
      EXTEND_BUFFER;							\
  } while (0)

/* Make sure we have one more byte of buffer space and then add CH to it.  */
#define BUFPUSH(ch)							\
  do {									\
    GET_BUFFER_SPACE(1);						\
    *b++ = (char)(ch);							\
  } while (0)

/* Extend the buffer by twice its current size via reallociation and
   reset the pointers that pointed into the old allocation to point to
   the correct places in the new allocation.  If extending the buffer
   results in it being larger than 1 << 16, then flag memory exhausted.  */
#define EXTEND_BUFFER							\
  do { char *old_buffer = bufp->buffer;					\
    if (bufp->allocated == (1L<<16)) goto too_big;			\
    bufp->allocated *= 2;						\
    if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16);		\
    bufp->buffer = (char*)xrealloc(bufp->buffer, bufp->allocated);	\
    if (bufp->buffer == 0)						\
      goto memory_exhausted;						\
    b = (b - old_buffer) + bufp->buffer;				\
    if (fixup_alt_jump)							\
      fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;	\
    if (laststart)							\
      laststart = (laststart - old_buffer) + bufp->buffer;		\
    begalt = (begalt - old_buffer) + bufp->buffer;			\
    if (pending_exact)							\
      pending_exact = (pending_exact - old_buffer) + bufp->buffer;	\
  } while (0)


/* Set the bit for character C in a character set list.  */
#define SET_LIST_BIT(c)							\
  (b[(unsigned char)(c) / BYTEWIDTH]					\
   |= 1 << ((unsigned char)(c) % BYTEWIDTH))

/* Get the next unsigned number in the uncompiled pattern.  */
#define GET_UNSIGNED_NUMBER(num) 					\
  do { if (p != pend) { 						\
        PATFETCH(c); 							\
	while (ISDIGIT(c)) { 						\
	  if (num < 0) 							\
	     num = 0; 							\
	  num = num * 10 + c - '0'; 					\
	  if (p == pend) 						\
	     break; 							\
	  PATFETCH(c); 							\
	} 								\
     } 									\
  } while (0)

#define STREQ(s1, s2) ((strcmp(s1, s2) == 0))

#define CHAR_CLASS_MAX_LENGTH  6 /* Namely, `xdigit'.  */

#define IS_CHAR_CLASS(string)						\
   (STREQ(string, "alpha") || STREQ(string, "upper")			\
    || STREQ(string, "lower") || STREQ(string, "digit")			\
    || STREQ(string, "alnum") || STREQ(string, "xdigit")		\
    || STREQ(string, "space") || STREQ(string, "print")			\
    || STREQ(string, "punct") || STREQ(string, "graph")			\
    || STREQ(string, "cntrl") || STREQ(string, "blank"))
