]> granicus.if.org Git - postgresql/blob - src/backend/utils/adt/varlena.c
Big warnings cleanup for Solaris/GCC. Down to about 40 now, but
[postgresql] / src / backend / utils / adt / varlena.c
1 /*-------------------------------------------------------------------------
2  *
3  * varlena.c
4  *        Functions for the variable-length built-in types.
5  *
6  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *        $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.60 2000/06/14 18:17:45 petere Exp $
12  *
13  *-------------------------------------------------------------------------
14  */
15 #include <ctype.h>
16
17 #include "postgres.h"
18
19 #include "mb/pg_wchar.h"
20 #include "utils/builtins.h"
21
22 static int      text_cmp(text *arg1, text *arg2);
23
24
25 /*****************************************************************************
26  *       USER I/O ROUTINES                                                                                                               *
27  *****************************************************************************/
28
29
30 #define VAL(CH)                 ((CH) - '0')
31 #define DIG(VAL)                ((VAL) + '0')
32
33 /*
34  *              byteain                 - converts from printable representation of byte array
35  *
36  *              Non-printable characters must be passed as '\nnn' (octal) and are
37  *              converted to internal form.  '\' must be passed as '\\'.
38  *              elog(ERROR, ...) if bad form.
39  *
40  *              BUGS:
41  *                              The input is scaned twice.
42  *                              The error checking of input is minimal.
43  */
44 bytea *
45 byteain(char *inputText)
46 {
47         char       *tp;
48         char       *rp;
49         int                     byte;
50         bytea      *result;
51
52         if (inputText == NULL)
53                 elog(ERROR, "Bad input string for type bytea");
54
55         for (byte = 0, tp = inputText; *tp != '\0'; byte++)
56                 if (*tp++ == '\\')
57                 {
58                         if (*tp == '\\')
59                                 tp++;
60                         else if (!isdigit((int) *tp++) ||
61                                          !isdigit((int) *tp++) ||
62                                          !isdigit((int) *tp++))
63                                 elog(ERROR, "Bad input string for type bytea");
64                 }
65         tp = inputText;
66         byte += VARHDRSZ;
67         result = (bytea *) palloc(byte);
68         result->vl_len = byte;          /* varlena? */
69         rp = result->vl_dat;
70         while (*tp != '\0')
71                 if (*tp != '\\' || *++tp == '\\')
72                         *rp++ = *tp++;
73                 else
74                 {
75                         byte = VAL(*tp++);
76                         byte <<= 3;
77                         byte += VAL(*tp++);
78                         byte <<= 3;
79                         *rp++ = byte + VAL(*tp++);
80                 }
81         return result;
82 }
83
84 /*
85  *              byteaout                - converts to printable representation of byte array
86  *
87  *              Non-printable characters are inserted as '\nnn' (octal) and '\' as
88  *              '\\'.
89  *
90  *              NULL vlena should be an error--returning string with NULL for now.
91  */
92 char *
93 byteaout(bytea *vlena)
94 {
95         char       *result;
96         char       *vp;
97         char       *rp;
98         int                     val;                    /* holds unprintable chars */
99         int                     i;
100         int                     len;
101
102         if (vlena == NULL)
103         {
104                 result = (char *) palloc(2);
105                 result[0] = '-';
106                 result[1] = '\0';
107                 return result;
108         }
109         vp = vlena->vl_dat;
110         len = 1;                                        /* empty string has 1 char */
111         for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
112                 if (*vp == '\\')
113                         len += 2;
114                 else if (isascii((int) *vp) && isprint((int) *vp))
115                         len++;
116                 else
117                         len += VARHDRSZ;
118         rp = result = (char *) palloc(len);
119         vp = vlena->vl_dat;
120         for (i = vlena->vl_len - VARHDRSZ; i != 0; i--)
121                 if (*vp == '\\')
122                 {
123                         vp++;
124                         *rp++ = '\\';
125                         *rp++ = '\\';
126                 }
127                 else if (isascii((int) *vp) && isprint((int) *vp))
128                         *rp++ = *vp++;
129                 else
130                 {
131                         val = *vp++;
132                         *rp = '\\';
133                         rp += 3;
134                         *rp-- = DIG(val & 07);
135                         val >>= 3;
136                         *rp-- = DIG(val & 07);
137                         val >>= 3;
138                         *rp = DIG(val & 03);
139                         rp += 3;
140                 }
141         *rp = '\0';
142         return result;
143 }
144
145
146 /*
147  *              textin                  - converts "..." to internal representation
148  */
149 text *
150 textin(char *inputText)
151 {
152         text       *result;
153         int                     len;
154
155         if (inputText == NULL)
156                 return NULL;
157
158         len = strlen(inputText) + VARHDRSZ;
159         result = (text *) palloc(len);
160         VARSIZE(result) = len;
161
162         memmove(VARDATA(result), inputText, len - VARHDRSZ);
163
164 #ifdef CYR_RECODE
165         convertstr(VARDATA(result), len - VARHDRSZ, 0);
166 #endif
167
168         return result;
169 }
170
171 /*
172  *              textout                 - converts internal representation to "..."
173  */
174 char *
175 textout(text *vlena)
176 {
177         int                     len;
178         char       *result;
179
180         if (vlena == NULL)
181         {
182                 result = (char *) palloc(2);
183                 result[0] = '-';
184                 result[1] = '\0';
185                 return result;
186         }
187         len = VARSIZE(vlena) - VARHDRSZ;
188         result = (char *) palloc(len + 1);
189         memmove(result, VARDATA(vlena), len);
190         result[len] = '\0';
191
192 #ifdef CYR_RECODE
193         convertstr(result, len, 1);
194 #endif
195
196         return result;
197 }
198
199
200 /* ========== PUBLIC ROUTINES ========== */
201
202 /*
203  * textlen -
204  *        returns the logical length of a text*
205  *         (which is less than the VARSIZE of the text*)
206  */
207 int32
208 textlen(text *t)
209 {
210 #ifdef MULTIBYTE
211         unsigned char *s;
212         int                     len,
213                                 l,
214                                 wl;
215
216 #endif
217
218         if (!PointerIsValid(t))
219                 return 0;
220
221 #ifdef MULTIBYTE
222         len = 0;
223         s = VARDATA(t);
224         l = VARSIZE(t) - VARHDRSZ;
225         while (l > 0)
226         {
227                 wl = pg_mblen(s);
228                 l -= wl;
229                 s += wl;
230                 len++;
231         }
232         return (len);
233 #else
234         return VARSIZE(t) - VARHDRSZ;
235 #endif
236
237 }       /* textlen() */
238
239 /*
240  * textoctetlen -
241  *        returns the physical length of a text*
242  *         (which is less than the VARSIZE of the text*)
243  */
244 int32
245 textoctetlen(text *t)
246 {
247         if (!PointerIsValid(t))
248                 return 0;
249
250         return VARSIZE(t) - VARHDRSZ;
251 }       /* textoctetlen() */
252
253 /*
254  * textcat -
255  *        takes two text* and returns a text* that is the concatentation of
256  *        the two.
257  *
258  * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
259  * Updated by Thomas, Thomas.Lockhart@jpl.nasa.gov 1997-07-10.
260  * Allocate space for output in all cases.
261  * XXX - thomas 1997-07-10
262  */
263 text *
264 textcat(text *t1, text *t2)
265 {
266         int                     len1,
267                                 len2,
268                                 len;
269         char       *ptr;
270         text       *result;
271
272         if (!PointerIsValid(t1) || !PointerIsValid(t2))
273                 return NULL;
274
275         len1 = (VARSIZE(t1) - VARHDRSZ);
276         if (len1 < 0)
277                 len1 = 0;
278         while (len1 > 0 && VARDATA(t1)[len1 - 1] == '\0')
279                 len1--;
280
281         len2 = (VARSIZE(t2) - VARHDRSZ);
282         if (len2 < 0)
283                 len2 = 0;
284         while (len2 > 0 && VARDATA(t2)[len2 - 1] == '\0')
285                 len2--;
286
287         len = len1 + len2 + VARHDRSZ;
288         result = palloc(len);
289
290         /* Set size of result string... */
291         VARSIZE(result) = len;
292
293         /* Fill data field of result string... */
294         ptr = VARDATA(result);
295         if (len1 > 0)
296                 memcpy(ptr, VARDATA(t1), len1);
297         if (len2 > 0)
298                 memcpy(ptr + len1, VARDATA(t2), len2);
299
300         return result;
301 }       /* textcat() */
302
303 /*
304  * text_substr()
305  * Return a substring starting at the specified position.
306  * - thomas 1997-12-31
307  *
308  * Input:
309  *      - string
310  *      - starting position (is one-based)
311  *      - string length
312  *
313  * If the starting position is zero or less, then return from the start of the string
314  *      adjusting the length to be consistant with the "negative start" per SQL92.
315  * If the length is less than zero, return the remaining string.
316  *
317  * Note that the arguments operate on octet length,
318  *      so not aware of multi-byte character sets.
319  *
320  * Added multi-byte support.
321  * - Tatsuo Ishii 1998-4-21
322  * Changed behavior if starting position is less than one to conform to SQL92 behavior.
323  * Formerly returned the entire string; now returns a portion.
324  * - Thomas Lockhart 1998-12-10
325  */
326 Datum
327 text_substr(PG_FUNCTION_ARGS)
328 {
329         text       *string = PG_GETARG_TEXT_P(0);
330         int32           m = PG_GETARG_INT32(1);
331         int32           n = PG_GETARG_INT32(2);
332         text       *ret;
333         int                     len;
334 #ifdef MULTIBYTE
335         int                     i;
336         char       *p;
337 #endif
338
339         len = VARSIZE(string) - VARHDRSZ;
340 #ifdef MULTIBYTE
341         len = pg_mbstrlen_with_len(VARDATA(string), len);
342 #endif
343
344         /* starting position after the end of the string? */
345         if (m > len)
346         {
347                 m = 1;
348                 n = 0;
349         }
350
351         /*
352          * starting position before the start of the string? then offset into
353          * the string per SQL92 spec...
354          */
355         else if (m < 1)
356         {
357                 n += (m - 1);
358                 m = 1;
359         }
360
361         /* m will now become a zero-based starting position */
362         m--;
363         if (((m + n) > len) || (n < 0))
364                 n = (len - m);
365
366 #ifdef MULTIBYTE
367         p = VARDATA(string);
368         for (i = 0; i < m; i++)
369                 p += pg_mblen(p);
370         m = p - VARDATA(string);
371         for (i = 0; i < n; i++)
372                 p += pg_mblen(p);
373         n = p - (VARDATA(string) + m);
374 #endif
375
376         ret = (text *) palloc(VARHDRSZ + n);
377         VARSIZE(ret) = VARHDRSZ + n;
378
379         memcpy(VARDATA(ret), VARDATA(string) + m, n);
380
381         PG_RETURN_TEXT_P(ret);
382 }
383
384 /*
385  * textpos -
386  *        Return the position of the specified substring.
387  *        Implements the SQL92 POSITION() function.
388  *        Ref: A Guide To The SQL Standard, Date & Darwen, 1997
389  * - thomas 1997-07-27
390  *
391  * Added multi-byte support.
392  * - Tatsuo Ishii 1998-4-21
393  */
394 int32
395 textpos(text *t1, text *t2)
396 {
397         int                     pos;
398         int                     px,
399                                 p;
400         int                     len1,
401                                 len2;
402         pg_wchar   *p1,
403                            *p2;
404
405 #ifdef MULTIBYTE
406         pg_wchar   *ps1,
407                            *ps2;
408
409 #endif
410
411         if (!PointerIsValid(t1) || !PointerIsValid(t2))
412                 return 0;
413
414         if (VARSIZE(t2) <= 0)
415                 return 1;
416
417         len1 = (VARSIZE(t1) - VARHDRSZ);
418         len2 = (VARSIZE(t2) - VARHDRSZ);
419 #ifdef MULTIBYTE
420         ps1 = p1 = (pg_wchar *) palloc((len1 + 1) * sizeof(pg_wchar));
421         (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t1), p1, len1);
422         len1 = pg_wchar_strlen(p1);
423         ps2 = p2 = (pg_wchar *) palloc((len2 + 1) * sizeof(pg_wchar));
424         (void) pg_mb2wchar_with_len((unsigned char *) VARDATA(t2), p2, len2);
425         len2 = pg_wchar_strlen(p2);
426 #else
427         p1 = VARDATA(t1);
428         p2 = VARDATA(t2);
429 #endif
430         pos = 0;
431         px = (len1 - len2);
432         for (p = 0; p <= px; p++)
433         {
434 #ifdef MULTIBYTE
435                 if ((*p2 == *p1) && (pg_wchar_strncmp(p1, p2, len2) == 0))
436 #else
437                 if ((*p2 == *p1) && (strncmp(p1, p2, len2) == 0))
438 #endif
439                 {
440                         pos = p + 1;
441                         break;
442                 };
443                 p1++;
444         };
445 #ifdef MULTIBYTE
446         pfree(ps1);
447         pfree(ps2);
448 #endif
449         return pos;
450 }       /* textpos() */
451
452 /*
453  *              texteq                  - returns 1 iff arguments are equal
454  *              textne                  - returns 1 iff arguments are not equal
455  */
456 bool
457 texteq(text *arg1, text *arg2)
458 {
459         int                     len;
460         char       *a1p,
461                            *a2p;
462
463         if (arg1 == NULL || arg2 == NULL)
464                 return (bool) NULL;
465         if ((len = arg1->vl_len) != arg2->vl_len)
466                 return (bool) 0;
467         a1p = arg1->vl_dat;
468         a2p = arg2->vl_dat;
469
470         /*
471          * Varlenas are stored as the total size (data + size variable)
472          * followed by the data. Use VARHDRSZ instead of explicit sizeof() -
473          * thomas 1997-07-10
474          */
475         len -= VARHDRSZ;
476         while (len-- != 0)
477                 if (*a1p++ != *a2p++)
478                         return (bool) 0;
479         return (bool) 1;
480 }       /* texteq() */
481
482 bool
483 textne(text *arg1, text *arg2)
484 {
485         return (bool) !texteq(arg1, arg2);
486 }
487
488 /* varstr_cmp()
489  * Comparison function for text strings with given lengths.
490  * Includes locale support, but must copy strings to temporary memory
491  *      to allow null-termination for inputs to strcoll().
492  * Returns -1, 0 or 1
493  */
494 int
495 varstr_cmp(char *arg1, int len1, char *arg2, int len2)
496 {
497         int                     result;
498         char       *a1p,
499                            *a2p;
500
501 #ifdef USE_LOCALE
502         a1p = (unsigned char *) palloc(len1 + 1);
503         a2p = (unsigned char *) palloc(len2 + 1);
504
505         memcpy(a1p, arg1, len1);
506         *(a1p + len1) = '\0';
507         memcpy(a2p, arg2, len2);
508         *(a2p + len2) = '\0';
509
510         result = strcoll(a1p, a2p);
511
512         pfree(a1p);
513         pfree(a2p);
514
515 #else
516
517         a1p = arg1;
518         a2p = arg2;
519
520         result = strncmp(a1p, a2p, Min(len1, len2));
521         if ((result == 0) && (len1 != len2))
522                 result = (len1 < len2) ? -1 : 1;
523 #endif
524
525         return result;
526 }       /* varstr_cmp() */
527
528
529 /* text_cmp()
530  * Comparison function for text strings.
531  * Includes locale support, but must copy strings to temporary memory
532  *      to allow null-termination for inputs to strcoll().
533  * XXX HACK code for textlen() indicates that there can be embedded nulls
534  *      but it appears that most routines (incl. this one) assume not! - tgl 97/04/07
535  * Returns -1, 0 or 1
536  */
537 static int
538 text_cmp(text *arg1, text *arg2)
539 {
540         char       *a1p,
541                            *a2p;
542         int                     len1,
543                                 len2;
544
545         if (arg1 == NULL || arg2 == NULL)
546                 return (bool) FALSE;
547
548         a1p = VARDATA(arg1);
549         a2p = VARDATA(arg2);
550
551         len1 = VARSIZE(arg1) - VARHDRSZ;
552         len2 = VARSIZE(arg2) - VARHDRSZ;
553
554         return varstr_cmp(a1p, len1, a2p, len2);
555 }       /* text_cmp() */
556
557 /* text_lt()
558  * Comparison function for text strings.
559  */
560 bool
561 text_lt(text *arg1, text *arg2)
562 {
563         return (bool) (text_cmp(arg1, arg2) < 0);
564 }       /* text_lt() */
565
566 /* text_le()
567  * Comparison function for text strings.
568  */
569 bool
570 text_le(text *arg1, text *arg2)
571 {
572         return (bool) (text_cmp(arg1, arg2) <= 0);
573 }       /* text_le() */
574
575 bool
576 text_gt(text *arg1, text *arg2)
577 {
578         return (bool) !text_le(arg1, arg2);
579 }
580
581 bool
582 text_ge(text *arg1, text *arg2)
583 {
584         return (bool) !text_lt(arg1, arg2);
585 }
586
587 text *
588 text_larger(text *arg1, text *arg2)
589 {
590         text       *result;
591         text       *temp;
592
593         temp = ((text_cmp(arg1, arg2) <= 0) ? arg2 : arg1);
594
595         /* Make a copy */
596
597         result = (text *) palloc(VARSIZE(temp));
598         memmove((char *) result, (char *) temp, VARSIZE(temp));
599
600         return (result);
601 }
602
603 text *
604 text_smaller(text *arg1, text *arg2)
605 {
606         text       *result;
607         text       *temp;
608
609         temp = ((text_cmp(arg1, arg2) > 0) ? arg2 : arg1);
610
611         /* Make a copy */
612
613         result = (text *) palloc(VARSIZE(temp));
614         memmove((char *) result, (char *) temp, VARSIZE(temp));
615
616         return (result);
617 }
618
619 /*-------------------------------------------------------------
620  * byteaoctetlen
621  *
622  * get the number of bytes contained in an instance of type 'bytea'
623  *-------------------------------------------------------------
624  */
625 int32
626 byteaoctetlen(bytea *v)
627 {
628         if (!PointerIsValid(v))
629                 return 0;
630
631         return VARSIZE(v) - VARHDRSZ;
632 }
633
634 /*-------------------------------------------------------------
635  * byteaGetByte
636  *
637  * this routine treats "bytea" as an array of bytes.
638  * It returns the Nth byte (a number between 0 and 255).
639  *-------------------------------------------------------------
640  */
641 Datum
642 byteaGetByte(PG_FUNCTION_ARGS)
643 {
644         bytea      *v = PG_GETARG_BYTEA_P(0);
645         int32           n = PG_GETARG_INT32(1);
646         int                     len;
647         int                     byte;
648
649         len = VARSIZE(v) - VARHDRSZ;
650
651         if (n < 0 || n >= len)
652                 elog(ERROR, "byteaGetByte: index %d out of range [0..%d]",
653                          n, len - 1);
654
655         byte = ((unsigned char *) VARDATA(v))[n];
656
657         PG_RETURN_INT32(byte);
658 }
659
660 /*-------------------------------------------------------------
661  * byteaGetBit
662  *
663  * This routine treats a "bytea" type like an array of bits.
664  * It returns the value of the Nth bit (0 or 1).
665  *
666  *-------------------------------------------------------------
667  */
668 Datum
669 byteaGetBit(PG_FUNCTION_ARGS)
670 {
671         bytea      *v = PG_GETARG_BYTEA_P(0);
672         int32           n = PG_GETARG_INT32(1);
673         int                     byteNo,
674                                 bitNo;
675         int                     len;
676         int                     byte;
677
678         len = VARSIZE(v) - VARHDRSZ;
679
680         if (n < 0 || n >= len * 8)
681                 elog(ERROR, "byteaGetBit: index %d out of range [0..%d]",
682                          n, len * 8 - 1);
683
684         byteNo = n / 8;
685         bitNo = n % 8;
686
687         byte = ((unsigned char *) VARDATA(v))[byteNo];
688
689         if (byte & (1 << bitNo))
690                 PG_RETURN_INT32(1);
691         else
692                 PG_RETURN_INT32(0);
693 }
694
695 /*-------------------------------------------------------------
696  * byteaSetByte
697  *
698  * Given an instance of type 'bytea' creates a new one with
699  * the Nth byte set to the given value.
700  *
701  *-------------------------------------------------------------
702  */
703 Datum
704 byteaSetByte(PG_FUNCTION_ARGS)
705 {
706         bytea      *v = PG_GETARG_BYTEA_P(0);
707         int32           n = PG_GETARG_INT32(1);
708         int32           newByte = PG_GETARG_INT32(2);
709         int                     len;
710         bytea      *res;
711
712         len = VARSIZE(v) - VARHDRSZ;
713
714         if (n < 0 || n >= len)
715                 elog(ERROR, "byteaSetByte: index %d out of range [0..%d]",
716                          n, len - 1);
717
718         /*
719          * Make a copy of the original varlena.
720          */
721         res = (bytea *) palloc(VARSIZE(v));
722         memcpy((char *) res, (char *) v, VARSIZE(v));
723
724         /*
725          * Now set the byte.
726          */
727         ((unsigned char *) VARDATA(res))[n] = newByte;
728
729         PG_RETURN_BYTEA_P(res);
730 }
731
732 /*-------------------------------------------------------------
733  * byteaSetBit
734  *
735  * Given an instance of type 'bytea' creates a new one with
736  * the Nth bit set to the given value.
737  *
738  *-------------------------------------------------------------
739  */
740 Datum
741 byteaSetBit(PG_FUNCTION_ARGS)
742 {
743         bytea      *v = PG_GETARG_BYTEA_P(0);
744         int32           n = PG_GETARG_INT32(1);
745         int32           newBit = PG_GETARG_INT32(2);
746         bytea      *res;
747         int                     len;
748         int                     oldByte,
749                                 newByte;
750         int                     byteNo,
751                                 bitNo;
752
753         len = VARSIZE(v) - VARHDRSZ;
754
755         if (n < 0 || n >= len * 8)
756                 elog(ERROR, "byteaSetBit: index %d out of range [0..%d]",
757                          n, len * 8 - 1);
758
759         byteNo = n / 8;
760         bitNo = n % 8;
761
762         /*
763          * sanity check!
764          */
765         if (newBit != 0 && newBit != 1)
766                 elog(ERROR, "byteaSetBit: new bit must be 0 or 1");
767
768         /*
769          * Make a copy of the original varlena.
770          */
771         res = (bytea *) palloc(VARSIZE(v));
772         memcpy((char *) res, (char *) v, VARSIZE(v));
773
774         /*
775          * Update the byte.
776          */
777         oldByte = ((unsigned char *) VARDATA(res))[byteNo];
778
779         if (newBit == 0)
780                 newByte = oldByte & (~(1 << bitNo));
781         else
782                 newByte = oldByte | (1 << bitNo);
783
784         ((unsigned char *) VARDATA(res))[byteNo] = newByte;
785
786         PG_RETURN_BYTEA_P(res);
787 }
788
789
790 /* text_name()
791  * Converts a text() type to a NameData type.
792  */
793 NameData   *
794 text_name(text *s)
795 {
796         NameData   *result;
797         int                     len;
798
799         if (s == NULL)
800                 return NULL;
801
802         len = VARSIZE(s) - VARHDRSZ;
803         if (len > NAMEDATALEN)
804                 len = NAMEDATALEN;
805
806 #ifdef STRINGDEBUG
807         printf("text- convert string length %d (%d) ->%d\n",
808                    VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
809 #endif
810
811         result = palloc(NAMEDATALEN);
812         StrNCpy(NameStr(*result), VARDATA(s), NAMEDATALEN);
813
814         /* now null pad to full length... */
815         while (len < NAMEDATALEN)
816         {
817                 *(NameStr(*result) + len) = '\0';
818                 len++;
819         }
820
821         return result;
822 }       /* text_name() */
823
824 /* name_text()
825  * Converts a NameData type to a text type.
826  */
827 text *
828 name_text(NameData *s)
829 {
830         text       *result;
831         int                     len;
832
833         if (s == NULL)
834                 return NULL;
835
836         len = strlen(NameStr(*s));
837
838 #ifdef STRINGDEBUG
839         printf("text- convert string length %d (%d) ->%d\n",
840                    VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
841 #endif
842
843         result = palloc(VARHDRSZ + len);
844         strncpy(VARDATA(result), NameStr(*s), len);
845         VARSIZE(result) = len + VARHDRSZ;
846
847         return result;
848 }       /* name_text() */