comparison src/regex.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 fdefd0186b75
children a5954632b187
comparison
equal deleted inserted replaced
770:336a418893b5 771:943eaba38521
3 (Implements POSIX draft P10003.2/D11.2, except for 3 (Implements POSIX draft P10003.2/D11.2, except for
4 internationalization features.) 4 internationalization features.)
5 5
6 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc. 6 Copyright (C) 1993, 1994, 1995 Free Software Foundation, Inc.
7 Copyright (C) 1995 Sun Microsystems, Inc. 7 Copyright (C) 1995 Sun Microsystems, Inc.
8 Copyright (C) 1995 Ben Wing. 8 Copyright (C) 1995, 2001, 2002 Ben Wing.
9 9
10 This program is free software; you can redistribute it and/or modify 10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by 11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option) 12 the Free Software Foundation; either version 2, or (at your option)
13 any later version. 13 any later version.
69 # include <libintl.h> 69 # include <libintl.h>
70 #else 70 #else
71 # define gettext(msgid) (msgid) 71 # define gettext(msgid) (msgid)
72 #endif 72 #endif
73 73
74 /* XEmacs addition */
75 #ifdef REL_ALLOC
76 #define REGEX_REL_ALLOC /* may be undefined below */
77 #endif
78
74 /* XEmacs: define this to add in a speedup for patterns anchored at 79 /* XEmacs: define this to add in a speedup for patterns anchored at
75 the beginning of a line. Keep the ifdefs so that it's easier to 80 the beginning of a line. Keep the ifdefs so that it's easier to
76 tell where/why this code has diverged from v19. */ 81 tell where/why this code has diverged from v19. */
77 #define REGEX_BEGLINE_CHECK 82 #define REGEX_BEGLINE_CHECK
78 83
79 /* XEmacs: the current mmap-based ralloc handles small blocks very 84 /* XEmacs: the current mmap-based ralloc handles small blocks very
80 poorly, so we disable it here. */ 85 poorly, so we disable it here. */
81 86
82 #if (defined (REL_ALLOC) && defined (HAVE_MMAP)) || defined(DOUG_LEA_MALLOC) 87 #if defined (HAVE_MMAP) || defined (DOUG_LEA_MALLOC)
83 # undef REL_ALLOC 88 # undef REGEX_REL_ALLOC
84 #endif 89 #endif
85 90
86 /* The `emacs' switch turns on certain matching commands 91 /* The `emacs' switch turns on certain matching commands
87 that make sense only in Emacs. */ 92 that make sense only in Emacs. */
88 #ifdef emacs 93 #ifdef emacs
121 #else /* not emacs */ 126 #else /* not emacs */
122 127
123 /* If we are not linking with Emacs proper, 128 /* If we are not linking with Emacs proper,
124 we can't use the relocating allocator 129 we can't use the relocating allocator
125 even if config.h says that we can. */ 130 even if config.h says that we can. */
126 #undef REL_ALLOC 131 #undef REGEX_REL_ALLOC
127 132
128 /* defined in lisp.h */ 133 /* defined in lisp.h */
129 #ifdef REGEX_MALLOC 134 #ifdef REGEX_MALLOC
130 #ifndef DECLARE_NOTHING 135 #ifndef DECLARE_NOTHING
131 #define DECLARE_NOTHING struct nosuchstruct 136 #define DECLARE_NOTHING struct nosuchstruct
298 #ifndef alloca 303 #ifndef alloca
299 304
300 /* Make alloca work the best possible way. */ 305 /* Make alloca work the best possible way. */
301 #ifdef __GNUC__ 306 #ifdef __GNUC__
302 #define alloca __builtin_alloca 307 #define alloca __builtin_alloca
308 #elif defined (__DECC) /* XEmacs: added next 3 lines, similar to config.h.in */
309 #include <alloca.h>
310 #pragma intrinsic(alloca)
303 #else /* not __GNUC__ */ 311 #else /* not __GNUC__ */
304 #if HAVE_ALLOCA_H 312 #if HAVE_ALLOCA_H
305 #include <alloca.h> 313 #include <alloca.h>
306 #else /* not __GNUC__ or HAVE_ALLOCA_H */ 314 #else /* not __GNUC__ or HAVE_ALLOCA_H */
307 #ifndef _AIX /* Already did AIX, up at the top. */ 315 #ifndef _AIX /* Already did AIX, up at the top. */
325 333
326 #endif /* REGEX_MALLOC */ 334 #endif /* REGEX_MALLOC */
327 335
328 /* Define how to allocate the failure stack. */ 336 /* Define how to allocate the failure stack. */
329 337
330 #ifdef REL_ALLOC 338 #ifdef REGEX_REL_ALLOC
331 #define REGEX_ALLOCATE_STACK(size) \ 339 #define REGEX_ALLOCATE_STACK(size) \
332 r_alloc ((char **) &failure_stack_ptr, (size)) 340 r_alloc ((char **) &failure_stack_ptr, (size))
333 #define REGEX_REALLOCATE_STACK(source, osize, nsize) \ 341 #define REGEX_REALLOCATE_STACK(source, osize, nsize) \
334 r_re_alloc ((char **) &failure_stack_ptr, (nsize)) 342 r_re_alloc ((char **) &failure_stack_ptr, (nsize))
335 #define REGEX_FREE_STACK(ptr) \ 343 #define REGEX_FREE_STACK(ptr) \
336 r_alloc_free ((void **) &failure_stack_ptr) 344 r_alloc_free ((void **) &failure_stack_ptr)
337 345
338 #else /* not REL_ALLOC */ 346 #else /* not REGEX_REL_ALLOC */
339 347
340 #ifdef REGEX_MALLOC 348 #ifdef REGEX_MALLOC
341 349
342 #define REGEX_ALLOCATE_STACK malloc 350 #define REGEX_ALLOCATE_STACK malloc
343 #define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize) 351 #define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
351 REGEX_REALLOCATE (source, osize, nsize) 359 REGEX_REALLOCATE (source, osize, nsize)
352 /* No need to explicitly free anything. */ 360 /* No need to explicitly free anything. */
353 #define REGEX_FREE_STACK(arg) 361 #define REGEX_FREE_STACK(arg)
354 362
355 #endif /* REGEX_MALLOC */ 363 #endif /* REGEX_MALLOC */
356 #endif /* REL_ALLOC */ 364 #endif /* REGEX_REL_ALLOC */
357 365
358 366
359 /* True if `size1' is non-NULL and PTR is pointing anywhere inside 367 /* True if `size1' is non-NULL and PTR is pointing anywhere inside
360 `string1' or just past its end. This works if PTR is NULL, which is 368 `string1' or just past its end. This works if PTR is NULL, which is
361 a good thing. */ 369 a good thing. */
1022 } 1030 }
1023 } 1031 }
1024 1032
1025 #else /* not DEBUG */ 1033 #else /* not DEBUG */
1026 1034
1035 #ifndef emacs
1027 #undef assert 1036 #undef assert
1028 #define assert(e) 1037 #define assert(e) ((void) (1))
1038 #endif
1029 1039
1030 #define DEBUG_STATEMENT(e) 1040 #define DEBUG_STATEMENT(e)
1031 #define DEBUG_PRINT1(x) 1041 #define DEBUG_PRINT1(x)
1032 #define DEBUG_PRINT2(x1, x2) 1042 #define DEBUG_PRINT2(x1, x2)
1033 #define DEBUG_PRINT3(x1, x2, x3) 1043 #define DEBUG_PRINT3(x1, x2, x3)
1100 searching and matching functions should not call alloca. On some 1110 searching and matching functions should not call alloca. On some
1101 systems, alloca is implemented in terms of malloc, and if we're 1111 systems, alloca is implemented in terms of malloc, and if we're
1102 using the relocating allocator routines, then malloc could cause a 1112 using the relocating allocator routines, then malloc could cause a
1103 relocation, which might (if the strings being searched are in the 1113 relocation, which might (if the strings being searched are in the
1104 ralloc heap) shift the data out from underneath the regexp 1114 ralloc heap) shift the data out from underneath the regexp
1105 routines. 1115 routines. [To clarify: The purpose of rel-alloc is to allow data to
1106 1116 be moved in memory from one place to another so that all data
1107 Here's another reason to avoid allocation: Emacs 1117 blocks can be consolidated together and excess memory released back
1108 processes input from X in a signal handler; processing X input may 1118 to the operating system. This requires that all the blocks that
1109 call malloc; if input arrives while a matching routine is calling 1119 are managed by rel-alloc go at the very end of the program's heap,
1110 malloc, then we're scrod. But Emacs can't just block input while 1120 after all regularly malloc()ed data. malloc(), however, is used to
1111 calling matching routines; then we don't notice interrupts when 1121 owning the end of the heap, so that when more memory is needed, it
1112 they come in. So, Emacs blocks input around all regexp calls 1122 just expands the heap using sbrk(). This is reconciled by using a
1113 except the matching calls, which it leaves unprotected, in the 1123 malloc() (such as malloc.c, gmalloc.c, or recent versions of
1114 faith that they will not malloc. */ 1124 malloc() in libc) where the sbrk() call can be replaced with a
1125 user-specified call -- in this case, to rel-alloc's r_alloc_sbrk()
1126 routine. This routine calls the real sbrk(), but then shifts all
1127 the rel-alloc-managed blocks forward to the end of the heap again,
1128 so that malloc() gets the memory it needs in the location it needs
1129 it at. The regex routines may well have pointers to buffer data as
1130 their arguments, and buffers are managed by rel-alloc if rel-alloc
1131 has been enabled, so calling malloc() may potentially screw things
1132 up badly if it runs out of space and asks for more from the OS.]
1133
1134 [[Here's another reason to avoid allocation: Emacs processes input
1135 from X in a signal handler; processing X input may call malloc; if
1136 input arrives while a matching routine is calling malloc, then
1137 we're scrod. But Emacs can't just block input while calling
1138 matching routines; then we don't notice interrupts when they come
1139 in. So, Emacs blocks input around all regexp calls except the
1140 matching calls, which it leaves unprotected, in the faith that they
1141 will not malloc.]] This previous paragraph is irrelevant.
1142
1143 XEmacs: We *do not* do anything so stupid as process input from
1144 within a signal handler. However, the regexp routines may get
1145 called reentrantly as a result of QUIT processing (e.g. under
1146 Windows: re_match -> QUIT -> quit_p -> drain events -> process
1147 WM_INITMENU -> call filter -> re_match), so we cannot have any
1148 global variables (unless we do lots of trickiness including some
1149 unwind-protects, which isn't worth it at this point). The first
1150 paragraph appears utterly garbled to me -- shouldn't *ANY* use of
1151 rel-alloc to different potentially cause buffer data to be
1152 relocated? I must be missing something, though -- perhaps the
1153 writer above is assuming that the failure stack(s) will always be
1154 allocated after the buffer data, and thus reallocating them with
1155 rel-alloc won't move buffer data. --ben */
1115 1156
1116 /* Normally, this is fine. */ 1157 /* Normally, this is fine. */
1117 #define MATCH_MAY_ALLOCATE 1158 #define MATCH_MAY_ALLOCATE
1118 1159
1119 /* When using GNU C, we are not REALLY using the C alloca, no matter 1160 /* When using GNU C, we are not REALLY using the C alloca, no matter
1125 /* The match routines may not allocate if (1) they would do it with malloc 1166 /* The match routines may not allocate if (1) they would do it with malloc
1126 and (2) it's not safe for them to use malloc. 1167 and (2) it's not safe for them to use malloc.
1127 Note that if REL_ALLOC is defined, matching would not use malloc for the 1168 Note that if REL_ALLOC is defined, matching would not use malloc for the
1128 failure stack, but we would still use it for the register vectors; 1169 failure stack, but we would still use it for the register vectors;
1129 so REL_ALLOC should not affect this. */ 1170 so REL_ALLOC should not affect this. */
1130 #if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (emacs) 1171
1172 /* XEmacs change emacs -> REL_ALLOC */
1173 #if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && defined (REL_ALLOC)
1131 #undef MATCH_MAY_ALLOCATE 1174 #undef MATCH_MAY_ALLOCATE
1175 #endif
1176
1177 /* #### need better check */
1178
1179 #if !defined (MATCH_MAY_ALLOCATE) && defined (emacs) && defined (HAVE_MS_WINDOWS)
1180 #error regex must be handle reentrancy; MATCH_MAY_ALLOCATE must be defined
1132 #endif 1181 #endif
1133 1182
1134 1183
1135 /* Failure stack declarations and macros; both re_compile_fastmap and 1184 /* Failure stack declarations and macros; both re_compile_fastmap and
1136 re_match_2 use a failure stack. These have to be macros because of 1185 re_match_2 use a failure stack. These have to be macros because of
1275 num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be 1324 num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
1276 declared. 1325 declared.
1277 1326
1278 Does `return FAILURE_CODE' if runs out of memory. */ 1327 Does `return FAILURE_CODE' if runs out of memory. */
1279 1328
1280 #if !defined (REGEX_MALLOC) && !defined (REL_ALLOC) 1329 #if !defined (REGEX_MALLOC) && !defined (REGEX_REL_ALLOC)
1281 #define DECLARE_DESTINATION char *destination 1330 #define DECLARE_DESTINATION char *destination
1282 #else 1331 #else
1283 #define DECLARE_DESTINATION DECLARE_NOTHING 1332 #define DECLARE_DESTINATION DECLARE_NOTHING
1284 #endif 1333 #endif
1285 1334
3525 unsigned char *pattern = bufp->buffer; 3574 unsigned char *pattern = bufp->buffer;
3526 long size = bufp->used; 3575 long size = bufp->used;
3527 unsigned char *p = pattern; 3576 unsigned char *p = pattern;
3528 REGISTER unsigned char *pend = pattern + size; 3577 REGISTER unsigned char *pend = pattern + size;
3529 3578
3530 #ifdef REL_ALLOC 3579 #ifdef REGEX_REL_ALLOC
3531 /* This holds the pointer to the failure stack, when 3580 /* This holds the pointer to the failure stack, when
3532 it is allocated relocatably. */ 3581 it is allocated relocatably. */
3533 fail_stack_elt_t *failure_stack_ptr; 3582 fail_stack_elt_t *failure_stack_ptr;
3534 #endif 3583 #endif
3535 3584
3764 (regex_emacs_buffer->mirror_syntax_table), j) == 3813 (regex_emacs_buffer->mirror_syntax_table), j) ==
3765 (enum syntaxcode) k) 3814 (enum syntaxcode) k)
3766 fastmap[j] = 1; 3815 fastmap[j] = 1;
3767 for (j = 0x80; j < 0xA0; j++) 3816 for (j = 0x80; j < 0xA0; j++)
3768 { 3817 {
3769 if (LEADING_BYTE_PREFIX_P(j)) 3818 if (LEADING_BYTE_PREFIX_P((unsigned char) j))
3770 /* too complicated to calculate this right */ 3819 /* too complicated to calculate this right */
3771 fastmap[j] = 1; 3820 fastmap[j] = 1;
3772 else 3821 else
3773 { 3822 {
3774 int multi_p; 3823 int multi_p;
3807 (regex_emacs_buffer->mirror_syntax_table), j) != 3856 (regex_emacs_buffer->mirror_syntax_table), j) !=
3808 (enum syntaxcode) k) 3857 (enum syntaxcode) k)
3809 fastmap[j] = 1; 3858 fastmap[j] = 1;
3810 for (j = 0x80; j < 0xA0; j++) 3859 for (j = 0x80; j < 0xA0; j++)
3811 { 3860 {
3812 if (LEADING_BYTE_PREFIX_P(j)) 3861 if (LEADING_BYTE_PREFIX_P((unsigned char) j))
3813 /* too complicated to calculate this right */ 3862 /* too complicated to calculate this right */
3814 fastmap[j] = 1; 3863 fastmap[j] = 1;
3815 else 3864 else
3816 { 3865 {
3817 int multi_p; 3866 int multi_p;
4431 4480
4432 alloca (0); 4481 alloca (0);
4433 return result; 4482 return result;
4434 } 4483 }
4435 4484
4485 #if defined (ERROR_CHECK_CHARBPOS) && defined (emacs)
4486 int in_re_match_2_internal;
4487
4488 /* #### I am seeing an error (once) where regex_match_object gets set
4489 to a string while matching on a buffer. The only way this seems
4490 possible is recursive invocation of re_match_2_internal(). */
4491 static Lisp_Object
4492 restore_in_re_match_2_internal (Lisp_Object val)
4493 {
4494 in_re_match_2_internal = 0;
4495 return Qnil;
4496 }
4497
4498 #define RESTORE_IN_MATCH_FLAG unbind_to (speccount)
4499
4500 #else
4501
4502 #define RESTORE_IN_MATCH_FLAG do {} while (0)
4503
4504 #endif /* defined (ERROR_CHECK_CHARBPOS) && defined (emacs) */
4505
4506
4436 /* This is a separate function so that we can force an alloca cleanup 4507 /* This is a separate function so that we can force an alloca cleanup
4437 afterwards. */ 4508 afterwards. */
4438 static int 4509 static int
4439 re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1, 4510 re_match_2_internal (struct re_pattern_buffer *bufp, re_char *string1,
4440 int size1, re_char *string2, int size2, int pos, 4511 int size1, re_char *string2, int size2, int pos,
4481 #ifdef DEBUG 4552 #ifdef DEBUG
4482 static int failure_id; 4553 static int failure_id;
4483 int nfailure_points_pushed = 0, nfailure_points_popped = 0; 4554 int nfailure_points_pushed = 0, nfailure_points_popped = 0;
4484 #endif 4555 #endif
4485 4556
4486 #ifdef REL_ALLOC 4557 #ifdef REGEX_REL_ALLOC
4487 /* This holds the pointer to the failure stack, when 4558 /* This holds the pointer to the failure stack, when
4488 it is allocated relocatably. */ 4559 it is allocated relocatably. */
4489 fail_stack_elt_t *failure_stack_ptr; 4560 fail_stack_elt_t *failure_stack_ptr;
4490 #endif 4561 #endif
4491 4562
4565 as the best previous match. */ 4636 as the best previous match. */
4566 re_bool same_str_p; 4637 re_bool same_str_p;
4567 4638
4568 /* 1 if this match is the best seen so far. */ 4639 /* 1 if this match is the best seen so far. */
4569 re_bool best_match_p; 4640 re_bool best_match_p;
4641
4642 #if defined (ERROR_CHECK_CHARBPOS) && defined (emacs)
4643 int speccount = specpdl_depth ();
4644
4645 #if 0
4646 /* we've hopefully fixed the reentrancy problem. */
4647 assert (!in_re_match_2_internal);
4648 #endif
4649 in_re_match_2_internal = 1;
4650 record_unwind_protect (restore_in_re_match_2_internal, Qnil);
4651 #endif /* defined (ERROR_CHECK_CHARBPOS) && defined (emacs) */
4570 4652
4571 DEBUG_PRINT1 ("\n\nEntering re_match_2.\n"); 4653 DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
4572 4654
4573 INIT_FAIL_STACK (); 4655 INIT_FAIL_STACK ();
4574 4656
4592 4674
4593 if (!(regstart && regend && old_regstart && old_regend && reg_info 4675 if (!(regstart && regend && old_regstart && old_regend && reg_info
4594 && best_regstart && best_regend && reg_dummy && reg_info_dummy)) 4676 && best_regstart && best_regend && reg_dummy && reg_info_dummy))
4595 { 4677 {
4596 FREE_VARIABLES (); 4678 FREE_VARIABLES ();
4679 RESTORE_IN_MATCH_FLAG;
4597 return -2; 4680 return -2;
4598 } 4681 }
4599 } 4682 }
4600 else 4683 else
4601 { 4684 {
4609 4692
4610 /* The starting position is bogus. */ 4693 /* The starting position is bogus. */
4611 if (pos < 0 || pos > size1 + size2) 4694 if (pos < 0 || pos > size1 + size2)
4612 { 4695 {
4613 FREE_VARIABLES (); 4696 FREE_VARIABLES ();
4697 RESTORE_IN_MATCH_FLAG;
4614 return -1; 4698 return -1;
4615 } 4699 }
4616 4700
4617 /* Initialize subexpression text positions to -1 to mark ones that no 4701 /* Initialize subexpression text positions to -1 to mark ones that no
4618 start_memory/stop_memory has been seen for. Also initialize the 4702 start_memory/stop_memory has been seen for. Also initialize the
4766 regs->start = TALLOC (regs->num_regs, regoff_t); 4850 regs->start = TALLOC (regs->num_regs, regoff_t);
4767 regs->end = TALLOC (regs->num_regs, regoff_t); 4851 regs->end = TALLOC (regs->num_regs, regoff_t);
4768 if (regs->start == NULL || regs->end == NULL) 4852 if (regs->start == NULL || regs->end == NULL)
4769 { 4853 {
4770 FREE_VARIABLES (); 4854 FREE_VARIABLES ();
4855 RESTORE_IN_MATCH_FLAG;
4771 return -2; 4856 return -2;
4772 } 4857 }
4773 bufp->regs_allocated = REGS_REALLOCATE; 4858 bufp->regs_allocated = REGS_REALLOCATE;
4774 } 4859 }
4775 else if (bufp->regs_allocated == REGS_REALLOCATE) 4860 else if (bufp->regs_allocated == REGS_REALLOCATE)
4782 RETALLOC (regs->start, regs->num_regs, regoff_t); 4867 RETALLOC (regs->start, regs->num_regs, regoff_t);
4783 RETALLOC (regs->end, regs->num_regs, regoff_t); 4868 RETALLOC (regs->end, regs->num_regs, regoff_t);
4784 if (regs->start == NULL || regs->end == NULL) 4869 if (regs->start == NULL || regs->end == NULL)
4785 { 4870 {
4786 FREE_VARIABLES (); 4871 FREE_VARIABLES ();
4872 RESTORE_IN_MATCH_FLAG;
4787 return -2; 4873 return -2;
4788 } 4874 }
4789 } 4875 }
4790 } 4876 }
4791 else 4877 else
4843 : string2 - size1); 4929 : string2 - size1);
4844 4930
4845 DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt); 4931 DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
4846 4932
4847 FREE_VARIABLES (); 4933 FREE_VARIABLES ();
4934 RESTORE_IN_MATCH_FLAG;
4848 return mcnt; 4935 return mcnt;
4849 } 4936 }
4850 4937
4851 /* Otherwise match next pattern command. */ 4938 /* Otherwise match next pattern command. */
4852 switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++)) 4939 switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
5945 if (best_regs_set) 6032 if (best_regs_set)
5946 goto restore_best_regs; 6033 goto restore_best_regs;
5947 6034
5948 FREE_VARIABLES (); 6035 FREE_VARIABLES ();
5949 6036
6037 RESTORE_IN_MATCH_FLAG;
5950 return -1; /* Failure to match. */ 6038 return -1; /* Failure to match. */
5951 } /* re_match_2 */ 6039 } /* re_match_2 */
5952 6040
5953 /* Subroutine definitions for re_match_2. */ 6041 /* Subroutine definitions for re_match_2. */
5954 6042