xref: /aosp_15_r20/external/pcre/maint/utf8.c (revision 22dc650d8ae982c6770746019a6f94af92b0f024)
1*22dc650dSSadaf Ebrahimi /****************************************************
2*22dc650dSSadaf Ebrahimi * PCRE maintainers' helper program: UTF-8 converter *
3*22dc650dSSadaf Ebrahimi ****************************************************/
4*22dc650dSSadaf Ebrahimi 
5*22dc650dSSadaf Ebrahimi /* This is a test program for converting character code points to UTF-8 and
6*22dc650dSSadaf Ebrahimi vice versa. Note that this program conforms to the original definition of
7*22dc650dSSadaf Ebrahimi UTF-8, which allows codepoints up to 7fffffff. The more recent definition
8*22dc650dSSadaf Ebrahimi limits the validity of Unicode UTF-8 codepoints to a maximum of 10ffffff, and
9*22dc650dSSadaf Ebrahimi forbids the "surrogate" code points. This program now gives warnings for these
10*22dc650dSSadaf Ebrahimi invalid code points.
11*22dc650dSSadaf Ebrahimi 
12*22dc650dSSadaf Ebrahimi The arguments are either single code point values written as U+hh.. or 0xhh..
13*22dc650dSSadaf Ebrahimi for conversion to UTF-8, or sequences of hex values, written without 0x and
14*22dc650dSSadaf Ebrahimi optionally including spaces (but such arguments must be quoted), for conversion
15*22dc650dSSadaf Ebrahimi from UTF-8 to codepoints. For example:
16*22dc650dSSadaf Ebrahimi 
17*22dc650dSSadaf Ebrahimi ./utf8 0x1234
18*22dc650dSSadaf Ebrahimi U+00001234 => e1 88 b4
19*22dc650dSSadaf Ebrahimi 
20*22dc650dSSadaf Ebrahimi ./utf8 "e1 88 b4"
21*22dc650dSSadaf Ebrahimi U+00001234 <= e1 88 b4
22*22dc650dSSadaf Ebrahimi 
23*22dc650dSSadaf Ebrahimi In the second case, a number of UTF-8 characters can be present in one
24*22dc650dSSadaf Ebrahimi argument. In other words, each such argument is interpreted (after ignoring
25*22dc650dSSadaf Ebrahimi spaces) as a string of UTF-8 bytes representing a string of characters:
26*22dc650dSSadaf Ebrahimi 
27*22dc650dSSadaf Ebrahimi ./utf8 "65 e188b4 77"
28*22dc650dSSadaf Ebrahimi 0x00000065 <= 65
29*22dc650dSSadaf Ebrahimi 0x00001234 <= e1 88 b4
30*22dc650dSSadaf Ebrahimi 0x00000077 <= 77
31*22dc650dSSadaf Ebrahimi 
32*22dc650dSSadaf Ebrahimi If the option -s is given, the sequence of UTF-bytes is written out between
33*22dc650dSSadaf Ebrahimi angle brackets at the end of the line. On a UTF-8 terminal, this will show the
34*22dc650dSSadaf Ebrahimi appropriate graphic for the code point.
35*22dc650dSSadaf Ebrahimi 
36*22dc650dSSadaf Ebrahimi Errors provoke error messages, but the program carries on with the next
37*22dc650dSSadaf Ebrahimi argument. The return code is always zero.
38*22dc650dSSadaf Ebrahimi 
39*22dc650dSSadaf Ebrahimi Philip Hazel
40*22dc650dSSadaf Ebrahimi Original creation data: unknown
41*22dc650dSSadaf Ebrahimi Code extended and tidied to avoid compiler warnings: 26 March 2020
42*22dc650dSSadaf Ebrahimi */
43*22dc650dSSadaf Ebrahimi 
44*22dc650dSSadaf Ebrahimi 
45*22dc650dSSadaf Ebrahimi #include <stdio.h>
46*22dc650dSSadaf Ebrahimi #include <stdlib.h>
47*22dc650dSSadaf Ebrahimi #include <ctype.h>
48*22dc650dSSadaf Ebrahimi #include <string.h>
49*22dc650dSSadaf Ebrahimi 
50*22dc650dSSadaf Ebrahimi /* The valid ranges for UTF-8 characters are:
51*22dc650dSSadaf Ebrahimi 
52*22dc650dSSadaf Ebrahimi 0000 0000  to  0000 007f   1 byte (ascii)
53*22dc650dSSadaf Ebrahimi 0000 0080  to  0000 07ff   2 bytes
54*22dc650dSSadaf Ebrahimi 0000 0800  to  0000 ffff   3 bytes
55*22dc650dSSadaf Ebrahimi 0001 0000  to  001f ffff   4 bytes
56*22dc650dSSadaf Ebrahimi 0020 0000  to  03ff ffff   5 bytes
57*22dc650dSSadaf Ebrahimi 0400 0000  to  7fff ffff   6 bytes
58*22dc650dSSadaf Ebrahimi */
59*22dc650dSSadaf Ebrahimi 
60*22dc650dSSadaf Ebrahimi 
61*22dc650dSSadaf Ebrahimi static const unsigned int utf8_table1[] = {
62*22dc650dSSadaf Ebrahimi   0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff};
63*22dc650dSSadaf Ebrahimi 
64*22dc650dSSadaf Ebrahimi static const int utf8_table2[] = {
65*22dc650dSSadaf Ebrahimi   0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
66*22dc650dSSadaf Ebrahimi 
67*22dc650dSSadaf Ebrahimi static const int utf8_table3[] = {
68*22dc650dSSadaf Ebrahimi   0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
69*22dc650dSSadaf Ebrahimi 
70*22dc650dSSadaf Ebrahimi 
71*22dc650dSSadaf Ebrahimi /*************************************************
72*22dc650dSSadaf Ebrahimi *       Convert character value to UTF-8         *
73*22dc650dSSadaf Ebrahimi *************************************************/
74*22dc650dSSadaf Ebrahimi 
75*22dc650dSSadaf Ebrahimi /* This function takes an unsigned long integer value in the range 0 -
76*22dc650dSSadaf Ebrahimi 0x7fffffff and encodes it as a UTF-8 character in 1 to 6 bytes.
77*22dc650dSSadaf Ebrahimi 
78*22dc650dSSadaf Ebrahimi Arguments:
79*22dc650dSSadaf Ebrahimi   cvalue     the character value
80*22dc650dSSadaf Ebrahimi   buffer     pointer to buffer for result - at least 6 bytes long
81*22dc650dSSadaf Ebrahimi 
82*22dc650dSSadaf Ebrahimi Returns:     number of bytes placed in the buffer
83*22dc650dSSadaf Ebrahimi              0 if input code point is too big
84*22dc650dSSadaf Ebrahimi */
85*22dc650dSSadaf Ebrahimi 
86*22dc650dSSadaf Ebrahimi static size_t
ord2utf8(unsigned long int cvalue,unsigned char * buffer)87*22dc650dSSadaf Ebrahimi ord2utf8(unsigned long int cvalue, unsigned char *buffer)
88*22dc650dSSadaf Ebrahimi {
89*22dc650dSSadaf Ebrahimi size_t i, j;
90*22dc650dSSadaf Ebrahimi for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++)
91*22dc650dSSadaf Ebrahimi   if (cvalue <= utf8_table1[i]) break;
92*22dc650dSSadaf Ebrahimi if (i >= sizeof(utf8_table1)/sizeof(int)) return 0;
93*22dc650dSSadaf Ebrahimi buffer += i;
94*22dc650dSSadaf Ebrahimi for (j = i; j > 0; j--)
95*22dc650dSSadaf Ebrahimi  {
96*22dc650dSSadaf Ebrahimi  *buffer-- = 0x80 | (cvalue & 0x3f);
97*22dc650dSSadaf Ebrahimi  cvalue >>= 6;
98*22dc650dSSadaf Ebrahimi  }
99*22dc650dSSadaf Ebrahimi *buffer = utf8_table2[i] | cvalue;
100*22dc650dSSadaf Ebrahimi return i + 1;
101*22dc650dSSadaf Ebrahimi }
102*22dc650dSSadaf Ebrahimi 
103*22dc650dSSadaf Ebrahimi 
104*22dc650dSSadaf Ebrahimi 
105*22dc650dSSadaf Ebrahimi /*************************************************
106*22dc650dSSadaf Ebrahimi *            Convert UTF-8 string to value       *
107*22dc650dSSadaf Ebrahimi *************************************************/
108*22dc650dSSadaf Ebrahimi 
109*22dc650dSSadaf Ebrahimi /* This function takes one or more bytes that represent a UTF-8 character from
110*22dc650dSSadaf Ebrahimi the start of a string of bytes. It returns the value of the character, or the
111*22dc650dSSadaf Ebrahimi offset of a malformation. For an overlong encoding that works but is not the
112*22dc650dSSadaf Ebrahimi correct (shortest) one, the error offset is just after the last byte.
113*22dc650dSSadaf Ebrahimi 
114*22dc650dSSadaf Ebrahimi Argument:
115*22dc650dSSadaf Ebrahimi   buffer   a pointer to the byte vector
116*22dc650dSSadaf Ebrahimi   buffend  a pointer to the end of the buffer
117*22dc650dSSadaf Ebrahimi   vptr     a pointer to a variable to receive the value
118*22dc650dSSadaf Ebrahimi   lenptr   a pointer to a variable to receive the offset when error detected
119*22dc650dSSadaf Ebrahimi 
120*22dc650dSSadaf Ebrahimi Returns:   > 0 => the number of bytes consumed
121*22dc650dSSadaf Ebrahimi              0 => invalid UTF-8: first byte missing 0x40 bit
122*22dc650dSSadaf Ebrahimi             -1 => invalid UTF-8: first byte has too many high-order 1-bits
123*22dc650dSSadaf Ebrahimi             -2 => incomplete sequence at end of string
124*22dc650dSSadaf Ebrahimi             -3 => incomplete sequence within string
125*22dc650dSSadaf Ebrahimi             -4 => overlong code sequence
126*22dc650dSSadaf Ebrahimi */
127*22dc650dSSadaf Ebrahimi 
128*22dc650dSSadaf Ebrahimi static int
utf82ord(unsigned char * buffer,unsigned char * buffend,long unsigned int * vptr,int * lenptr)129*22dc650dSSadaf Ebrahimi utf82ord(unsigned char *buffer, unsigned char *buffend,
130*22dc650dSSadaf Ebrahimi   long unsigned int *vptr, int *lenptr)
131*22dc650dSSadaf Ebrahimi {
132*22dc650dSSadaf Ebrahimi unsigned int c = *buffer++;
133*22dc650dSSadaf Ebrahimi unsigned int d = c;
134*22dc650dSSadaf Ebrahimi int i, j, s;
135*22dc650dSSadaf Ebrahimi 
136*22dc650dSSadaf Ebrahimi /* Check for an ASCII character, or find the number of additional bytes in a
137*22dc650dSSadaf Ebrahimi multibyte character. */
138*22dc650dSSadaf Ebrahimi 
139*22dc650dSSadaf Ebrahimi for (i = -1; i < 6; i++)
140*22dc650dSSadaf Ebrahimi   {
141*22dc650dSSadaf Ebrahimi   if ((d & 0x80) == 0) break;
142*22dc650dSSadaf Ebrahimi   d <<= 1;
143*22dc650dSSadaf Ebrahimi   }
144*22dc650dSSadaf Ebrahimi 
145*22dc650dSSadaf Ebrahimi switch (i)
146*22dc650dSSadaf Ebrahimi   {
147*22dc650dSSadaf Ebrahimi   case -1:      /* ASCII character; first byte does not have 0x80 bit */
148*22dc650dSSadaf Ebrahimi   *vptr = c;
149*22dc650dSSadaf Ebrahimi   return 1;
150*22dc650dSSadaf Ebrahimi 
151*22dc650dSSadaf Ebrahimi   case 0:       /* First byte has 0x80 but is missing 0x40 bit */
152*22dc650dSSadaf Ebrahimi   *lenptr = 0;
153*22dc650dSSadaf Ebrahimi   return 0;
154*22dc650dSSadaf Ebrahimi 
155*22dc650dSSadaf Ebrahimi   case 6:
156*22dc650dSSadaf Ebrahimi   *lenptr = 0;  /* Too many high bits */
157*22dc650dSSadaf Ebrahimi   return -1;
158*22dc650dSSadaf Ebrahimi 
159*22dc650dSSadaf Ebrahimi   default:
160*22dc650dSSadaf Ebrahimi   break;
161*22dc650dSSadaf Ebrahimi   }
162*22dc650dSSadaf Ebrahimi 
163*22dc650dSSadaf Ebrahimi /* i now has a value in the range 1-5 */
164*22dc650dSSadaf Ebrahimi 
165*22dc650dSSadaf Ebrahimi s = 6*i;
166*22dc650dSSadaf Ebrahimi d = (c & utf8_table3[i]) << s;
167*22dc650dSSadaf Ebrahimi 
168*22dc650dSSadaf Ebrahimi for (j = 0; j < i; j++)
169*22dc650dSSadaf Ebrahimi   {
170*22dc650dSSadaf Ebrahimi   if (buffer >= buffend)
171*22dc650dSSadaf Ebrahimi     {
172*22dc650dSSadaf Ebrahimi     *lenptr = j + 1;
173*22dc650dSSadaf Ebrahimi     return -2;
174*22dc650dSSadaf Ebrahimi     }
175*22dc650dSSadaf Ebrahimi   c = *buffer++;
176*22dc650dSSadaf Ebrahimi   if ((c & 0xc0) != 0x80)
177*22dc650dSSadaf Ebrahimi     {
178*22dc650dSSadaf Ebrahimi     *lenptr = j + 1;
179*22dc650dSSadaf Ebrahimi     return -3;
180*22dc650dSSadaf Ebrahimi     }
181*22dc650dSSadaf Ebrahimi   s -= 6;
182*22dc650dSSadaf Ebrahimi   d |= (c & 0x3f) << s;
183*22dc650dSSadaf Ebrahimi   }
184*22dc650dSSadaf Ebrahimi 
185*22dc650dSSadaf Ebrahimi /* Valid UTF-8 syntax */
186*22dc650dSSadaf Ebrahimi 
187*22dc650dSSadaf Ebrahimi *vptr = d;
188*22dc650dSSadaf Ebrahimi 
189*22dc650dSSadaf Ebrahimi /* Check that encoding was the correct one, not overlong */
190*22dc650dSSadaf Ebrahimi 
191*22dc650dSSadaf Ebrahimi for (j = 0; j < (int)(sizeof(utf8_table1)/sizeof(int)); j++)
192*22dc650dSSadaf Ebrahimi   if (d <= utf8_table1[j]) break;
193*22dc650dSSadaf Ebrahimi if (j != i)
194*22dc650dSSadaf Ebrahimi   {
195*22dc650dSSadaf Ebrahimi   *lenptr = i + 1;
196*22dc650dSSadaf Ebrahimi   return -4;
197*22dc650dSSadaf Ebrahimi   }
198*22dc650dSSadaf Ebrahimi 
199*22dc650dSSadaf Ebrahimi /* Valid value */
200*22dc650dSSadaf Ebrahimi 
201*22dc650dSSadaf Ebrahimi return i + 1;
202*22dc650dSSadaf Ebrahimi }
203*22dc650dSSadaf Ebrahimi 
204*22dc650dSSadaf Ebrahimi 
205*22dc650dSSadaf Ebrahimi 
206*22dc650dSSadaf Ebrahimi /*************************************************
207*22dc650dSSadaf Ebrahimi *                 Main Program                   *
208*22dc650dSSadaf Ebrahimi *************************************************/
209*22dc650dSSadaf Ebrahimi 
210*22dc650dSSadaf Ebrahimi int
main(int argc,char ** argv)211*22dc650dSSadaf Ebrahimi main(int argc, char **argv)
212*22dc650dSSadaf Ebrahimi {
213*22dc650dSSadaf Ebrahimi int i = 1;
214*22dc650dSSadaf Ebrahimi int show = 0;
215*22dc650dSSadaf Ebrahimi unsigned char buffer[64];
216*22dc650dSSadaf Ebrahimi 
217*22dc650dSSadaf Ebrahimi if (argc > 1 && strcmp(argv[1], "-s") == 0)
218*22dc650dSSadaf Ebrahimi   {
219*22dc650dSSadaf Ebrahimi   show = 1;
220*22dc650dSSadaf Ebrahimi   i = 2;
221*22dc650dSSadaf Ebrahimi   }
222*22dc650dSSadaf Ebrahimi 
223*22dc650dSSadaf Ebrahimi for (; i < argc; i++)
224*22dc650dSSadaf Ebrahimi   {
225*22dc650dSSadaf Ebrahimi   char *x = argv[i];
226*22dc650dSSadaf Ebrahimi   char *endptr;
227*22dc650dSSadaf Ebrahimi   if (strncmp(x, "0x", 2) == 0 || strncmp(x, "U+", 2) == 0)
228*22dc650dSSadaf Ebrahimi     {
229*22dc650dSSadaf Ebrahimi     size_t rc, j;
230*22dc650dSSadaf Ebrahimi     unsigned long int d = strtoul(x+2, &endptr, 16);
231*22dc650dSSadaf Ebrahimi     if (*endptr != 0)
232*22dc650dSSadaf Ebrahimi       {
233*22dc650dSSadaf Ebrahimi       printf("** Invalid hex number %s\n", x);
234*22dc650dSSadaf Ebrahimi       continue;   /* With next argument */
235*22dc650dSSadaf Ebrahimi       }
236*22dc650dSSadaf Ebrahimi     rc = ord2utf8(d, buffer);
237*22dc650dSSadaf Ebrahimi     printf("U+%08lx => ", d);
238*22dc650dSSadaf Ebrahimi     if (rc == 0)
239*22dc650dSSadaf Ebrahimi       printf("** Code point greater than 0x7fffffff cannot be encoded");
240*22dc650dSSadaf Ebrahimi     else
241*22dc650dSSadaf Ebrahimi       {
242*22dc650dSSadaf Ebrahimi       for (j = 0; j < rc; j++) printf("%02x ", buffer[j]);
243*22dc650dSSadaf Ebrahimi       if (show)
244*22dc650dSSadaf Ebrahimi         {
245*22dc650dSSadaf Ebrahimi         printf(">");
246*22dc650dSSadaf Ebrahimi         for (j = 0; j < rc; j++) printf("%c", buffer[j]);
247*22dc650dSSadaf Ebrahimi         printf("< ");
248*22dc650dSSadaf Ebrahimi         }
249*22dc650dSSadaf Ebrahimi       if (d >= 0xd800 && d <= 0xdfff)
250*22dc650dSSadaf Ebrahimi         printf("** Invalid Unicode (surrogate)");
251*22dc650dSSadaf Ebrahimi       else if (d > 0x10ffff)
252*22dc650dSSadaf Ebrahimi         printf("** Invalid Unicode (greater than U+10ffff)");
253*22dc650dSSadaf Ebrahimi       }
254*22dc650dSSadaf Ebrahimi     printf("\n");
255*22dc650dSSadaf Ebrahimi     }
256*22dc650dSSadaf Ebrahimi   else
257*22dc650dSSadaf Ebrahimi     {
258*22dc650dSSadaf Ebrahimi     unsigned char *bptr;
259*22dc650dSSadaf Ebrahimi     unsigned char *buffend;
260*22dc650dSSadaf Ebrahimi     int len = 0;
261*22dc650dSSadaf Ebrahimi     int y = 0;
262*22dc650dSSadaf Ebrahimi     int z = 0;
263*22dc650dSSadaf Ebrahimi 
264*22dc650dSSadaf Ebrahimi     for (;;)
265*22dc650dSSadaf Ebrahimi       {
266*22dc650dSSadaf Ebrahimi       while (*x == ' ') x++;
267*22dc650dSSadaf Ebrahimi       if (*x == 0 && !z) break;
268*22dc650dSSadaf Ebrahimi       if (!isxdigit(*x))
269*22dc650dSSadaf Ebrahimi         {
270*22dc650dSSadaf Ebrahimi         printf("** Malformed hex string: %s\n", argv[i]);
271*22dc650dSSadaf Ebrahimi         len = -1;
272*22dc650dSSadaf Ebrahimi         break;
273*22dc650dSSadaf Ebrahimi         }
274*22dc650dSSadaf Ebrahimi       y = y * 16 + tolower(*x) - ((isdigit(*x))? '0' : 'W');
275*22dc650dSSadaf Ebrahimi       x++;
276*22dc650dSSadaf Ebrahimi       if (z)
277*22dc650dSSadaf Ebrahimi         {
278*22dc650dSSadaf Ebrahimi         buffer[len++] = y;
279*22dc650dSSadaf Ebrahimi         y = 0;
280*22dc650dSSadaf Ebrahimi         }
281*22dc650dSSadaf Ebrahimi       z ^= 1;
282*22dc650dSSadaf Ebrahimi       }
283*22dc650dSSadaf Ebrahimi 
284*22dc650dSSadaf Ebrahimi     if (len < 0) continue;  /* With next argument after malformation */
285*22dc650dSSadaf Ebrahimi 
286*22dc650dSSadaf Ebrahimi     bptr = buffer;
287*22dc650dSSadaf Ebrahimi     buffend = buffer + len;
288*22dc650dSSadaf Ebrahimi 
289*22dc650dSSadaf Ebrahimi     while (bptr < buffend)
290*22dc650dSSadaf Ebrahimi       {
291*22dc650dSSadaf Ebrahimi       unsigned long int d;
292*22dc650dSSadaf Ebrahimi       int j;
293*22dc650dSSadaf Ebrahimi       int offset;
294*22dc650dSSadaf Ebrahimi       int rc = utf82ord(bptr, buffend, &d, &offset);
295*22dc650dSSadaf Ebrahimi 
296*22dc650dSSadaf Ebrahimi       if (rc > 0)
297*22dc650dSSadaf Ebrahimi         {
298*22dc650dSSadaf Ebrahimi         printf("U+%08lx <= ", d);
299*22dc650dSSadaf Ebrahimi         for (j = 0; j < rc; j++) printf("%02x ", bptr[j]);
300*22dc650dSSadaf Ebrahimi         if (show)
301*22dc650dSSadaf Ebrahimi           {
302*22dc650dSSadaf Ebrahimi           printf(">");
303*22dc650dSSadaf Ebrahimi           for (j = 0; j < rc; j++) printf("%c", bptr[j]);
304*22dc650dSSadaf Ebrahimi           printf("<");
305*22dc650dSSadaf Ebrahimi           }
306*22dc650dSSadaf Ebrahimi         printf("\n");
307*22dc650dSSadaf Ebrahimi         bptr += rc;
308*22dc650dSSadaf Ebrahimi         }
309*22dc650dSSadaf Ebrahimi       else if (rc == -4)
310*22dc650dSSadaf Ebrahimi         {
311*22dc650dSSadaf Ebrahimi         printf("U+%08lx <= ", d);
312*22dc650dSSadaf Ebrahimi         for (j = 0; j < offset; j++) printf("%02x ", bptr[j]);
313*22dc650dSSadaf Ebrahimi         printf("** Overlong UTF-8 sequence\n");
314*22dc650dSSadaf Ebrahimi         bptr += offset;
315*22dc650dSSadaf Ebrahimi         }
316*22dc650dSSadaf Ebrahimi       else
317*22dc650dSSadaf Ebrahimi         {
318*22dc650dSSadaf Ebrahimi         switch (rc)
319*22dc650dSSadaf Ebrahimi           {
320*22dc650dSSadaf Ebrahimi           case 0:  printf("** First byte missing 0x40 bit");
321*22dc650dSSadaf Ebrahimi           break;
322*22dc650dSSadaf Ebrahimi 
323*22dc650dSSadaf Ebrahimi           case -1: printf("** First byte has too many high-order bits");
324*22dc650dSSadaf Ebrahimi           break;
325*22dc650dSSadaf Ebrahimi 
326*22dc650dSSadaf Ebrahimi           case -2: printf("** Incomplete UTF-8 sequence at end of string");
327*22dc650dSSadaf Ebrahimi           break;
328*22dc650dSSadaf Ebrahimi 
329*22dc650dSSadaf Ebrahimi           case -3: printf("** Incomplete UTF-8 sequence");
330*22dc650dSSadaf Ebrahimi           break;
331*22dc650dSSadaf Ebrahimi 
332*22dc650dSSadaf Ebrahimi           default: printf("** Unexpected return %d from utf82ord()", rc);
333*22dc650dSSadaf Ebrahimi           break;
334*22dc650dSSadaf Ebrahimi           }
335*22dc650dSSadaf Ebrahimi         printf(" at offset %d in string ", offset);
336*22dc650dSSadaf Ebrahimi         while (bptr < buffend) printf("%02x ", *bptr++);
337*22dc650dSSadaf Ebrahimi         printf("\n");
338*22dc650dSSadaf Ebrahimi         break;
339*22dc650dSSadaf Ebrahimi         }
340*22dc650dSSadaf Ebrahimi       }
341*22dc650dSSadaf Ebrahimi     }
342*22dc650dSSadaf Ebrahimi   }
343*22dc650dSSadaf Ebrahimi 
344*22dc650dSSadaf Ebrahimi return 0;
345*22dc650dSSadaf Ebrahimi }
346*22dc650dSSadaf Ebrahimi 
347*22dc650dSSadaf Ebrahimi /* End */
348