diff options
| author | Eli Zaretskii | 2010-09-23 08:09:12 -0400 |
|---|---|---|
| committer | Eli Zaretskii | 2010-09-23 08:09:12 -0400 |
| commit | 141624691330c7622d9a31d53ec919dee8e97473 (patch) | |
| tree | c8f2a43e69346342552c6a72a307555ae26a739f /src/alloc.c | |
| parent | 7228f056909af1ffe9d8f611b959638bc9544d2f (diff) | |
| download | emacs-141624691330c7622d9a31d53ec919dee8e97473.tar.gz emacs-141624691330c7622d9a31d53ec919dee8e97473.zip | |
Fix some more uses of int instead of EMACS_INT.
font.c (font_intern_prop): Use EMACS_INT for string length
variables.
character.c (parse_str_as_multibyte, str_as_multibyte)
(parse_str_to_multibyte, str_to_multibyte, str_as_unibyte)
(string_count_byte8, string_escape_byte8): Use EMACS_INT for
string length arguments, variables, and return values.
character.h (parse_str_as_multibyte, str_as_multibyte)
(parse_str_to_multibyte, str_to_multibyte, str_as_unibyte): Adjust
prototypes.
fns.c (Fstring_as_multibyte): Use EMACS_INT for string length
variables.
alloc.c <total_string_size>: Declare as EMACS_INT, not int.
(Fmake_string): Protect against too large strings.
(live_string_p, live_cons_p, live_symbol_p, live_float_p)
(live_misc_p): Use ptrdiff_t instead of int for pointer
differences.
(string_bytes, check_sblock, check_string_free_list)
(allocate_string_data, compact_small_strings, Fmake_string)
(Fmake_bool_vector, make_string, make_unibyte_string)
(make_multibyte_string, make_string_from_bytes)
(make_specified_string_string, Fmake_list, Fmake_vector): Use
EMACS_INT for string length variables and arguments.
(find_string_data_in_pure, make_pure_string, make_pure_c_string)
(Fpurecopy): Use EMACS_INT for string size.
(mark_vectorlike, mark_char_table, mark_object): Use EMACS_UINT
for vector size.
lisp.h (make_string, make_unibyte_string, make_multibyte_string)
(make_string_from_bytes, make_specified_string_string)
(make_pure_string, string_bytes): Adjust prototypes.
Diffstat (limited to 'src/alloc.c')
| -rw-r--r-- | src/alloc.c | 85 |
1 files changed, 48 insertions, 37 deletions
diff --git a/src/alloc.c b/src/alloc.c index 60b8016fb88..5cbc7cfe411 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -1644,7 +1644,7 @@ static int total_strings, total_free_strings; | |||
| 1644 | 1644 | ||
| 1645 | /* Number of bytes used by live strings. */ | 1645 | /* Number of bytes used by live strings. */ |
| 1646 | 1646 | ||
| 1647 | static int total_string_size; | 1647 | static EMACS_INT total_string_size; |
| 1648 | 1648 | ||
| 1649 | /* Given a pointer to a Lisp_String S which is on the free-list | 1649 | /* Given a pointer to a Lisp_String S which is on the free-list |
| 1650 | string_free_list, return a pointer to its successor in the | 1650 | string_free_list, return a pointer to its successor in the |
| @@ -1739,11 +1739,12 @@ static void check_sblock (struct sblock *); | |||
| 1739 | 1739 | ||
| 1740 | /* Like GC_STRING_BYTES, but with debugging check. */ | 1740 | /* Like GC_STRING_BYTES, but with debugging check. */ |
| 1741 | 1741 | ||
| 1742 | int | 1742 | EMACS_INT |
| 1743 | string_bytes (s) | 1743 | string_bytes (struct Lisp_String *s) |
| 1744 | struct Lisp_String *s; | ||
| 1745 | { | 1744 | { |
| 1746 | int nbytes = (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); | 1745 | EMACS_INT nbytes = |
| 1746 | (s->size_byte < 0 ? s->size & ~ARRAY_MARK_FLAG : s->size_byte); | ||
| 1747 | |||
| 1747 | if (!PURE_POINTER_P (s) | 1748 | if (!PURE_POINTER_P (s) |
| 1748 | && s->data | 1749 | && s->data |
| 1749 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) | 1750 | && nbytes != SDATA_NBYTES (SDATA_OF_STRING (s))) |
| @@ -1765,7 +1766,7 @@ check_sblock (b) | |||
| 1765 | { | 1766 | { |
| 1766 | /* Compute the next FROM here because copying below may | 1767 | /* Compute the next FROM here because copying below may |
| 1767 | overwrite data we need to compute it. */ | 1768 | overwrite data we need to compute it. */ |
| 1768 | int nbytes; | 1769 | EMACS_INT nbytes; |
| 1769 | 1770 | ||
| 1770 | /* Check that the string size recorded in the string is the | 1771 | /* Check that the string size recorded in the string is the |
| 1771 | same as the one recorded in the sdata structure. */ | 1772 | same as the one recorded in the sdata structure. */ |
| @@ -1825,7 +1826,7 @@ check_string_free_list () | |||
| 1825 | s = string_free_list; | 1826 | s = string_free_list; |
| 1826 | while (s != NULL) | 1827 | while (s != NULL) |
| 1827 | { | 1828 | { |
| 1828 | if ((unsigned)s < 1024) | 1829 | if ((unsigned long)s < 1024) |
| 1829 | abort(); | 1830 | abort(); |
| 1830 | s = NEXT_FREE_LISP_STRING (s); | 1831 | s = NEXT_FREE_LISP_STRING (s); |
| 1831 | } | 1832 | } |
| @@ -1913,7 +1914,7 @@ allocate_string_data (struct Lisp_String *s, | |||
| 1913 | { | 1914 | { |
| 1914 | struct sdata *data, *old_data; | 1915 | struct sdata *data, *old_data; |
| 1915 | struct sblock *b; | 1916 | struct sblock *b; |
| 1916 | int needed, old_nbytes; | 1917 | EMACS_INT needed, old_nbytes; |
| 1917 | 1918 | ||
| 1918 | /* Determine the number of bytes needed to store NBYTES bytes | 1919 | /* Determine the number of bytes needed to store NBYTES bytes |
| 1919 | of string data. */ | 1920 | of string data. */ |
| @@ -2155,7 +2156,7 @@ compact_small_strings (void) | |||
| 2155 | { | 2156 | { |
| 2156 | /* Compute the next FROM here because copying below may | 2157 | /* Compute the next FROM here because copying below may |
| 2157 | overwrite data we need to compute it. */ | 2158 | overwrite data we need to compute it. */ |
| 2158 | int nbytes; | 2159 | EMACS_INT nbytes; |
| 2159 | 2160 | ||
| 2160 | #ifdef GC_CHECK_STRING_BYTES | 2161 | #ifdef GC_CHECK_STRING_BYTES |
| 2161 | /* Check that the string size recorded in the string is the | 2162 | /* Check that the string size recorded in the string is the |
| @@ -2233,7 +2234,8 @@ INIT must be an integer that represents a character. */) | |||
| 2233 | { | 2234 | { |
| 2234 | register Lisp_Object val; | 2235 | register Lisp_Object val; |
| 2235 | register unsigned char *p, *end; | 2236 | register unsigned char *p, *end; |
| 2236 | int c, nbytes; | 2237 | int c; |
| 2238 | EMACS_INT nbytes; | ||
| 2237 | 2239 | ||
| 2238 | CHECK_NATNUM (length); | 2240 | CHECK_NATNUM (length); |
| 2239 | CHECK_NUMBER (init); | 2241 | CHECK_NUMBER (init); |
| @@ -2252,9 +2254,12 @@ INIT must be an integer that represents a character. */) | |||
| 2252 | { | 2254 | { |
| 2253 | unsigned char str[MAX_MULTIBYTE_LENGTH]; | 2255 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 2254 | int len = CHAR_STRING (c, str); | 2256 | int len = CHAR_STRING (c, str); |
| 2257 | EMACS_INT string_len = XINT (length); | ||
| 2255 | 2258 | ||
| 2256 | nbytes = len * XINT (length); | 2259 | if (string_len > MOST_POSITIVE_FIXNUM / len) |
| 2257 | val = make_uninit_multibyte_string (XINT (length), nbytes); | 2260 | error ("Maximum string size exceeded"); |
| 2261 | nbytes = len * string_len; | ||
| 2262 | val = make_uninit_multibyte_string (string_len, nbytes); | ||
| 2258 | p = SDATA (val); | 2263 | p = SDATA (val); |
| 2259 | end = p + nbytes; | 2264 | end = p + nbytes; |
| 2260 | while (p != end) | 2265 | while (p != end) |
| @@ -2277,7 +2282,8 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2277 | register Lisp_Object val; | 2282 | register Lisp_Object val; |
| 2278 | struct Lisp_Bool_Vector *p; | 2283 | struct Lisp_Bool_Vector *p; |
| 2279 | int real_init, i; | 2284 | int real_init, i; |
| 2280 | int length_in_chars, length_in_elts, bits_per_value; | 2285 | EMACS_INT length_in_chars, length_in_elts; |
| 2286 | int bits_per_value; | ||
| 2281 | 2287 | ||
| 2282 | CHECK_NATNUM (length); | 2288 | CHECK_NATNUM (length); |
| 2283 | 2289 | ||
| @@ -2317,10 +2323,10 @@ LENGTH must be a number. INIT matters only in whether it is t or nil. */) | |||
| 2317 | multibyte, depending on the contents. */ | 2323 | multibyte, depending on the contents. */ |
| 2318 | 2324 | ||
| 2319 | Lisp_Object | 2325 | Lisp_Object |
| 2320 | make_string (const char *contents, int nbytes) | 2326 | make_string (const char *contents, EMACS_INT nbytes) |
| 2321 | { | 2327 | { |
| 2322 | register Lisp_Object val; | 2328 | register Lisp_Object val; |
| 2323 | int nchars, multibyte_nbytes; | 2329 | EMACS_INT nchars, multibyte_nbytes; |
| 2324 | 2330 | ||
| 2325 | parse_str_as_multibyte (contents, nbytes, &nchars, &multibyte_nbytes); | 2331 | parse_str_as_multibyte (contents, nbytes, &nchars, &multibyte_nbytes); |
| 2326 | if (nbytes == nchars || nbytes != multibyte_nbytes) | 2332 | if (nbytes == nchars || nbytes != multibyte_nbytes) |
| @@ -2336,7 +2342,7 @@ make_string (const char *contents, int nbytes) | |||
| 2336 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ | 2342 | /* Make an unibyte string from LENGTH bytes at CONTENTS. */ |
| 2337 | 2343 | ||
| 2338 | Lisp_Object | 2344 | Lisp_Object |
| 2339 | make_unibyte_string (const char *contents, int length) | 2345 | make_unibyte_string (const char *contents, EMACS_INT length) |
| 2340 | { | 2346 | { |
| 2341 | register Lisp_Object val; | 2347 | register Lisp_Object val; |
| 2342 | val = make_uninit_string (length); | 2348 | val = make_uninit_string (length); |
| @@ -2350,7 +2356,8 @@ make_unibyte_string (const char *contents, int length) | |||
| 2350 | bytes at CONTENTS. */ | 2356 | bytes at CONTENTS. */ |
| 2351 | 2357 | ||
| 2352 | Lisp_Object | 2358 | Lisp_Object |
| 2353 | make_multibyte_string (const char *contents, int nchars, int nbytes) | 2359 | make_multibyte_string (const char *contents, |
| 2360 | EMACS_INT nchars, EMACS_INT nbytes) | ||
| 2354 | { | 2361 | { |
| 2355 | register Lisp_Object val; | 2362 | register Lisp_Object val; |
| 2356 | val = make_uninit_multibyte_string (nchars, nbytes); | 2363 | val = make_uninit_multibyte_string (nchars, nbytes); |
| @@ -2363,7 +2370,8 @@ make_multibyte_string (const char *contents, int nchars, int nbytes) | |||
| 2363 | CONTENTS. It is a multibyte string if NBYTES != NCHARS. */ | 2370 | CONTENTS. It is a multibyte string if NBYTES != NCHARS. */ |
| 2364 | 2371 | ||
| 2365 | Lisp_Object | 2372 | Lisp_Object |
| 2366 | make_string_from_bytes (const char *contents, int nchars, int nbytes) | 2373 | make_string_from_bytes (const char *contents, |
| 2374 | EMACS_INT nchars, EMACS_INT nbytes) | ||
| 2367 | { | 2375 | { |
| 2368 | register Lisp_Object val; | 2376 | register Lisp_Object val; |
| 2369 | val = make_uninit_multibyte_string (nchars, nbytes); | 2377 | val = make_uninit_multibyte_string (nchars, nbytes); |
| @@ -2380,7 +2388,8 @@ make_string_from_bytes (const char *contents, int nchars, int nbytes) | |||
| 2380 | characters by itself. */ | 2388 | characters by itself. */ |
| 2381 | 2389 | ||
| 2382 | Lisp_Object | 2390 | Lisp_Object |
| 2383 | make_specified_string (const char *contents, int nchars, int nbytes, int multibyte) | 2391 | make_specified_string (const char *contents, |
| 2392 | EMACS_INT nchars, EMACS_INT nbytes, int multibyte) | ||
| 2384 | { | 2393 | { |
| 2385 | register Lisp_Object val; | 2394 | register Lisp_Object val; |
| 2386 | 2395 | ||
| @@ -2768,7 +2777,7 @@ DEFUN ("make-list", Fmake_list, Smake_list, 2, 2, 0, | |||
| 2768 | (register Lisp_Object length, Lisp_Object init) | 2777 | (register Lisp_Object length, Lisp_Object init) |
| 2769 | { | 2778 | { |
| 2770 | register Lisp_Object val; | 2779 | register Lisp_Object val; |
| 2771 | register int size; | 2780 | register EMACS_INT size; |
| 2772 | 2781 | ||
| 2773 | CHECK_NATNUM (length); | 2782 | CHECK_NATNUM (length); |
| 2774 | size = XFASTINT (length); | 2783 | size = XFASTINT (length); |
| @@ -2946,7 +2955,7 @@ See also the function `vector'. */) | |||
| 2946 | { | 2955 | { |
| 2947 | Lisp_Object vector; | 2956 | Lisp_Object vector; |
| 2948 | register EMACS_INT sizei; | 2957 | register EMACS_INT sizei; |
| 2949 | register int index; | 2958 | register EMACS_INT index; |
| 2950 | register struct Lisp_Vector *p; | 2959 | register struct Lisp_Vector *p; |
| 2951 | 2960 | ||
| 2952 | CHECK_NATNUM (length); | 2961 | CHECK_NATNUM (length); |
| @@ -3786,7 +3795,7 @@ live_string_p (struct mem_node *m, void *p) | |||
| 3786 | if (m->type == MEM_TYPE_STRING) | 3795 | if (m->type == MEM_TYPE_STRING) |
| 3787 | { | 3796 | { |
| 3788 | struct string_block *b = (struct string_block *) m->start; | 3797 | struct string_block *b = (struct string_block *) m->start; |
| 3789 | int offset = (char *) p - (char *) &b->strings[0]; | 3798 | ptrdiff_t offset = (char *) p - (char *) &b->strings[0]; |
| 3790 | 3799 | ||
| 3791 | /* P must point to the start of a Lisp_String structure, and it | 3800 | /* P must point to the start of a Lisp_String structure, and it |
| 3792 | must not be on the free-list. */ | 3801 | must not be on the free-list. */ |
| @@ -3809,7 +3818,7 @@ live_cons_p (struct mem_node *m, void *p) | |||
| 3809 | if (m->type == MEM_TYPE_CONS) | 3818 | if (m->type == MEM_TYPE_CONS) |
| 3810 | { | 3819 | { |
| 3811 | struct cons_block *b = (struct cons_block *) m->start; | 3820 | struct cons_block *b = (struct cons_block *) m->start; |
| 3812 | int offset = (char *) p - (char *) &b->conses[0]; | 3821 | ptrdiff_t offset = (char *) p - (char *) &b->conses[0]; |
| 3813 | 3822 | ||
| 3814 | /* P must point to the start of a Lisp_Cons, not be | 3823 | /* P must point to the start of a Lisp_Cons, not be |
| 3815 | one of the unused cells in the current cons block, | 3824 | one of the unused cells in the current cons block, |
| @@ -3835,7 +3844,7 @@ live_symbol_p (struct mem_node *m, void *p) | |||
| 3835 | if (m->type == MEM_TYPE_SYMBOL) | 3844 | if (m->type == MEM_TYPE_SYMBOL) |
| 3836 | { | 3845 | { |
| 3837 | struct symbol_block *b = (struct symbol_block *) m->start; | 3846 | struct symbol_block *b = (struct symbol_block *) m->start; |
| 3838 | int offset = (char *) p - (char *) &b->symbols[0]; | 3847 | ptrdiff_t offset = (char *) p - (char *) &b->symbols[0]; |
| 3839 | 3848 | ||
| 3840 | /* P must point to the start of a Lisp_Symbol, not be | 3849 | /* P must point to the start of a Lisp_Symbol, not be |
| 3841 | one of the unused cells in the current symbol block, | 3850 | one of the unused cells in the current symbol block, |
| @@ -3861,7 +3870,7 @@ live_float_p (struct mem_node *m, void *p) | |||
| 3861 | if (m->type == MEM_TYPE_FLOAT) | 3870 | if (m->type == MEM_TYPE_FLOAT) |
| 3862 | { | 3871 | { |
| 3863 | struct float_block *b = (struct float_block *) m->start; | 3872 | struct float_block *b = (struct float_block *) m->start; |
| 3864 | int offset = (char *) p - (char *) &b->floats[0]; | 3873 | ptrdiff_t offset = (char *) p - (char *) &b->floats[0]; |
| 3865 | 3874 | ||
| 3866 | /* P must point to the start of a Lisp_Float and not be | 3875 | /* P must point to the start of a Lisp_Float and not be |
| 3867 | one of the unused cells in the current float block. */ | 3876 | one of the unused cells in the current float block. */ |
| @@ -3885,7 +3894,7 @@ live_misc_p (struct mem_node *m, void *p) | |||
| 3885 | if (m->type == MEM_TYPE_MISC) | 3894 | if (m->type == MEM_TYPE_MISC) |
| 3886 | { | 3895 | { |
| 3887 | struct marker_block *b = (struct marker_block *) m->start; | 3896 | struct marker_block *b = (struct marker_block *) m->start; |
| 3888 | int offset = (char *) p - (char *) &b->markers[0]; | 3897 | ptrdiff_t offset = (char *) p - (char *) &b->markers[0]; |
| 3889 | 3898 | ||
| 3890 | /* P must point to the start of a Lisp_Misc, not be | 3899 | /* P must point to the start of a Lisp_Misc, not be |
| 3891 | one of the unused cells in the current misc block, | 3900 | one of the unused cells in the current misc block, |
| @@ -4592,9 +4601,10 @@ check_pure_size (void) | |||
| 4592 | address. Return NULL if not found. */ | 4601 | address. Return NULL if not found. */ |
| 4593 | 4602 | ||
| 4594 | static char * | 4603 | static char * |
| 4595 | find_string_data_in_pure (const char *data, int nbytes) | 4604 | find_string_data_in_pure (const char *data, EMACS_INT nbytes) |
| 4596 | { | 4605 | { |
| 4597 | int i, skip, bm_skip[256], last_char_skip, infinity, start, start_max; | 4606 | int i; |
| 4607 | EMACS_INT skip, bm_skip[256], last_char_skip, infinity, start, start_max; | ||
| 4598 | const unsigned char *p; | 4608 | const unsigned char *p; |
| 4599 | char *non_lisp_beg; | 4609 | char *non_lisp_beg; |
| 4600 | 4610 | ||
| @@ -4661,7 +4671,8 @@ find_string_data_in_pure (const char *data, int nbytes) | |||
| 4661 | string; then the string is not protected from gc. */ | 4671 | string; then the string is not protected from gc. */ |
| 4662 | 4672 | ||
| 4663 | Lisp_Object | 4673 | Lisp_Object |
| 4664 | make_pure_string (const char *data, int nchars, int nbytes, int multibyte) | 4674 | make_pure_string (const char *data, |
| 4675 | EMACS_INT nchars, EMACS_INT nbytes, int multibyte) | ||
| 4665 | { | 4676 | { |
| 4666 | Lisp_Object string; | 4677 | Lisp_Object string; |
| 4667 | struct Lisp_String *s; | 4678 | struct Lisp_String *s; |
| @@ -4689,7 +4700,7 @@ make_pure_c_string (const char *data) | |||
| 4689 | { | 4700 | { |
| 4690 | Lisp_Object string; | 4701 | Lisp_Object string; |
| 4691 | struct Lisp_String *s; | 4702 | struct Lisp_String *s; |
| 4692 | int nchars = strlen (data); | 4703 | EMACS_INT nchars = strlen (data); |
| 4693 | 4704 | ||
| 4694 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); | 4705 | s = (struct Lisp_String *) pure_alloc (sizeof *s, Lisp_String); |
| 4695 | s->size = nchars; | 4706 | s->size = nchars; |
| @@ -4779,7 +4790,7 @@ Does not copy symbols. Copies strings without text properties. */) | |||
| 4779 | else if (COMPILEDP (obj) || VECTORP (obj)) | 4790 | else if (COMPILEDP (obj) || VECTORP (obj)) |
| 4780 | { | 4791 | { |
| 4781 | register struct Lisp_Vector *vec; | 4792 | register struct Lisp_Vector *vec; |
| 4782 | register int i; | 4793 | register EMACS_INT i; |
| 4783 | EMACS_INT size; | 4794 | EMACS_INT size; |
| 4784 | 4795 | ||
| 4785 | size = XVECTOR (obj)->size; | 4796 | size = XVECTOR (obj)->size; |
| @@ -5228,8 +5239,8 @@ static int mark_object_loop_halt; | |||
| 5228 | static void | 5239 | static void |
| 5229 | mark_vectorlike (struct Lisp_Vector *ptr) | 5240 | mark_vectorlike (struct Lisp_Vector *ptr) |
| 5230 | { | 5241 | { |
| 5231 | register EMACS_INT size = ptr->size; | 5242 | register EMACS_UINT size = ptr->size; |
| 5232 | register int i; | 5243 | register EMACS_UINT i; |
| 5233 | 5244 | ||
| 5234 | eassert (!VECTOR_MARKED_P (ptr)); | 5245 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5235 | VECTOR_MARK (ptr); /* Else mark it */ | 5246 | VECTOR_MARK (ptr); /* Else mark it */ |
| @@ -5251,8 +5262,8 @@ mark_vectorlike (struct Lisp_Vector *ptr) | |||
| 5251 | static void | 5262 | static void |
| 5252 | mark_char_table (struct Lisp_Vector *ptr) | 5263 | mark_char_table (struct Lisp_Vector *ptr) |
| 5253 | { | 5264 | { |
| 5254 | register EMACS_INT size = ptr->size & PSEUDOVECTOR_SIZE_MASK; | 5265 | register EMACS_UINT size = ptr->size & PSEUDOVECTOR_SIZE_MASK; |
| 5255 | register int i; | 5266 | register EMACS_UINT i; |
| 5256 | 5267 | ||
| 5257 | eassert (!VECTOR_MARKED_P (ptr)); | 5268 | eassert (!VECTOR_MARKED_P (ptr)); |
| 5258 | VECTOR_MARK (ptr); | 5269 | VECTOR_MARK (ptr); |
| @@ -5381,8 +5392,8 @@ mark_object (Lisp_Object arg) | |||
| 5381 | recursion there. */ | 5392 | recursion there. */ |
| 5382 | { | 5393 | { |
| 5383 | register struct Lisp_Vector *ptr = XVECTOR (obj); | 5394 | register struct Lisp_Vector *ptr = XVECTOR (obj); |
| 5384 | register EMACS_INT size = ptr->size; | 5395 | register EMACS_UINT size = ptr->size; |
| 5385 | register int i; | 5396 | register EMACS_UINT i; |
| 5386 | 5397 | ||
| 5387 | CHECK_LIVE (live_vector_p); | 5398 | CHECK_LIVE (live_vector_p); |
| 5388 | VECTOR_MARK (ptr); /* Else mark it */ | 5399 | VECTOR_MARK (ptr); /* Else mark it */ |