Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / osf / uil / UilSarComp.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
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)
10  * any later version.
11  *
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
16  * details.
17  *
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
22  */
23 /* 
24  *  @OSF_COPYRIGHT@
25  *  COPYRIGHT NOTICE
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.
29 */ 
30 /* 
31  * HISTORY
32 */ 
33 #ifdef REV_INFO
34 #ifndef lint
35 static char rcsid[] = "$XConsortium: UilSarComp.c /main/11 1995/07/14 09:36:46 drk $"
36 #endif
37 #endif
38
39 /*
40 *  (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
41
42 /*
43 **++
44 **  FACILITY:
45 **
46 **      User Interface Language Compiler (UIL)
47 **
48 **  ABSTRACT:
49 **
50 **      This module supports compound strings in UIL.  It includes
51 **      the basic operations for creating, copying, and concatenating
52 **      strings.
53 **
54 **--
55 **/
56
57
58 /*
59 **
60 **  INCLUDE FILES
61 **
62 **/
63
64
65
66 #include <Mrm/MrmAppl.h>
67
68
69
70 #ifdef DXM_V11
71 #include <DXm/DXmHelpB.h>
72 #endif
73
74 #include "UilDefI.h"
75
76 /*
77 **
78 **  TABLE OF CONTENTS
79 **
80 **/
81
82
83 /*
84 **
85 **  DEFINE and MACRO DEFINITIONS
86 **
87 **/
88
89 #define clear_class_mask (~(sym_m_private | sym_m_imported | sym_m_exported))
90
91 /*
92 **
93 **  EXTERNAL VARIABLE DECLARATIONS
94 **
95 **/
96
97 extern yystype          yylval;
98
99
100 /*
101 **
102 **  GLOBAL VARIABLE DECLARATIONS
103 **
104 **/
105
106
107
108 /*
109 **
110 **  OWN VARIABLE DECLARATIONS
111 **
112 **/
113
114
115 \f
116 /*
117 **++
118 **  FUNCTIONAL DESCRIPTION:
119 **
120 **      This function creates a null compound string.
121 **
122 **  FORMAL PARAMETERS:
123 **
124 **      none
125 **
126 **  IMPLICIT INPUTS:
127 **
128 **      none
129 **
130 **  IMPLICIT OUTPUTS:
131 **
132 **      none
133 **
134 **  FUNCTION VALUE:
135 **
136 **      none
137 **
138 **  SIDE EFFECTS:
139 **
140 **      a copy of the primitive string may be made
141 **
142 **--
143 **/
144
145 sym_value_entry_type    *sem_create_cstr()
146
147 {
148     sym_value_entry_type    *az_cstr_entry;
149
150     az_cstr_entry = (sym_value_entry_type *)
151                 sem_allocate_node
152                         ( sym_k_value_entry,
153                           sym_k_value_entry_size + sizeof( char * ) );
154
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;
159
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;
163
164     _sar_save_source_pos (&az_cstr_entry->header, &yylval);
165
166     return az_cstr_entry;
167
168 }
169
170 \f
171 /*
172 **++
173 **  FUNCTIONAL DESCRIPTION:
174 **
175 **      This function creates a null wide_character string.
176 **
177 **  FORMAL PARAMETERS:
178 **
179 **      none
180 **
181 **  IMPLICIT INPUTS:
182 **
183 **      none
184 **
185 **  IMPLICIT OUTPUTS:
186 **
187 **      none
188 **
189 **  FUNCTION VALUE:
190 **
191 **      none
192 **
193 **  SIDE EFFECTS:
194 **
195 **      a copy of the primitive string may be made
196 **
197 **--
198 **/
199
200 sym_value_entry_type    *sem_create_wchar_str()
201
202 {
203     sym_value_entry_type    *az_wchar_str_entry;
204
205     az_wchar_str_entry = (sym_value_entry_type *)
206                 sem_allocate_node
207                         ( sym_k_value_entry,
208                           sym_k_value_entry_size + sizeof( char * ) );
209
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;
214
215     _sar_save_source_pos (&az_wchar_str_entry->header, &yylval);
216
217     return az_wchar_str_entry;
218
219 }
220
221 \f
222 /*
223 **++
224 **  FUNCTIONAL DESCRIPTION:
225 **
226 **      This function appends a primitive or a localized string to a
227 **      compound string.
228 **
229 **  FORMAL PARAMETERS:
230 **
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
234 **
235 **  IMPLICIT INPUTS:
236 **
237 **      none
238 **
239 **  IMPLICIT OUTPUTS:
240 **
241 **      none
242 **
243 **  FUNCTION VALUE:
244 **
245 **      none
246 **
247 **  SIDE EFFECTS:
248 **
249 **      a copy of the primitive string may be made
250 **
251 **--
252 **/
253
254 void    sem_append_str_to_cstr(az_cstr_entry, az_str_entry, op2_temporary)
255
256 sym_value_entry_type    *az_cstr_entry;
257 sym_value_entry_type    *az_str_entry;
258 boolean                 op2_temporary;
259
260 {
261     sym_value_entry_type        *last_str_entry;
262     sym_value_entry_type        **ptr;
263     sym_value_entry_type        *new_str_entry;
264     boolean                     merge;
265
266     /*
267     **  A couple of points:
268     **  1) if op2_temporary = FALSE - we must make a copy
269     **     of it 
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
272     */
273
274     /* find the last string of the compound string */
275
276     ptr = &(az_cstr_entry->az_first_table_value);
277     last_str_entry = *ptr;
278     merge = FALSE;
279
280     if (last_str_entry != NULL)
281     {
282         for (  ;
283              last_str_entry->az_next_table_value != NULL;  
284
285              ptr = (sym_value_entry_type * *) 
286                  &(last_str_entry->az_next_table_value),
287              last_str_entry = *ptr);
288
289         if ((last_str_entry->b_charset == az_str_entry->b_charset)
290             &&
291             ((last_str_entry->b_direction)== (az_str_entry->b_direction))
292             &&
293             ((last_str_entry->b_aux_flags & sym_m_separate) == 0 ))
294             merge = TRUE;
295         else
296             ptr = (sym_value_entry_type * *)
297                 &(last_str_entry->az_next_table_value);
298     }
299
300     if (merge)
301     {
302         new_str_entry = 
303             sem_cat_str_to_str( last_str_entry, TRUE, 
304                                 az_str_entry, op2_temporary );
305     }
306     else
307     {
308         /*
309         **  Append a new segment to the compound string
310         */
311
312         if( op2_temporary == FALSE )
313         {
314             unsigned short      old_size;
315
316             /* must make a copy since user has access to string via name */
317             
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 );
321
322             old_size = new_str_entry->header.w_node_size;
323
324             _sym_copy_entry( new_str_entry, 
325                    az_str_entry,
326                    az_str_entry->header.w_node_size );
327
328             new_str_entry->header.w_node_size = old_size;
329
330         }
331         else
332             new_str_entry = az_str_entry;
333
334     }
335
336     /* link to the end of the compound string */
337
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;
343 }
344 \f
345 /*
346 **++
347 **  FUNCTIONAL DESCRIPTION:
348 **
349 **      This function appends a compound string to a compound string.
350 **
351 **  FORMAL PARAMETERS:
352 **
353 **      az_cstr1_entry      compound string
354 **      az_cstr2_entry      compound string
355 **      op2_temporary       true if op2 is not needed after operation
356 **
357 **  IMPLICIT INPUTS:
358 **
359 **      none
360 **
361 **  IMPLICIT OUTPUTS:
362 **
363 **      none
364 **
365 **  FUNCTION VALUE:
366 **
367 **      none
368 **
369 **  SIDE EFFECTS:
370 **
371 **      none
372 **
373 **--
374 **/
375
376 void    sem_append_cstr_to_cstr(az_cstr1_entry, az_cstr2_entry, op2_temporary)
377
378 sym_value_entry_type    *az_cstr1_entry;
379 sym_value_entry_type    *az_cstr2_entry;
380 boolean                 op2_temporary;
381
382 {
383     sym_value_entry_type        *last_str_entry;
384     sym_value_entry_type        **ptr;
385     sym_value_entry_type        *next_str_entry;
386
387     /*
388     **  A couple of points:
389     **  1) if op2_temporary = FALSE - we must make a copy of 2nd compound
390     **     string
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
394     */
395
396     /* find the last string of the 1st compound string */
397
398     ptr = &(az_cstr1_entry->az_first_table_value);
399     last_str_entry = *ptr;
400
401     next_str_entry = az_cstr2_entry->az_first_table_value;
402
403     if (op2_temporary)
404         sem_free_node(( sym_entry_type *) az_cstr2_entry );
405
406     if (next_str_entry == NULL)
407         return;
408
409     if (last_str_entry != NULL)
410     {
411         for (  ;
412              last_str_entry->az_next_table_value != NULL;  
413
414              ptr = (sym_value_entry_type * *)
415                  &(last_str_entry->az_next_table_value),
416              last_str_entry = *ptr);
417
418         if ((last_str_entry->b_charset == next_str_entry->b_charset)
419             &&
420             ((last_str_entry->b_direction)== (next_str_entry->b_direction))
421             &&
422             ((last_str_entry->b_aux_flags & sym_m_separate) == 0 ))
423         {
424             last_str_entry = 
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;
429             next_str_entry =
430                 (sym_value_entry_type *) next_str_entry->az_next_table_value;
431         }
432
433         ptr = (sym_value_entry_type * *)
434             &(last_str_entry->az_next_table_value);
435     }
436
437     if (op2_temporary)
438     {
439         *ptr = next_str_entry;
440         return;
441     }
442
443     for ( ; 
444          next_str_entry != NULL;
445          next_str_entry = (sym_value_entry_type *)
446              next_str_entry->az_next_table_value )
447     {
448         sym_value_entry_type    *new_str_entry;
449         unsigned short          old_size;
450
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 );
454
455         old_size = new_str_entry->header.w_node_size;
456
457         _sym_copy_entry( new_str_entry, 
458                next_str_entry,
459                next_str_entry->header.w_node_size );
460         
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;
465
466         /* link to the end of the compound string */
467
468         *ptr = new_str_entry;
469         ptr = (sym_value_entry_type * *)
470             &(new_str_entry->az_next_table_value);
471     }
472
473     *ptr = NULL;
474
475 }
476 \f
477 /*
478 **++
479 **  FUNCTIONAL DESCRIPTION:
480 **
481 **      This function concatenates 2 primitive strings.
482 **
483 **  FORMAL PARAMETERS:
484 **
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
489 **
490 **  IMPLICIT INPUTS:
491 **
492 **      none
493 **
494 **  IMPLICIT OUTPUTS:
495 **
496 **      none
497 **
498 **  FUNCTION VALUE:
499 **
500 **      ptr to the result string
501 **
502 **  SIDE EFFECTS:
503 **
504 **      none
505 **
506 **--
507 **/
508
509 sym_value_entry_type
510         *sem_cat_str_to_str
511             (az_str1_entry, op1_temporary, az_str2_entry, op2_temporary)
512
513 sym_value_entry_type    *az_str1_entry;
514 boolean                 op1_temporary;
515 sym_value_entry_type    *az_str2_entry;
516 boolean                 op2_temporary;
517
518 {
519     sym_value_entry_type    *new_str_entry;
520     int                     l1, l2;
521
522     /*
523     **  Can only append two simple strings if they have the same direction and
524     **  the first does not have the separate attribute.
525     */
526     _assert(((az_str1_entry->b_charset == az_str2_entry->b_charset)
527              &&
528              ((az_str1_entry->b_direction) == (az_str2_entry->b_direction))
529             ),
530             "strings with different attrs concatenated" );
531
532     l1 = az_str1_entry->w_length;
533     l2 = az_str2_entry->w_length;
534
535     /* extra 1 is for terminating null */
536
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);
541
542
543     new_str_entry->obj_header.b_flags = sym_m_builtin | sym_m_private;
544
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;
552
553     _move( new_str_entry->value.c_value, 
554            az_str1_entry->value.c_value, l1 );
555
556     _move( &new_str_entry->value.c_value[ l1 ],
557            az_str2_entry->value.c_value,
558            l2+1 );
559
560     /* 
561     **  if either of the operands is unnamed - free the node 
562     */
563
564     if (op1_temporary)
565         {
566         _free_memory( az_str1_entry->value.c_value );
567         sem_free_node(( sym_entry_type *) az_str1_entry );
568         }
569
570     if (op2_temporary)
571         {
572         _free_memory( az_str2_entry->value.c_value );
573         sem_free_node(( sym_entry_type *) az_str2_entry );
574         }
575
576     return new_str_entry;
577
578 }
579 \f
580 /*
581 **++
582 **  FUNCTIONAL DESCRIPTION:
583 **
584 **      This function takes the charset sets understood by the parser
585 **      and maps them to charsets understood by the symbol table and
586 **      toolkit.
587 **
588 **  FORMAL PARAMETERS:
589 **
590 **      charset_as_subclass     sym_k_..._charset literal naming charset
591 **
592 **  IMPLICIT INPUTS:
593 **
594 **      none
595 **
596 **  IMPLICIT OUTPUTS:
597 **
598 **      none
599 **
600 **  FUNCTION VALUE:
601 **
602 **      sym_k...charset name for charset
603 **
604 **  SIDE EFFECTS:
605 **
606 **      none
607 **
608 **--
609 **/
610
611 int     sem_map_subclass_to_charset(charset_as_subclass)
612
613 int     charset_as_subclass;
614
615 {
616     switch (charset_as_subclass)
617     {
618
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;
626     default:
627         _assert (charset_as_subclass!=0, "charset code==0");
628         _assert (charset_as_subclass<=uil_max_charset, "unknown charset");
629         return charset_as_subclass;
630     }
631 }
632
633 \f
634 /*
635 **++
636 **  FUNCTIONAL DESCRIPTION:
637 **
638 **      This function verifies the character set indicated by the user.
639 **
640 **  FORMAL PARAMETERS:
641 **
642 **      current_frame       current stack frame
643 **      charset_frame       stack frame of CHARSET token
644 **
645 **  IMPLICIT INPUTS:
646 **
647 **      none
648 **
649 **  IMPLICIT OUTPUTS:
650 **
651 **      none
652 **
653 **  FUNCTION VALUE:
654 **
655 **      none
656 **
657 **  SIDE EFFECTS:
658 **
659 **      none
660 **
661 **--
662 **/
663
664 void    sar_charset_verify ( charset_frame )
665
666 yystype           *charset_frame;
667
668 {
669     key_keytable_entry_type     *az_keyword_entry;
670
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" );
674
675     az_keyword_entry = charset_frame->value.az_keyword_entry;
676
677
678
679     /*
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)
682     */
683     Uil_lex_l_literal_charset = az_keyword_entry->b_subclass;
684 }
685
686 \f
687 /*
688 **++
689 **  FUNCTIONAL DESCRIPTION:
690 **
691 **      This function converts a random NAME into a CHARSET_NAME 
692 **      with the default charset.
693 **
694 **  FORMAL PARAMETERS:
695 **
696 **      name_frame       current stack frame containing NAME
697 **
698 **  IMPLICIT INPUTS:
699 **
700 **      none
701 **
702 **  IMPLICIT OUTPUTS:
703 **
704 **      modified name_frame
705 **
706 **  FUNCTION VALUE:
707 **
708 **      none
709 **
710 **  SIDE EFFECTS:
711 **
712 **      name_frame converted from NAME to CHARSET_NAME
713 **
714 **--
715 **/
716
717 void sar_make_fallback_charset(name_frame)
718      yystype           *name_frame;
719 {
720   sym_name_entry_type                   *symbol_entry;
721   static key_keytable_entry_type        *az_keyword_entry = NULL;
722
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" );
726
727   /* Get symbol and check if already used as charset. */
728   symbol_entry = (sym_name_entry_type *)name_frame->value.az_symbol_entry;
729   
730   if ((symbol_entry->b_flags & sym_m_charset) == 0)
731     {
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,
736                             DEFAULT_TAG);
737     }
738   
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);
742   
743   _assert((az_keyword_entry !=NULL), "default charset keyword missing");
744
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;
748
749   /*
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)
752    */
753     Uil_lex_l_literal_charset = az_keyword_entry->b_subclass;
754 }
755
756 \f
757 /*
758 **++
759 **  FUNCTIONAL DESCRIPTION:
760 **
761 **      This function checks the attributes of CHARACTER_SET function.
762 **
763 **  FORMAL PARAMETERS:
764 **
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
768 **
769 **  IMPLICIT INPUTS:
770 **
771 **      none
772 **
773 **  IMPLICIT OUTPUTS:
774 **
775 **      none
776 **
777 **  FUNCTION VALUE:
778 **
779 **      void
780 **
781 **  SIDE EFFECTS:
782 **
783 **      attribute information is stuffed in target frame
784 **
785 **--
786 **/
787
788 void    sar_chk_charset_attr( target_frame, value_frame, prior_value_frame )
789
790 yystype     *target_frame;
791 yystype     *value_frame;
792 yystype     *prior_value_frame;
793 {
794
795     /*
796     **  Set up not specified values in the target frame.
797     **      b_type will hold the sixteen_bit property
798     */
799
800     switch (prior_value_frame->b_tag)
801     {
802     case sar_k_null_frame:
803         /*
804         ** no prior values
805         */
806
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;
811         break;
812
813     case sar_k_token_frame:
814     case sar_k_value_frame:
815         /*
816         **  prior values - transfer them
817         */
818
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;
823         break;
824     default:
825         _assert( FALSE, "prior value frame missing from stack" );
826     }
827
828     /*
829     **  Case on the keyword for the attribute given
830     */
831
832     switch (value_frame->b_type)
833     {
834     case RIGHT_TO_LEFT:
835     {
836         sym_value_entry_type    *value_entry;
837
838         value_entry =
839                 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
840
841         /*
842         **  If the value is a boolean, then just set the corresponding mask 
843         **  accordingly.
844         */
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;
848             else
849                 target_frame->b_direction = XmSTRING_DIRECTION_L_TO_R;
850
851         break;
852     }
853
854     case SIXTEEN_BIT:
855     {
856         sym_value_entry_type    *value_entry;
857
858         value_entry =
859                 (sym_value_entry_type *) value_frame->value.az_symbol_entry;
860
861         /*
862         **  If the value is a boolean, then just set the corresponding mask 
863         **  accordingly.
864         */
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; 
868             else
869                 target_frame->b_type &= ~sym_m_sixteen_bit; 
870
871         break;
872     }
873
874     default:
875         _assert( FALSE, "keyword missing from stack" );
876     }
877
878 }
879
880 \f
881 /*
882 **++
883 **  FUNCTIONAL DESCRIPTION:
884 **
885 **      This function makes a CHARACTER_SET and sets the properties
886 **      of the string.
887 **
888 **  FORMAL PARAMETERS:
889 **
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
894 **
895 **  IMPLICIT INPUTS:
896 **
897 **      none
898 **
899 **  IMPLICIT OUTPUTS:
900 **
901 **      none
902 **
903 **  FUNCTION VALUE:
904 **
905 **      void
906 **
907 **  SIDE EFFECTS:
908 **
909 **      none
910 **
911 **--
912 **/
913
914 void    sar_make_charset (target_frame, value_frame, attr_frame, keyword_frame)
915
916 yystype     *target_frame;
917 yystype     *value_frame;
918 yystype     *attr_frame;
919 yystype     *keyword_frame;
920 {
921     sym_value_entry_type    *value_entry;
922
923     _assert( value_frame->b_tag == sar_k_value_frame,
924              "value frame missing from stack" );
925
926
927     /*
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.
931     */
932     value_entry =
933         (sym_value_entry_type *) value_frame->value.az_symbol_entry;
934     value_entry->b_charset = sym_k_userdefined_charset;
935  
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
940             (d_wrong_type,
941              _sar_source_pos2( value_entry ),
942              diag_value_text( value_entry->b_type ),
943              "null-terminated string");
944 /* END HaL fix CR 5547 */
945   
946  
947     /*
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.
950     */
951     if (attr_frame->b_tag == sar_k_token_frame)
952         {
953         /*
954         **  Set the attributes of the string, as specified by the options
955         **  to the CHARACTER_SET function, without disturbing any
956         **  existing bits.
957         */
958         value_entry->b_direction = attr_frame->b_direction;
959         value_entry->b_aux_flags = (attr_frame->b_type & sym_m_sixteen_bit);
960         }
961
962
963     /*
964     ** initialize the target frame
965     */
966
967     _sar_move_source_info( target_frame, keyword_frame );
968
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;
973
974
975     /*
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
978     **  string literal)
979     */
980     Uil_lex_l_literal_charset = lex_k_userdefined_charset;
981     Uil_lex_az_literal_charset = value_entry;
982 }
983
984