2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
26 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
27 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
28 * the full copyright text.
35 static char rcsid[] = "$XConsortium: UilSarComp.c /main/11 1995/07/14 09:36:46 drk $"
40 * (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
46 ** User Interface Language Compiler (UIL)
50 ** This module supports compound strings in UIL. It includes
51 ** the basic operations for creating, copying, and concatenating
66 #include <Mrm/MrmAppl.h>
71 #include <DXm/DXmHelpB.h>
85 ** DEFINE and MACRO DEFINITIONS
89 #define clear_class_mask (~(sym_m_private | sym_m_imported | sym_m_exported))
93 ** EXTERNAL VARIABLE DECLARATIONS
97 extern yystype yylval;
102 ** GLOBAL VARIABLE DECLARATIONS
110 ** OWN VARIABLE DECLARATIONS
118 ** FUNCTIONAL DESCRIPTION:
120 ** This function creates a null compound string.
122 ** FORMAL PARAMETERS:
140 ** a copy of the primitive string may be made
145 sym_value_entry_type *sem_create_cstr()
148 sym_value_entry_type *az_cstr_entry;
150 az_cstr_entry = (sym_value_entry_type *)
153 sym_k_value_entry_size + sizeof( char * ) );
155 az_cstr_entry->obj_header.b_flags = sym_m_builtin | sym_m_private;
156 az_cstr_entry->b_type = sym_k_compound_string_value;
157 az_cstr_entry->w_length = sizeof (char *);
158 az_cstr_entry->b_direction = NOSTRING_DIRECTION;
160 /* Fix for CN 16149 (DTS 10023) part 1 -- initialize charset info */
161 az_cstr_entry->b_charset = sym_k_error_charset;
162 az_cstr_entry->az_charset_value = NULL;
164 _sar_save_source_pos (&az_cstr_entry->header, &yylval);
166 return az_cstr_entry;
173 ** FUNCTIONAL DESCRIPTION:
175 ** This function creates a null wide_character string.
177 ** FORMAL PARAMETERS:
195 ** a copy of the primitive string may be made
200 sym_value_entry_type *sem_create_wchar_str()
203 sym_value_entry_type *az_wchar_str_entry;
205 az_wchar_str_entry = (sym_value_entry_type *)
208 sym_k_value_entry_size + sizeof( char * ) );
210 az_wchar_str_entry->obj_header.b_flags = sym_m_builtin | sym_m_private;
211 az_wchar_str_entry->b_type = sym_k_wchar_string_value;
212 az_wchar_str_entry->w_length = sizeof (char *);
213 az_wchar_str_entry->b_direction = NOSTRING_DIRECTION;
215 _sar_save_source_pos (&az_wchar_str_entry->header, &yylval);
217 return az_wchar_str_entry;
224 ** FUNCTIONAL DESCRIPTION:
226 ** This function appends a primitive or a localized string to a
229 ** FORMAL PARAMETERS:
231 ** az_cstr_entry compound string
232 ** az_str_entry primitive string or localized string
233 ** op2_temporary true if op2 is not needed after operation
249 ** a copy of the primitive string may be made
254 void sem_append_str_to_cstr(az_cstr_entry, az_str_entry, op2_temporary)
256 sym_value_entry_type *az_cstr_entry;
257 sym_value_entry_type *az_str_entry;
258 boolean op2_temporary;
261 sym_value_entry_type *last_str_entry;
262 sym_value_entry_type **ptr;
263 sym_value_entry_type *new_str_entry;
267 ** A couple of points:
268 ** 1) if op2_temporary = FALSE - we must make a copy
270 ** 2) if the last string of the compound string has the same attributes
271 ** as the string being appended, the strings are merged into 1
274 /* find the last string of the compound string */
276 ptr = &(az_cstr_entry->az_first_table_value);
277 last_str_entry = *ptr;
280 if (last_str_entry != NULL)
283 last_str_entry->az_next_table_value != NULL;
285 ptr = (sym_value_entry_type * *)
286 &(last_str_entry->az_next_table_value),
287 last_str_entry = *ptr);
289 if ((last_str_entry->b_charset == az_str_entry->b_charset)
291 ((last_str_entry->b_direction)== (az_str_entry->b_direction))
293 ((last_str_entry->b_aux_flags & sym_m_separate) == 0 ))
296 ptr = (sym_value_entry_type * *)
297 &(last_str_entry->az_next_table_value);
303 sem_cat_str_to_str( last_str_entry, TRUE,
304 az_str_entry, op2_temporary );
309 ** Append a new segment to the compound string
312 if( op2_temporary == FALSE )
314 unsigned short old_size;
316 /* must make a copy since user has access to string via name */
318 new_str_entry = (sym_value_entry_type *)
319 sem_allocate_node( sym_k_value_entry,
320 az_str_entry->header.w_node_size<<2 );
322 old_size = new_str_entry->header.w_node_size;
324 _sym_copy_entry( new_str_entry,
326 az_str_entry->header.w_node_size );
328 new_str_entry->header.w_node_size = old_size;
332 new_str_entry = az_str_entry;
336 /* link to the end of the compound string */
338 new_str_entry->b_aux_flags |= sym_m_table_entry;
339 new_str_entry->obj_header.b_flags = sym_m_private | sym_m_builtin;
340 new_str_entry->obj_header.az_name = NULL;
341 new_str_entry->az_next_table_value = NULL;
342 *ptr = new_str_entry;
347 ** FUNCTIONAL DESCRIPTION:
349 ** This function appends a compound string to a compound string.
351 ** FORMAL PARAMETERS:
353 ** az_cstr1_entry compound string
354 ** az_cstr2_entry compound string
355 ** op2_temporary true if op2 is not needed after operation
376 void sem_append_cstr_to_cstr(az_cstr1_entry, az_cstr2_entry, op2_temporary)
378 sym_value_entry_type *az_cstr1_entry;
379 sym_value_entry_type *az_cstr2_entry;
380 boolean op2_temporary;
383 sym_value_entry_type *last_str_entry;
384 sym_value_entry_type **ptr;
385 sym_value_entry_type *next_str_entry;
388 ** A couple of points:
389 ** 1) if op2_temporary = FALSE - we must make a copy of 2nd compound
391 ** 2) if the last string of 1st compound string has the same attributes
392 ** as the 1st string of the 2nd compound string being appended,
393 ** the strings are merged into 1
396 /* find the last string of the 1st compound string */
398 ptr = &(az_cstr1_entry->az_first_table_value);
399 last_str_entry = *ptr;
401 next_str_entry = az_cstr2_entry->az_first_table_value;
404 sem_free_node(( sym_entry_type *) az_cstr2_entry );
406 if (next_str_entry == NULL)
409 if (last_str_entry != NULL)
412 last_str_entry->az_next_table_value != NULL;
414 ptr = (sym_value_entry_type * *)
415 &(last_str_entry->az_next_table_value),
416 last_str_entry = *ptr);
418 if ((last_str_entry->b_charset == next_str_entry->b_charset)
420 ((last_str_entry->b_direction)== (next_str_entry->b_direction))
422 ((last_str_entry->b_aux_flags & sym_m_separate) == 0 ))
425 sem_cat_str_to_str( last_str_entry, TRUE,
426 next_str_entry, op2_temporary );
427 last_str_entry->b_aux_flags |= sym_m_table_entry;
428 *ptr = last_str_entry;
430 (sym_value_entry_type *) next_str_entry->az_next_table_value;
433 ptr = (sym_value_entry_type * *)
434 &(last_str_entry->az_next_table_value);
439 *ptr = next_str_entry;
444 next_str_entry != NULL;
445 next_str_entry = (sym_value_entry_type *)
446 next_str_entry->az_next_table_value )
448 sym_value_entry_type *new_str_entry;
449 unsigned short old_size;
451 new_str_entry = (sym_value_entry_type *)
452 sem_allocate_node( sym_k_value_entry,
453 next_str_entry->header.w_node_size<<2 );
455 old_size = new_str_entry->header.w_node_size;
457 _sym_copy_entry( new_str_entry,
459 next_str_entry->header.w_node_size );
461 new_str_entry->header.w_node_size = old_size;
462 new_str_entry->obj_header.b_flags = sym_m_private | sym_m_builtin;
463 new_str_entry->obj_header.az_name = NULL;
464 new_str_entry->b_aux_flags |= sym_m_table_entry;
466 /* link to the end of the compound string */
468 *ptr = new_str_entry;
469 ptr = (sym_value_entry_type * *)
470 &(new_str_entry->az_next_table_value);
479 ** FUNCTIONAL DESCRIPTION:
481 ** This function concatenates 2 primitive strings.
483 ** FORMAL PARAMETERS:
485 ** az_str1_entry primitive string
486 ** op1_temporary op1 is a temporary string
487 ** az_str2_entry primitive string
488 ** op2_temporary op2 is a temporary string
500 ** ptr to the result string
511 (az_str1_entry, op1_temporary, az_str2_entry, op2_temporary)
513 sym_value_entry_type *az_str1_entry;
514 boolean op1_temporary;
515 sym_value_entry_type *az_str2_entry;
516 boolean op2_temporary;
519 sym_value_entry_type *new_str_entry;
523 ** Can only append two simple strings if they have the same direction and
524 ** the first does not have the separate attribute.
526 _assert(((az_str1_entry->b_charset == az_str2_entry->b_charset)
528 ((az_str1_entry->b_direction) == (az_str2_entry->b_direction))
530 "strings with different attrs concatenated" );
532 l1 = az_str1_entry->w_length;
533 l2 = az_str2_entry->w_length;
535 /* extra 1 is for terminating null */
537 new_str_entry = (sym_value_entry_type *)
538 sem_allocate_node( sym_k_value_entry,
539 sym_k_value_entry_size );
540 new_str_entry->value.c_value = XtCalloc(1, l1 + l2 + 1);
543 new_str_entry->obj_header.b_flags = sym_m_builtin | sym_m_private;
545 _sar_move_source_info_2 (&new_str_entry->header, &az_str1_entry->header);
546 new_str_entry->b_charset = az_str1_entry->b_charset;
547 new_str_entry->b_direction = az_str1_entry->b_direction;
548 new_str_entry->b_aux_flags =
549 (az_str1_entry->b_aux_flags & sym_m_separate);
550 new_str_entry->b_type = sym_k_char_8_value;
551 new_str_entry->w_length = l1 + l2;
553 _move( new_str_entry->value.c_value,
554 az_str1_entry->value.c_value, l1 );
556 _move( &new_str_entry->value.c_value[ l1 ],
557 az_str2_entry->value.c_value,
561 ** if either of the operands is unnamed - free the node
566 _free_memory( az_str1_entry->value.c_value );
567 sem_free_node(( sym_entry_type *) az_str1_entry );
572 _free_memory( az_str2_entry->value.c_value );
573 sem_free_node(( sym_entry_type *) az_str2_entry );
576 return new_str_entry;
582 ** FUNCTIONAL DESCRIPTION:
584 ** This function takes the charset sets understood by the parser
585 ** and maps them to charsets understood by the symbol table and
588 ** FORMAL PARAMETERS:
590 ** charset_as_subclass sym_k_..._charset literal naming charset
602 ** sym_k...charset name for charset
611 int sem_map_subclass_to_charset(charset_as_subclass)
613 int charset_as_subclass;
616 switch (charset_as_subclass)
619 case lex_k_fontlist_default_tag:
620 case sym_k_fontlist_default_tag:
621 return sym_k_fontlist_default_tag;
622 case lex_k_default_charset:
623 return uil_sym_default_charset;
624 case lex_k_userdefined_charset:
625 return sym_k_userdefined_charset;
627 _assert (charset_as_subclass!=0, "charset code==0");
628 _assert (charset_as_subclass<=uil_max_charset, "unknown charset");
629 return charset_as_subclass;
636 ** FUNCTIONAL DESCRIPTION:
638 ** This function verifies the character set indicated by the user.
640 ** FORMAL PARAMETERS:
642 ** current_frame current stack frame
643 ** charset_frame stack frame of CHARSET token
664 void sar_charset_verify ( charset_frame )
666 yystype *charset_frame;
669 key_keytable_entry_type *az_keyword_entry;
671 _assert(((charset_frame->b_tag == sar_k_token_frame) ||
672 (charset_frame->b_tag == sar_k_value_frame)),
673 "token or value frame missing" );
675 az_keyword_entry = charset_frame->value.az_keyword_entry;
680 ** Store the current charset so it can be used by LEX to processes a
681 ** string literal (if the CHARSET_NAME is used to prefix a string literal)
683 Uil_lex_l_literal_charset = az_keyword_entry->b_subclass;
689 ** FUNCTIONAL DESCRIPTION:
691 ** This function converts a random NAME into a CHARSET_NAME
692 ** with the default charset.
694 ** FORMAL PARAMETERS:
696 ** name_frame current stack frame containing NAME
704 ** modified name_frame
712 ** name_frame converted from NAME to CHARSET_NAME
717 void sar_make_fallback_charset(name_frame)
720 sym_name_entry_type *symbol_entry;
721 static key_keytable_entry_type *az_keyword_entry = NULL;
723 _assert(((name_frame->b_tag == sar_k_token_frame) ||
724 (name_frame->b_tag == sar_k_value_frame)),
725 "token or value frame missing" );
727 /* Get symbol and check if already used as charset. */
728 symbol_entry = (sym_name_entry_type *)name_frame->value.az_symbol_entry;
730 if ((symbol_entry->b_flags & sym_m_charset) == 0)
732 symbol_entry->b_flags |= sym_m_charset;
733 diag_issue_diagnostic(d_default_charset,
734 _sar_source_pos2(symbol_entry),
735 symbol_entry->c_text,
739 /* Get the default charset keyword entry. */
740 if (az_keyword_entry == NULL)
741 az_keyword_entry = key_find_keyword(strlen(DEFAULT_TAG), DEFAULT_TAG);
743 _assert((az_keyword_entry !=NULL), "default charset keyword missing");
745 /* Change NAME to CHARSET_NAME */
746 name_frame->value.az_keyword_entry = az_keyword_entry;
747 name_frame ->b_type = az_keyword_entry->b_token;
750 ** Store the current charset so it can be used by LEX to processes a
751 ** string literal (if the NAME is used to prefix a string literal)
753 Uil_lex_l_literal_charset = az_keyword_entry->b_subclass;
759 ** FUNCTIONAL DESCRIPTION:
761 ** This function checks the attributes of CHARACTER_SET function.
763 ** FORMAL PARAMETERS:
765 ** target_frame pointer to resultant token stack frame
766 ** value_frame pointer to frame holding keyword and value
767 ** prior_value_frame pointer to previous properties
783 ** attribute information is stuffed in target frame
788 void sar_chk_charset_attr( target_frame, value_frame, prior_value_frame )
790 yystype *target_frame;
791 yystype *value_frame;
792 yystype *prior_value_frame;
796 ** Set up not specified values in the target frame.
797 ** b_type will hold the sixteen_bit property
800 switch (prior_value_frame->b_tag)
802 case sar_k_null_frame:
807 target_frame->b_tag = sar_k_token_frame;
808 target_frame->b_direction = NOSTRING_DIRECTION;
809 target_frame->b_charset = uil_sym_default_charset;
810 target_frame->b_type = 0;
813 case sar_k_token_frame:
814 case sar_k_value_frame:
816 ** prior values - transfer them
819 target_frame->b_tag = sar_k_token_frame;
820 target_frame->b_direction = prior_value_frame->b_direction;
821 target_frame->b_charset = prior_value_frame->b_charset;
822 target_frame->b_type = prior_value_frame->b_type;
825 _assert( FALSE, "prior value frame missing from stack" );
829 ** Case on the keyword for the attribute given
832 switch (value_frame->b_type)
836 sym_value_entry_type *value_entry;
839 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
842 ** If the value is a boolean, then just set the corresponding mask
845 if (value_entry->b_type == sym_k_bool_value)
846 if (value_entry->value.l_integer == TRUE)
847 target_frame->b_direction = XmSTRING_DIRECTION_R_TO_L;
849 target_frame->b_direction = XmSTRING_DIRECTION_L_TO_R;
856 sym_value_entry_type *value_entry;
859 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
862 ** If the value is a boolean, then just set the corresponding mask
865 if (value_entry->b_type == sym_k_bool_value)
866 if (value_entry->value.l_integer == TRUE)
867 target_frame->b_type |= sym_m_sixteen_bit;
869 target_frame->b_type &= ~sym_m_sixteen_bit;
875 _assert( FALSE, "keyword missing from stack" );
883 ** FUNCTIONAL DESCRIPTION:
885 ** This function makes a CHARACTER_SET and sets the properties
888 ** FORMAL PARAMETERS:
890 ** target_frame pointer to resultant token stack frame
891 ** value_frame pointer to string value
892 ** attr_frame pointer to strings attributes
893 ** keyword_frame frame to use as locator for result
914 void sar_make_charset (target_frame, value_frame, attr_frame, keyword_frame)
916 yystype *target_frame;
917 yystype *value_frame;
919 yystype *keyword_frame;
921 sym_value_entry_type *value_entry;
923 _assert( value_frame->b_tag == sar_k_value_frame,
924 "value frame missing from stack" );
928 ** Set the character set information into the symbol table
929 ** entry for the char_8 string that indentifies the name of this
930 ** userdefined character set.
933 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
934 value_entry->b_charset = sym_k_userdefined_charset;
936 /* BEGIN HaL fix CR 5547 */
937 sem_evaluate_value (value_entry);
938 if (value_entry->b_type != sym_k_char_8_value)
939 diag_issue_diagnostic
941 _sar_source_pos2( value_entry ),
942 diag_value_text( value_entry->b_type ),
943 "null-terminated string");
944 /* END HaL fix CR 5547 */
948 ** If the attr_frame is not null, it must be a value frame with contains
949 ** a pointer to the attributes frame for this userdefined charset.
951 if (attr_frame->b_tag == sar_k_token_frame)
954 ** Set the attributes of the string, as specified by the options
955 ** to the CHARACTER_SET function, without disturbing any
958 value_entry->b_direction = attr_frame->b_direction;
959 value_entry->b_aux_flags = (attr_frame->b_type & sym_m_sixteen_bit);
964 ** initialize the target frame
967 _sar_move_source_info( target_frame, keyword_frame );
969 target_frame->b_tag = sar_k_value_frame;
970 target_frame->b_type = sym_k_char_8_value;
971 target_frame->b_flags = sym_m_private;
972 target_frame->value.az_symbol_entry = value_frame->value.az_symbol_entry;
976 ** Store the current charset so it can be used by LEX to processes a
977 ** string literal (if the CHARACTER_SET function is used to prefix a
980 Uil_lex_l_literal_charset = lex_k_userdefined_charset;
981 Uil_lex_az_literal_charset = value_entry;