comparison src/fns.c @ 771:943eaba38521

[xemacs-hg @ 2002-03-13 08:51:24 by ben] The big ben-mule-21-5 check-in! Various files were added and deleted. See CHANGES-ben-mule. There are still some test suite failures. No crashes, though. Many of the failures have to do with problems in the test suite itself rather than in the actual code. I'll be addressing these in the next day or so -- none of the test suite failures are at all critical. Meanwhile I'll be trying to address the biggest issues -- i.e. build or run failures, which will almost certainly happen on various platforms. All comments should be sent to ben@xemacs.org -- use a Cc: if necessary when sending to mailing lists. There will be pre- and post- tags, something like pre-ben-mule-21-5-merge-in, and post-ben-mule-21-5-merge-in.
author ben
date Wed, 13 Mar 2002 08:54:06 +0000
parents 358bd84dc7ff
children 578cb2932d72
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
1 /* Random utility Lisp functions. 1 /* Random utility Lisp functions.
2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc. 2 Copyright (C) 1985, 86, 87, 93, 94, 95 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996 Ben Wing. 3 Copyright (C) 1995, 1996, 2000, 2001, 2002 Ben Wing.
4 4
5 This file is part of XEmacs. 5 This file is part of XEmacs.
6 6
7 XEmacs is free software; you can redistribute it and/or modify it 7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the 8 under the terms of the GNU General Public License as published by the
35 #define vector ***** 35 #define vector *****
36 36
37 #include "lisp.h" 37 #include "lisp.h"
38 38
39 #include "sysfile.h" 39 #include "sysfile.h"
40 #include "sysproc.h" /* for qxe_getpid() */
40 41
41 #include "buffer.h" 42 #include "buffer.h"
42 #include "bytecode.h" 43 #include "bytecode.h"
43 #include "device.h" 44 #include "device.h"
44 #include "events.h" 45 #include "events.h"
55 Lisp_Object Qstring_lessp; 56 Lisp_Object Qstring_lessp;
56 Lisp_Object Qidentity; 57 Lisp_Object Qidentity;
57 58
58 Lisp_Object Qbase64_conversion_error; 59 Lisp_Object Qbase64_conversion_error;
59 60
61 Lisp_Object Vpath_separator;
62
60 static int internal_old_equal (Lisp_Object, Lisp_Object, int); 63 static int internal_old_equal (Lisp_Object, Lisp_Object, int);
61 Lisp_Object safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth); 64 Lisp_Object safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth);
62 65
63 static Lisp_Object 66 static Lisp_Object
64 mark_bit_vector (Lisp_Object obj) 67 mark_bit_vector (Lisp_Object obj)
137 (arg)) 140 (arg))
138 { 141 {
139 return arg; 142 return arg;
140 } 143 }
141 144
142 extern long get_random (void);
143 extern void seed_random (long arg);
144
145 DEFUN ("random", Frandom, 0, 1, 0, /* 145 DEFUN ("random", Frandom, 0, 1, 0, /*
146 Return a pseudo-random number. 146 Return a pseudo-random number.
147 All integers representable in Lisp are equally likely. 147 All integers representable in Lisp are equally likely.
148 On most systems, this is 28 bits' worth. 148 On most systems, this is 28 bits' worth.
149 With positive integer argument N, return random number in interval [0,N). 149 With positive integer argument N, return random number in interval [0,N).
153 { 153 {
154 EMACS_INT val; 154 EMACS_INT val;
155 unsigned long denominator; 155 unsigned long denominator;
156 156
157 if (EQ (limit, Qt)) 157 if (EQ (limit, Qt))
158 seed_random (getpid () + time (NULL)); 158 seed_random (qxe_getpid () + time (NULL));
159 if (NATNUMP (limit) && !ZEROP (limit)) 159 if (NATNUMP (limit) && !ZEROP (limit))
160 { 160 {
161 /* Try to take our random number from the higher bits of VAL, 161 /* Try to take our random number from the higher bits of VAL,
162 not the lower, since (says Gentzel) the low bits of `random' 162 not the lower, since (says Gentzel) the low bits of `random'
163 are less random than the higher ones. We do this by using the 163 are less random than the higher ones. We do this by using the
296 296
297 return (((len = string_length (p1)) == string_length (p2)) && 297 return (((len = string_length (p1)) == string_length (p2)) &&
298 !memcmp (string_data (p1), string_data (p2), len)) ? Qt : Qnil; 298 !memcmp (string_data (p1), string_data (p2), len)) ? Qt : Qnil;
299 } 299 }
300 300
301
302 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /* 301 DEFUN ("string-lessp", Fstring_lessp, 2, 2, 0, /*
303 Return t if first arg string is less than second in lexicographic order. 302 Return t if first arg string is less than second in lexicographic order.
304 If I18N2 support (but not Mule support) was compiled in, ordering is 303 Comparison is simply done on a character-by-character basis using the
305 determined by the locale. (Case is significant for the default C locale.) 304 numeric value of a character. (Note that this may not produce
306 In all other cases, comparison is simply done on a character-by- 305 particularly meaningful results under Mule if characters from
307 character basis using the numeric value of a character. (Note that 306 different charsets are being compared.)
308 this may not produce particularly meaningful results under Mule if
309 characters from different charsets are being compared.)
310 307
311 Symbols are also allowed; their print names are used instead. 308 Symbols are also allowed; their print names are used instead.
312 309
313 The reason that the I18N2 locale-specific collation is not used under 310 Currently we don't do proper language-specific collation or handle
314 Mule is that the locale model of internationalization does not handle 311 multiple character sets. This may be changed when Unicode support
315 multiple charsets and thus has no hope of working properly under Mule. 312 is implemented.
316 What we really should do is create a collation table over all built-in
317 charsets. This is extremely difficult to do from scratch, however.
318
319 Unicode is a good first step towards solving this problem. In fact,
320 it is quite likely that a collation table exists (or will exist) for
321 Unicode. When Unicode support is added to XEmacs/Mule, this problem
322 may be solved.
323 */ 313 */
324 (string1, string2)) 314 (string1, string2))
325 { 315 {
326 Lisp_String *p1, *p2; 316 Lisp_String *p1, *p2;
327 Charcount end, len2; 317 Charcount end, len2;
346 end = string_char_length (p1); 336 end = string_char_length (p1);
347 len2 = string_char_length (p2); 337 len2 = string_char_length (p2);
348 if (end > len2) 338 if (end > len2)
349 end = len2; 339 end = len2;
350 340
351 #if defined (I18N2) && !defined (MULE)
352 /* There is no hope of this working under Mule. Even if we converted
353 the data into an external format so that strcoll() processed it
354 properly, it would still not work because strcoll() does not
355 handle multiple locales. This is the fundamental flaw in the
356 locale model. */
357 {
358 Bytecount bcend = charcount_to_bytecount (string_data (p1), end);
359 /* Compare strings using collation order of locale. */
360 /* Need to be tricky to handle embedded nulls. */
361
362 for (i = 0; i < bcend; i += strlen((char *) string_data (p1) + i) + 1)
363 {
364 int val = strcoll ((char *) string_data (p1) + i,
365 (char *) string_data (p2) + i);
366 if (val < 0)
367 return Qt;
368 if (val > 0)
369 return Qnil;
370 }
371 }
372 #else /* not I18N2, or MULE */
373 { 341 {
374 Intbyte *ptr1 = string_data (p1); 342 Intbyte *ptr1 = string_data (p1);
375 Intbyte *ptr2 = string_data (p2); 343 Intbyte *ptr2 = string_data (p2);
376 344
377 /* #### It is not really necessary to do this: We could compare 345 /* #### It is not really necessary to do this: We could compare
387 return charptr_emchar (ptr1) < charptr_emchar (ptr2) ? Qt : Qnil; 355 return charptr_emchar (ptr1) < charptr_emchar (ptr2) ? Qt : Qnil;
388 INC_CHARPTR (ptr1); 356 INC_CHARPTR (ptr1);
389 INC_CHARPTR (ptr2); 357 INC_CHARPTR (ptr2);
390 } 358 }
391 } 359 }
392 #endif /* not I18N2, or MULE */
393 /* Can't do i < len2 because then comparison between "foo" and "foo^@" 360 /* Can't do i < len2 because then comparison between "foo" and "foo^@"
394 won't work right in I18N2 case */ 361 won't work right in I18N2 case */
395 return end < len2 ? Qt : Qnil; 362 return end < len2 ? Qt : Qnil;
396 } 363 }
397 364
920 887
921 CHECK_STRING (string); 888 CHECK_STRING (string);
922 CHECK_INT (start); 889 CHECK_INT (start);
923 get_string_range_char (string, start, end, &ccstart, &ccend, 890 get_string_range_char (string, start, end, &ccstart, &ccend,
924 GB_HISTORICAL_STRING_BEHAVIOR); 891 GB_HISTORICAL_STRING_BEHAVIOR);
925 bstart = charcount_to_bytecount (XSTRING_DATA (string), ccstart); 892 bstart = XSTRING_INDEX_CHAR_TO_BYTE (string, ccstart);
926 blen = charcount_to_bytecount (XSTRING_DATA (string) + bstart, ccend - ccstart); 893 blen = XSTRING_OFFSET_CHAR_TO_BYTE_LEN (string, bstart, ccend - ccstart);
927 val = make_string (XSTRING_DATA (string) + bstart, blen); 894 val = make_string (XSTRING_DATA (string) + bstart, blen);
928 /* Copy any applicable extent information into the new string. */ 895 /* Copy any applicable extent information into the new string. */
929 copy_string_extents (val, string, 0, bstart, blen); 896 copy_string_extents (val, string, 0, bstart, blen);
930 return val; 897 return val;
931 } 898 }
1005 { 972 {
1006 abort (); /* unreachable, since Flength (sequence) did not get 973 abort (); /* unreachable, since Flength (sequence) did not get
1007 an error */ 974 an error */
1008 return Qnil; 975 return Qnil;
1009 } 976 }
977 }
978
979 /* Split STRING into a list of substrings. The substrings are the
980 parts of original STRING separated by SEPCHAR. */
981 static Lisp_Object
982 split_string_by_emchar_1 (const Intbyte *string, Bytecount size,
983 Emchar sepchar)
984 {
985 Lisp_Object result = Qnil;
986 const Intbyte *end = string + size;
987
988 while (1)
989 {
990 const Intbyte *p = string;
991 while (p < end)
992 {
993 if (charptr_emchar (p) == sepchar)
994 break;
995 INC_CHARPTR (p);
996 }
997 result = Fcons (make_string (string, p - string), result);
998 if (p < end)
999 {
1000 string = p;
1001 INC_CHARPTR (string); /* skip sepchar */
1002 }
1003 else
1004 break;
1005 }
1006 return Fnreverse (result);
1007 }
1008
1009 /* The same as the above, except PATH is an external C string (it is
1010 converted using Qfile_name), and sepchar is hardcoded to SEPCHAR
1011 (':' or whatever). */
1012 Lisp_Object
1013 split_external_path (const Extbyte *path)
1014 {
1015 Bytecount newlen;
1016 Intbyte *newpath;
1017 if (!path)
1018 return Qnil;
1019
1020 TO_INTERNAL_FORMAT (C_STRING, path, ALLOCA, (newpath, newlen), Qfile_name);
1021
1022 /* #### Does this make sense? It certainly does for
1023 split_env_path(), but it looks dubious here. Does any code
1024 depend on split_external_path("") returning nil instead of an empty
1025 string? */
1026 if (!newlen)
1027 return Qnil;
1028
1029 return split_string_by_emchar_1 (newpath, newlen, SEPCHAR);
1030 }
1031
1032 Lisp_Object
1033 split_env_path (const CIntbyte *evarname, const Intbyte *default_)
1034 {
1035 const Intbyte *path = 0;
1036 if (evarname)
1037 path = egetenv (evarname);
1038 if (!path)
1039 path = default_;
1040 if (!path)
1041 return Qnil;
1042 return split_string_by_emchar_1 (path, qxestrlen (path), SEPCHAR);
1043 }
1044
1045 /* Ben thinks this function should not exist or be exported to Lisp.
1046 We use it to define split-path-string in subr.el (not!). */
1047
1048 DEFUN ("split-string-by-char", Fsplit_string_by_char, 1, 2, 0, /*
1049 Split STRING into a list of substrings originally separated by SEPCHAR.
1050 */
1051 (string, sepchar))
1052 {
1053 CHECK_STRING (string);
1054 CHECK_CHAR (sepchar);
1055 return split_string_by_emchar_1 (XSTRING_DATA (string),
1056 XSTRING_LENGTH (string),
1057 XCHAR (sepchar));
1058 }
1059
1060 /* #### This was supposed to be in subr.el, but is used VERY early in
1061 the bootstrap process, so it goes here. Damn. */
1062
1063 DEFUN ("split-path", Fsplit_path, 1, 1, 0, /*
1064 Explode a search path into a list of strings.
1065 The path components are separated with the characters specified
1066 with `path-separator'.
1067 */
1068 (path))
1069 {
1070 CHECK_STRING (path);
1071
1072 while (!STRINGP (Vpath_separator)
1073 || (XSTRING_CHAR_LENGTH (Vpath_separator) != 1))
1074 Vpath_separator = signal_continuable_error
1075 (Qinvalid_state,
1076 "`path-separator' should be set to a single-character string",
1077 Vpath_separator);
1078
1079 return (split_string_by_emchar_1
1080 (XSTRING_DATA (path), XSTRING_LENGTH (path),
1081 charptr_emchar (XSTRING_DATA (Vpath_separator))));
1010 } 1082 }
1011 1083
1012 1084
1013 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /* 1085 DEFUN ("nthcdr", Fnthcdr, 2, 2, 0, /*
1014 Take cdr N times on LIST, and return the result. 1086 Take cdr N times on LIST, and return the result.
1330 Lisp_Object 1402 Lisp_Object
1331 assoc_no_quit (Lisp_Object key, Lisp_Object alist) 1403 assoc_no_quit (Lisp_Object key, Lisp_Object alist)
1332 { 1404 {
1333 int speccount = specpdl_depth (); 1405 int speccount = specpdl_depth ();
1334 specbind (Qinhibit_quit, Qt); 1406 specbind (Qinhibit_quit, Qt);
1335 return unbind_to (speccount, Fassoc (key, alist)); 1407 return unbind_to_1 (speccount, Fassoc (key, alist));
1336 } 1408 }
1337 1409
1338 DEFUN ("assq", Fassq, 2, 2, 0, /* 1410 DEFUN ("assq", Fassq, 2, 2, 0, /*
1339 Return non-nil if KEY is `eq' to the car of an element of ALIST. 1411 Return non-nil if KEY is `eq' to the car of an element of ALIST.
1340 The value is actually the element of ALIST whose car is KEY. 1412 The value is actually the element of ALIST whose car is KEY.
1575 Lisp_Object 1647 Lisp_Object
1576 remassoc_no_quit (Lisp_Object key, Lisp_Object alist) 1648 remassoc_no_quit (Lisp_Object key, Lisp_Object alist)
1577 { 1649 {
1578 int speccount = specpdl_depth (); 1650 int speccount = specpdl_depth ();
1579 specbind (Qinhibit_quit, Qt); 1651 specbind (Qinhibit_quit, Qt);
1580 return unbind_to (speccount, Fremassoc (key, alist)); 1652 return unbind_to_1 (speccount, Fremassoc (key, alist));
1581 } 1653 }
1582 1654
1583 DEFUN ("remassq", Fremassq, 2, 2, 0, /* 1655 DEFUN ("remassq", Fremassq, 2, 2, 0, /*
1584 Delete by side effect any elements of ALIST whose car is `eq' to KEY. 1656 Delete by side effect any elements of ALIST whose car is `eq' to KEY.
1585 The modified ALIST is returned. If the first member of ALIST has a car 1657 The modified ALIST is returned. If the first member of ALIST has a car
1723 Lisp_Object pred) 1795 Lisp_Object pred)
1724 { 1796 {
1725 Lisp_Object tmp; 1797 Lisp_Object tmp;
1726 1798
1727 /* prevents the GC from happening in call2 */ 1799 /* prevents the GC from happening in call2 */
1728 int speccount = specpdl_depth ();
1729 /* Emacs' GC doesn't actually relocate pointers, so this probably 1800 /* Emacs' GC doesn't actually relocate pointers, so this probably
1730 isn't strictly necessary */ 1801 isn't strictly necessary */
1731 record_unwind_protect (restore_gc_inhibit, 1802 int speccount = begin_gc_forbidden ();
1732 make_int (gc_currently_forbidden));
1733 gc_currently_forbidden = 1;
1734 tmp = call2 (pred, obj1, obj2); 1803 tmp = call2 (pred, obj1, obj2);
1735 unbind_to (speccount, Qnil); 1804 unbind_to (speccount);
1736 1805
1737 if (NILP (tmp)) 1806 if (NILP (tmp))
1738 return -1; 1807 return -1;
1739 else 1808 else
1740 return 1; 1809 return 1;
2057 { 2126 {
2058 if (ERRB_EQ (errb, ERROR_ME_WARN)) 2127 if (ERRB_EQ (errb, ERROR_ME_WARN))
2059 { 2128 {
2060 warn_when_safe_lispobj 2129 warn_when_safe_lispobj
2061 (Qlist, Qwarning, 2130 (Qlist, Qwarning,
2062 list2 (build_string 2131 list2 (build_msg_string
2063 ("Malformed property list -- list has been truncated"), 2132 ("Malformed property list -- list has been truncated"),
2064 *plist)); 2133 *plist));
2065 *badplace = Qnil; 2134 *badplace = Qnil;
2066 } 2135 }
2067 return Qunbound; 2136 return Qunbound;
2084 { 2153 {
2085 if (ERRB_EQ (errb, ERROR_ME_WARN)) 2154 if (ERRB_EQ (errb, ERROR_ME_WARN))
2086 { 2155 {
2087 warn_when_safe_lispobj 2156 warn_when_safe_lispobj
2088 (Qlist, Qwarning, 2157 (Qlist, Qwarning,
2089 list2 (build_string 2158 list2 (build_msg_string
2090 ("Circular property list -- list has been truncated"), 2159 ("Circular property list -- list has been truncated"),
2091 *plist)); 2160 *plist));
2092 *badplace = Qnil; 2161 *badplace = Qnil;
2093 } 2162 }
2094 return Qunbound; 2163 return Qunbound;
2733 Intbyte *end; 2802 Intbyte *end;
2734 2803
2735 CHECK_CHAR_COERCE_INT (item); 2804 CHECK_CHAR_COERCE_INT (item);
2736 CHECK_LISP_WRITEABLE (array); 2805 CHECK_LISP_WRITEABLE (array);
2737 2806
2807 sledgehammer_check_ascii_begin (array);
2738 item_bytecount = set_charptr_emchar (item_buf, XCHAR (item)); 2808 item_bytecount = set_charptr_emchar (item_buf, XCHAR (item));
2739 new_bytecount = item_bytecount * string_char_length (s); 2809 new_bytecount = item_bytecount * string_char_length (s);
2740 2810
2741 resize_string (s, -1, new_bytecount - old_bytecount); 2811 resize_string (s, -1, new_bytecount - old_bytecount);
2742 2812
2744 p < end; 2814 p < end;
2745 p += item_bytecount) 2815 p += item_bytecount)
2746 memcpy (p, item_buf, item_bytecount); 2816 memcpy (p, item_buf, item_bytecount);
2747 *p = '\0'; 2817 *p = '\0';
2748 2818
2819 set_string_ascii_begin (s,
2820 item_bytecount == 1 ?
2821 min (new_bytecount, MAX_STRING_ASCII_BEGIN) :
2822 0);
2749 bump_string_modiff (array); 2823 bump_string_modiff (array);
2824 sledgehammer_check_ascii_begin (array);
2750 } 2825 }
2751 else if (VECTORP (array)) 2826 else if (VECTORP (array))
2752 { 2827 {
2753 Lisp_Object *p = XVECTOR_DATA (array); 2828 Lisp_Object *p = XVECTOR_DATA (array);
2754 Elemcount len = XVECTOR_LENGTH (array); 2829 Elemcount len = XVECTOR_LENGTH (array);
3106 3181
3107 return sequence; 3182 return sequence;
3108 } 3183 }
3109 3184
3110 3185
3111 3186 /* Extra random functions */
3112 3187
3113 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /* 3188 DEFUN ("replace-list", Freplace_list, 2, 2, 0, /*
3114 Destructively replace the list OLD with NEW. 3189 Destructively replace the list OLD with NEW.
3115 This is like (copy-sequence NEW) except that it reuses the 3190 This is like (copy-sequence NEW) except that it reuses the
3116 conses in OLD as much as possible. If OLD and NEW are the same 3191 conses in OLD as much as possible. If OLD and NEW are the same
3146 XCDR (prevoldtail) = Qnil; 3221 XCDR (prevoldtail) = Qnil;
3147 else 3222 else
3148 old = Qnil; 3223 old = Qnil;
3149 3224
3150 return old; 3225 return old;
3226 }
3227
3228 Lisp_Object
3229 add_suffix_to_symbol (Lisp_Object symbol, const Char_ASCII *ascii_string)
3230 {
3231 return Fintern (concat2 (Fsymbol_name (symbol),
3232 build_string (ascii_string)),
3233 Qnil);
3234 }
3235
3236 Lisp_Object
3237 add_prefix_to_symbol (const Char_ASCII *ascii_string, Lisp_Object symbol)
3238 {
3239 return Fintern (concat2 (build_string (ascii_string),
3240 Fsymbol_name (symbol)),
3241 Qnil);
3151 } 3242 }
3152 3243
3153 3244
3154 /* #### this function doesn't belong in this file! */ 3245 /* #### this function doesn't belong in this file! */
3155 3246
3356 if (NILP (tem)) 3447 if (NILP (tem))
3357 invalid_state ("Required feature was not provided", feature); 3448 invalid_state ("Required feature was not provided", feature);
3358 3449
3359 /* Once loading finishes, don't undo it. */ 3450 /* Once loading finishes, don't undo it. */
3360 Vautoload_queue = Qt; 3451 Vautoload_queue = Qt;
3361 return unbind_to (speccount, feature); 3452 return unbind_to_1 (speccount, feature);
3362 } 3453 }
3363 } 3454 }
3364 3455
3365 /* base64 encode/decode functions. 3456 /* base64 encode/decode functions.
3366 3457
3612 ptr = alloca_array (type, XOA_len); \ 3703 ptr = alloca_array (type, XOA_len); \
3613 } while (0) 3704 } while (0)
3614 3705
3615 #define XMALLOC_UNBIND(ptr, len, speccount) do { \ 3706 #define XMALLOC_UNBIND(ptr, len, speccount) do { \
3616 if ((len) > MAX_ALLOCA) \ 3707 if ((len) > MAX_ALLOCA) \
3617 unbind_to (speccount, Qnil); \ 3708 unbind_to (speccount); \
3618 } while (0) 3709 } while (0)
3619 3710
3620 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /* 3711 DEFUN ("base64-encode-region", Fbase64_encode_region, 2, 3, "r", /*
3621 Base64-encode the region between START and END. 3712 Base64-encode the region between START and END.
3622 Return the length of the encoded text. 3713 Return the length of the encoded text.
3869 DEFSUBR (Fprovide); 3960 DEFSUBR (Fprovide);
3870 DEFSUBR (Fbase64_encode_region); 3961 DEFSUBR (Fbase64_encode_region);
3871 DEFSUBR (Fbase64_encode_string); 3962 DEFSUBR (Fbase64_encode_string);
3872 DEFSUBR (Fbase64_decode_region); 3963 DEFSUBR (Fbase64_decode_region);
3873 DEFSUBR (Fbase64_decode_string); 3964 DEFSUBR (Fbase64_decode_string);
3965
3966 DEFSUBR (Fsplit_string_by_char);
3967 DEFSUBR (Fsplit_path); /* #### */
3968 }
3969
3970 void
3971 vars_of_fns (void)
3972 {
3973 DEFVAR_LISP ("path-separator", &Vpath_separator /*
3974 The directory separator in search paths, as a string.
3975 */ );
3976 {
3977 char c = SEPCHAR;
3978 Vpath_separator = make_string ((Intbyte *)&c, 1);
3979 }
3874 } 3980 }
3875 3981
3876 void 3982 void
3877 init_provide_once (void) 3983 init_provide_once (void)
3878 { 3984 {