/* * CDE - Common Desktop Environment * * Copyright (c) 1993-2012, The Open Group. All rights reserved. * * These libraries and programs are free software; you can * redistribute them and/or modify them under the terms of the GNU * Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) * any later version. * * These libraries and programs are distributed in the hope that * they will be useful, but WITHOUT ANY WARRANTY; without even the * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public * License along with these librararies and programs; if not, write * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth * Floor, Boston, MA 02110-1301 USA */ /* * $XConsortium: abuil_load.c /main/6 1996/10/17 16:20:11 drk $ * * @(#)abuil_load.c 1.38 31 May 1994 cose/unity1/cde_app_builder/src/libABil * * RESTRICTED CONFIDENTIAL INFORMATION: * * The information in this document is subject to special * restrictions in a confidential disclosure agreement between * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this * document outside HP, IBM, Sun, USL, SCO, or Univel without * Sun's specific written approval. This document and all copies * and derivative works thereof must be returned or destroyed at * Sun's request. * * Copyright 1993 Sun Microsystems, Inc. All rights reserved. * */ /* * This file contains the implementation of the uil load * component */ #include #include #include #include #include #include "abuil_loadP.h" /* * There is no public header file for this function (only an * internal header XmStringI.h). */ extern XtPointer _XmStringUngenerate (XmString string, XmStringTag tag, XmTextType tag_type, XmTextType output_type); typedef Uil_continue_type(*UIL_CB)(); /* * Private function declarations */ static ABObjPtr uil_tree_into_ab_project( sym_entry_type *uil_parse_tree, ABObjPtr ab_project ); static ABObjPtr root_into_project( sym_entry_type *uil_root, ABObjPtr ab_project ); static ABObjPtr module_hdr_to_module( sym_entry_type *uil_module_hdr ); static ABObjPtr sections_into_module( ABObjPtr ab_module, sym_entry_type *uil_sections ); static ABObjPtr object_into_module( ABObjPtr ab_module, sym_entry_type *uil_section_entries ); static ABObjPtr object_child_into_module( ABObjPtr ab_module, sym_entry_type *uil_section_entries ); static ABObjPtr widget_into_module( ABObjPtr ab_module, ABObjPtr ab_parent, sym_widget_entry_type *uil_widget ); static ABObjPtr gadget_into_module( ABObjPtr ab_module, ABObjPtr ab_parent, sym_widget_entry_type *uil_gadget ); static ABObjPtr arguments_into_ab_widget( ABObjPtr ab_widget, sym_list_entry_type *uil_widget_arguments ); static ABObjPtr callbacks_into_ab_module( ABObjPtr ab_widget, sym_list_entry_type *uil_widget_callbacks ); static STRING ab_name_for_uil_widget( sym_widget_entry_type *uil_widget ); static STRING resource_name_for_uil_arg( sym_argument_entry_type *uil_arg ); static XtPointer resource_value_for_uil_arg( sym_argument_entry_type *uil_arg, AB_ARG_TYPE *p_res_type ); static STRING *ab_action_handler_list_for_uil_callback( sym_callback_entry_type *uil_cb, AB_WHEN *p_ab_action_when ); static sym_entry_type *parse_uil( char *uil_file_name ); static Uil_continue_type message_cb( int *message_user_data, int msg_number, int msg_severity, char *msg_text, char *src_text, char *ptr_text, char *loc_text, int message_count[] ); static Uil_continue_type status_cb( char *status_user_data, int percent_complete, int lines_processed, char *current_file, int message_count[] ); static void init_sym_stacks( void ); static void cleanup_sym_stacks( void ); static void sym_stack_push( void ); static void sym_stack_pop( void ); static void uil_sym_push( sym_entry_type *sym_entry ); static sym_entry_type * uil_sym_pop( void ); static void init_unresolved_refs( void ); static void resolve_unresolved_refs( void ); static void object_for_widget( void *client_data ); static void free_uil_tree( sym_entry_type *node_entry ); /* * Recursively goes through the uil parse tree, freeing each node * accessible from the root node in postfix order. */ static void free_uil_node( sym_entry_type *node_entry ) { sym_value_entry_type *val_node; sym_widget_entry_type *widget_node; sym_module_entry_type *module_node; sym_list_entry_type *list_node; sym_obj_entry_type *list_entry; sym_root_entry_type *root_node; sym_include_file_entry_type *ifile_node; sym_section_entry_type *section_node; /* * No action on null node. Else freeing is based on the kind * of the current node. */ if (node_entry == NULL) return; switch (node_entry->header.b_tag) { case sym_k_value_entry: val_node = (sym_value_entry_type *) node_entry; free_uil_node((sym_entry_type *) val_node->az_charset_value); free_uil_node((sym_entry_type *) val_node->az_first_table_value); free_uil_node((sym_entry_type *) val_node->az_next_table_value); free_uil_node((sym_entry_type *) val_node->az_exp_op1); free_uil_node((sym_entry_type *) val_node->az_exp_op2); break; case sym_k_widget_entry: case sym_k_gadget_entry: case sym_k_child_entry: widget_node = (sym_widget_entry_type *) node_entry; free_uil_node((sym_entry_type *) widget_node->az_callbacks); free_uil_node((sym_entry_type *) widget_node->az_arguments); free_uil_node((sym_entry_type *) widget_node->az_controls); free_uil_node((sym_entry_type *) widget_node->az_create_proc); break; case sym_k_module_entry: module_node = (sym_module_entry_type *) node_entry; free_uil_node((sym_entry_type *) module_node->az_version); free_uil_node((sym_entry_type *) module_node->az_character_set); free_uil_node((sym_entry_type *) module_node->az_case_sense); free_uil_node((sym_entry_type *) module_node->az_def_obj); break; case sym_k_list_entry: list_node = (sym_list_entry_type *) node_entry; for (list_entry = (sym_obj_entry_type *)list_node->obj_header.az_next; list_entry != NULL; ) { list_entry = (sym_obj_entry_type *)list_entry->obj_header.az_next; free_uil_node((sym_entry_type *) list_entry); } break; case sym_k_root_entry: root_node = (sym_root_entry_type *) node_entry; free_uil_node((sym_entry_type *) root_node->module_hdr); free_uil_node((sym_entry_type *) root_node->sections); break; case sym_k_include_file_entry: ifile_node = (sym_include_file_entry_type *) node_entry; free_uil_node((sym_entry_type *) ifile_node->sections); break; case sym_k_section_entry: section_node = (sym_section_entry_type *) node_entry; switch (section_node->header.b_type) { case sym_k_section_tail: break; default: free_uil_node((sym_entry_type *) section_node->entries); free_uil_node((sym_entry_type *) section_node->next); break; } break; } XtFree((char *)node_entry); } /* ---------------------------------------------------------------------- * abuil_get_uil_file: * * This function parses a UIL file specified by uil_file_path * using the standard callable UIL compiler and constructs a * ABObj tree rooted at a AB_TYPE_MODULE after adding it to * the supplied AB_TYPE_PROJECT, ab_project. * Returns NULL in case of error; otherwise returns the AB_TYPE_MODULE * object. */ extern ABObjPtr abuil_get_uil_file( STRING uil_file_path, ABObjPtr ab_project ) { sym_entry_type *uil_parse_tree; ABObj ab_module = NULL; uil_parse_tree = parse_uil(uil_file_path); if (uil_parse_tree != NULL) { if (util_get_verbosity() > 3) { abuil_trav_uil_tree((void *) uil_parse_tree); } init_sym_stacks(); init_unresolved_refs(); ab_module = uil_tree_into_ab_project(uil_parse_tree, ab_project); resolve_unresolved_refs(); cleanup_sym_stacks(); free_uil_tree(uil_parse_tree); } if (util_get_verbosity() > 3) { obj_tree_print(ab_module); } return(ab_module); } /* * This function goes through the uil parse tree (symbol table),and * recursively constructs a ABOBJ tree rooted in a project, which it then * returns. Returns NULL if there is an error. */ static ABObjPtr uil_tree_into_ab_project( sym_entry_type *uil_parse_tree, ABObjPtr ab_project ) { return(root_into_project(uil_parse_tree, ab_project)); } /* * Root into project */ static ABObjPtr root_into_project( sym_entry_type *uil_root, ABObjPtr ab_project ) { sym_root_entry_type *root_node; ABObjPtr ab_module; ABObjPtr ret_val; if (uil_root == (sym_entry_type *)NULL || uil_root->header.b_tag != sym_k_root_entry) return((ABObjPtr)NULL); else root_node = (sym_root_entry_type *)uil_root; if (ab_project != NULL && obj_is_project(ab_project)) { /* * REMIND: populate project; * use fields in uil_root */ ab_project->info.project.is_default = TRUE; /* obj_set_name(ab_project, strdup(ab_ident_from_file_name(root_node->file_name))); */ ab_module = module_hdr_to_module((sym_entry_type *)root_node->module_hdr); if (ab_module != NULL) { if (sections_into_module(ab_module, (sym_entry_type *)root_node->sections) != NULL) { obj_append_child(ab_project, ab_module); ret_val = ab_module; } else { obj_destroy(ab_module); ret_val = (ABObjPtr)NULL; } } else ret_val = (ABObjPtr)NULL; } return(ret_val); } static ABObjPtr module_hdr_to_module( sym_entry_type *uil_module_hdr ) { ABObjPtr ab_module; sym_module_entry_type *module_node; if (uil_module_hdr == (sym_entry_type *)NULL || uil_module_hdr->header.b_tag != sym_k_module_entry) return((ABObjPtr)NULL); else module_node = (sym_module_entry_type *)uil_module_hdr; ab_module = obj_create(AB_TYPE_MODULE, NULL); if (ab_module != NULL) { /* * REMIND: populate module; * traverse module header */ obj_set_name(ab_module, strdup(ab_ident_from_file_name( (char *)module_node->obj_header.az_name->c_text))); } return(ab_module); } /* * The merge-in routines. */ /* * Pre-condition: ab_module != NULL */ static ABObjPtr sections_into_module( ABObjPtr ab_module, sym_entry_type *uil_sections ) { sym_entry_type *next_node; sym_section_entry_type *section_node; short int done; ABObjPtr ret_val; /* * populate module; * traverse tail terminated * list of sections. */ next_node = uil_sections; sym_stack_push(); done = 0; while (!done) { if (next_node == (sym_entry_type *)NULL || next_node->header.b_tag != sym_k_section_entry) { return((ABObjPtr)NULL); } else section_node = (sym_section_entry_type *)next_node; switch (section_node->header.b_type) { case sym_k_section_tail: done = 1; break; case sym_k_object_section: case 0: uil_sym_push((sym_entry_type *)section_node); break; default: break; } next_node = section_node->next; } done = 0; while (!done) { if ((section_node = (sym_section_entry_type *)uil_sym_pop()) == NULL) break; switch (section_node->header.b_type) { case sym_k_object_section: if ((ret_val = object_into_module(ab_module, section_node->entries)) == NULL) done = 1; break; case 0: if ((ret_val = object_child_into_module(ab_module, section_node->entries)) == NULL) done = 1; break; } } sym_stack_pop(); return(ret_val); } static ABObjPtr object_into_module( ABObjPtr ab_module, sym_entry_type *uil_section_entries ) { sym_section_entry_type *section_node; sym_section_entry_type *section_trav; ABObjPtr ret_val = NULL; if (uil_section_entries == (sym_entry_type *)NULL || uil_section_entries->header.b_tag != sym_k_section_entry) { return((ABObjPtr)NULL); } else section_node = (sym_section_entry_type *)uil_section_entries; /* * entries field of an object section is a small chain * consisting of type 0 sections (typically one) */ for (section_trav = section_node; section_trav != (sym_section_entry_type *)NULL; section_trav = (sym_section_entry_type *)section_trav->next) { if (section_trav->header.b_type != 0) continue; if ((ret_val = object_child_into_module(ab_module, section_trav->entries)) == NULL) break; } return(ret_val); } static ABObjPtr object_child_into_module( ABObjPtr ab_module, sym_entry_type *uil_section_entries ) { ABObjPtr ret_val; sym_widget_entry_type *uil_widget; if (uil_section_entries == (sym_entry_type *)NULL) { return((ABObjPtr)NULL); } ret_val = ab_module; switch (uil_section_entries->header.b_tag) { case sym_k_widget_entry: uil_widget = (sym_widget_entry_type *)uil_section_entries; if (uil_widget->parent_list == NULL) ret_val = widget_into_module(ab_module, ab_module, uil_widget); break; case sym_k_gadget_entry: uil_widget = (sym_widget_entry_type *)uil_section_entries; if (uil_widget->parent_list == NULL) ret_val = gadget_into_module(ab_module, ab_module, uil_widget); break; default: obj_destroy(ab_module); ret_val = (ABObjPtr)NULL; } return(ret_val); } /* * Precondition: uil_widget->header.b_tag = sym_k_widget_entry * uil_widget->parent_list = NULL */ static ABObjPtr widget_into_module( ABObjPtr ab_module, ABObjPtr ab_parent, sym_widget_entry_type *uil_widget ) { ABObjPtr ab_widget; sym_list_entry_type *controls; sym_control_entry_type *a_control; sym_widget_entry_type *uil_child; AB_OBJECT_TYPE ab_type; WidgetABObjMap *ab_map_entry = abuilP_entry_for_uil_widget(uil_widget); STRING ab_name = ab_name_for_uil_widget(uil_widget); /* * Should never happen */ if (ab_map_entry == (WidgetABObjMap *)NULL) return(NULL); if (ab_parent == (ABObj)NULL) return(NULL); ab_type = ab_map_entry->obj_type; if (ab_type != AB_TYPE_UNKNOWN) { char class_name[BUFSIZ]; ab_widget = obj_create(ab_type, NULL); if (ab_map_entry->sub_type != 0) obj_set_subtype(ab_widget, ab_map_entry->sub_type); obj_append_child(ab_parent, ab_widget); obj_set_name(ab_widget, ab_name); strcpy(class_name, ab_map_entry->widget_name); class_name[0] = tolower(class_name[0]); strcat(class_name, CLASS_SUFFIX); obj_set_class_name(ab_widget, class_name); /* * Store ABObj reference in uil widget node */ uil_widget->header.user_data = (long)ab_widget; /* * Populate arguments and callbacks */ if (arguments_into_ab_widget(ab_widget, uil_widget->az_arguments) == NULL || callbacks_into_ab_module(ab_widget, uil_widget->az_callbacks) == NULL) { obj_destroy(ab_widget); return((ABObjPtr)NULL); } } else { /* * skip this child: it goes as an attribute * in either its parent or its child */ ab_widget = ab_parent; /* * Store ABObj reference in uil widget node */ uil_widget->header.user_data = (long)ab_widget; } if (ab_map_entry->object_proc != NULL) { ABObj ret_widget; ret_widget = (*ab_map_entry->object_proc)(ab_map_entry->widget_name, ab_parent, ab_widget); if (ret_widget == NULL) { obj_unparent(ab_widget); obj_move_children(ab_parent, ab_widget); obj_destroy(ab_widget); return(ab_parent); } else ab_widget = ret_widget; } controls = uil_widget->az_controls; if (controls == NULL) return(ab_widget); sym_stack_push(); for (a_control = (sym_control_entry_type *)controls->obj_header.az_next; a_control != NULL; a_control = (sym_control_entry_type *)a_control->obj_header.az_next) { uil_child = a_control->az_con_obj; /* * If the reference field is set, this is a reference to a control * defined elsewhere. Otherwise it is an inline definition. */ while (uil_child->obj_header.az_reference != NULL) uil_child = (sym_widget_entry_type *)uil_child->obj_header.az_reference; uil_sym_push((sym_entry_type *) uil_child); } while ((uil_child = (sym_widget_entry_type *)uil_sym_pop()) != NULL) { ABObj ab_child; ab_child = widget_into_module(ab_module, ab_widget, uil_child); if (ab_child == ab_widget) continue; if (ab_map_entry->child_proc != NULL) { ABObj ret_child; ret_child = (*ab_map_entry->child_proc)(ab_map_entry->widget_name, ab_widget, ab_child); if (ret_child == NULL) obj_destroy(ab_child); else ab_child = ret_child; } } sym_stack_pop(); return(ab_widget); } /* * Precondition: uil_widget->header.b_tag = sym_k_gadget_entry */ static ABObjPtr gadget_into_module( ABObjPtr ab_module, ABObjPtr ab_parent, sym_widget_entry_type *uil_gadget ) { fprintf(stderr, "gadget_into_module: UNIMPLEMENTED.\n"); return(ab_module); } static ABObjPtr arguments_into_ab_widget( ABObjPtr ab_widget, sym_list_entry_type *uil_widget_arguments ) { sym_list_entry_type *widget_args; if (uil_widget_arguments == (sym_list_entry_type *)NULL) return(ab_widget); if (uil_widget_arguments->header.b_tag != sym_k_list_entry || uil_widget_arguments->header.b_type != sym_k_argument_entry) return(NULL); abuilP_init_context_attrs(); widget_args = (sym_list_entry_type *)uil_widget_arguments; for (widget_args = (sym_list_entry_type *)widget_args->obj_header.az_next; widget_args != NULL; widget_args = (sym_list_entry_type *)widget_args->obj_header.az_next) { /* * REMIND: All this stuff should be pushed into a function */ sym_argument_entry_type *uil_arg; STRING res_name; XtPointer res_value; AB_ARG_TYPE res_type; if (widget_args->header.b_tag != sym_k_argument_entry) continue; uil_arg = (sym_argument_entry_type *)widget_args; res_name = resource_name_for_uil_arg(uil_arg); res_value = resource_value_for_uil_arg(uil_arg, &res_type); if (!abuilP_store_attr_in_abobj(ab_widget, res_name, res_type, res_value)) { /* REMIND: we use Xt Args, now! obj_set_arg(ab_widget, res_type, res_name, res_value); */ } } abuilP_store_context_attrs(ab_widget); return(ab_widget); } static ABObjPtr callbacks_into_ab_module( ABObjPtr ab_widget, sym_list_entry_type *uil_widget_callbacks ) { sym_list_entry_type *widget_cbs; ABObjPtr ab_module; if (uil_widget_callbacks == (sym_list_entry_type *)NULL) return(ab_widget); ab_module = obj_get_module(ab_widget); if (uil_widget_callbacks->header.b_tag != sym_k_list_entry || uil_widget_callbacks->header.b_type != sym_k_callback_entry) return(NULL); widget_cbs = (sym_list_entry_type *)uil_widget_callbacks; for (widget_cbs = (sym_list_entry_type *)widget_cbs->obj_header.az_next; widget_cbs != NULL; widget_cbs = (sym_list_entry_type *)widget_cbs->obj_header.az_next) { /* * REMIND: All this stuff should be pushed into a function */ sym_callback_entry_type *uil_cb; AB_WHEN ab_action_when; STRING *ab_handler_list; STRING *ab_handler_trav; /* REMIND: incorporate new action API * ABTrigger ab_trigger; */ if (widget_cbs->header.b_tag != sym_k_callback_entry) continue; uil_cb = (sym_callback_entry_type *)widget_cbs; ab_handler_list = ab_action_handler_list_for_uil_callback(uil_cb, &ab_action_when); for (ab_handler_trav = ab_handler_list; ab_handler_trav != (STRING *)NULL; ab_handler_trav++) { ABObjPtr ab_action = obj_create(AB_TYPE_ACTION, NULL); obj_set_func_type(ab_action, AB_FUNC_USER_DEF); obj_set_func_name(ab_action, *ab_handler_trav); obj_set_arg_type(ab_action, AB_ARG_VOID_PTR); ab_action->info.action.to = NULL; /* * REMIND: incorporate new action API * * obj_add_action(ab_module, ab_action); * ab_trigger = trigger_create(); * ab_trigger->from = ab_widget; * ab_trigger->when = ab_action_when; * obj_action_add_trigger(ab_action, ab_trigger); */ } if (ab_handler_list != (STRING *)NULL) XtFree((char*)ab_handler_list); } return(ab_module); } /* * Convenience functions */ static STRING ab_name_for_uil_widget(sym_widget_entry_type *uil_widget) { STRING wid_name = NULL; if (uil_widget->obj_header.az_name != NULL) wid_name = (STRING)&(uil_widget->obj_header.az_name->c_text); if (wid_name == NULL) wid_name = "NoName"; return(wid_name); } static STRING resource_name_for_uil_arg(sym_argument_entry_type *uil_arg) { sym_value_entry_type *resource_name = (sym_value_entry_type *)uil_arg->az_arg_name; if (resource_name->obj_header.b_flags & sym_m_builtin) { key_keytable_entry_type *key_entry; key_entry = (key_keytable_entry_type *)resource_name->value.l_integer; return(key_entry->at_name); } else return((char *)resource_name->value.c_value); } static XtPointer resource_value_for_uil_arg( sym_argument_entry_type *uil_arg, AB_ARG_TYPE *p_res_type ) { sym_value_entry_type *resource_value = (sym_value_entry_type *)uil_arg->az_arg_value; XtPointer ret_val = (XtPointer)NULL; *p_res_type = AB_ARG_VOID_PTR; if (resource_value->obj_header.b_flags & sym_m_imported) { /* * REMIND: implement imported values */ fprintf(stderr, "imported value for argument: UNIMPLEMENTED\n"); return(NULL); } /* * Note that the argument value entry need not * be of type sym_k_value_entry. * It could be a sym_k_widget_entry!! (Oh joy). * In that case, process it as a widget reference */ if (resource_value->header.b_tag == sym_k_widget_entry) { ABObj abobj_ref; sym_widget_entry_type *uil_child = (sym_widget_entry_type *)resource_value; /* * The reference field will be set; this is a reference to a control * defined elsewhere. */ while (uil_child->obj_header.az_reference != NULL) uil_child = (sym_widget_entry_type *)uil_child->obj_header.az_reference; ret_val = (XtPointer)uil_child; abobj_ref = (ABObj)uil_child->header.user_data; if (abobj_ref == NULL) { *p_res_type = AB_ARG_WIDGET; ret_val = (XtPointer)uil_child; } else { *p_res_type = AB_ARG_VOID_PTR; ret_val = (XtPointer)abobj_ref; } return(ret_val); } switch (resource_value->b_type) { case sym_k_integer_value: /* * No special action if value is not an integer enumeration value. * Else; value must be from enumeration set */ if (resource_value->b_enumeration_value_code != 0) { unsigned short int enumval_code; enumval_code = resource_value->b_enumeration_value_code; ret_val = (XtPointer)uil_enumval_names[enumval_code]; *p_res_type = AB_ARG_LITERAL; } else { ret_val = (XtPointer)resource_value->value.l_integer; *p_res_type = AB_ARG_INT; } break; case sym_k_bool_value: ret_val = (XtPointer)resource_value->value.l_integer; *p_res_type = AB_ARG_BOOLEAN; break; case sym_k_float_value: { float *f_val = (float *)&(resource_value->value.d_real); ret_val = (XtPointer)f_val; *p_res_type = AB_ARG_FLOAT; } break; case sym_k_color_value: /* { char *ptr; switch (resource_value->b_arg_type) { case sym_k_background_color: ptr = "background"; break; case sym_k_foreground_color: ptr = "foreground"; break; case sym_k_unspecified_color: ptr = "unspecified"; break; default: ptr = "illegal"; } } */ ret_val = (XtPointer)resource_value->value.c_value; *p_res_type = AB_ARG_STRING; break; case sym_k_reason_value: case sym_k_argument_value: break; case sym_k_compound_string_value: ret_val = _XmStringUngenerate((XmString)resource_value->value.c_value, XmFONTLIST_DEFAULT_TAG, XmCHARSET_TEXT, XmCHARSET_TEXT); if (ret_val != NULL) { *p_res_type = AB_ARG_STRING; } break; case sym_k_font_value: case sym_k_fontset_value: fprintf(stderr, "font_value or fontset_value for argument: UNIMPLEMENTED\n"); goto check_for_table_value; case sym_k_char_8_value: fprintf(stderr, "char_8_value for argument: UNIMPLEMENTED\n"); if (resource_value->b_charset != sym_k_userdefined_charset) switch (resource_value->b_direction) { case XmSTRING_DIRECTION_L_TO_R: break; case XmSTRING_DIRECTION_R_TO_L: break; } else switch (resource_value->b_direction) { case XmSTRING_DIRECTION_L_TO_R: break; case XmSTRING_DIRECTION_R_TO_L: break; } /* See if this is an entry in a table. */ check_for_table_value: if ((resource_value->b_aux_flags & sym_m_table_entry) != 0) { printf(" next table entry: %p", resource_value->az_next_table_value); } ret_val = resource_value->value.c_value; *p_res_type = AB_ARG_LITERAL; break; case sym_k_identifier_value: ret_val = (XtPointer)resource_value->value.c_value; *p_res_type = AB_ARG_STRING; break; case sym_k_icon_value: fprintf(stderr, "icon_value for argument: UNIMPLEMENTED\n"); break; case sym_k_string_table_value: fprintf(stderr, "string_table_value for argument: UNIMPLEMENTED\n"); goto common_table; case sym_k_font_table_value: fprintf(stderr, "font_table_value for argument: UNIMPLEMENTED\n"); goto common_table; case sym_k_trans_table_value: fprintf(stderr, "trans_table_value for argument: UNIMPLEMENTED\n"); common_table: break; case sym_k_color_table_value: fprintf(stderr, "color_table_value for argument: UNIMPLEMENTED\n"); break; case sym_k_error_value: fprintf(stderr, "error_value for argument: UNIMPLEMENTED\n"); break; case sym_k_keysym_value: /* fprintf(stderr, "keysym_value for argument: UNIMPLEMENTED\n"); */ ret_val = (XtPointer)resource_value->value.c_value; *p_res_type = AB_ARG_STRING; break; default: fprintf(stderr, "unknown type %d for value for argument\n", (int) resource_value->b_type); break; } return(ret_val); } static STRING * ab_action_handler_list_for_uil_callback( sym_callback_entry_type *uil_cb, AB_WHEN *p_ab_action_when ) { return((STRING *)NULL); } /* * parse_uil: Use the callable UIL compiler to create a uil parse tree. * Check all error conditionals and print a report on stdout. * Returns the uil parse tree or NULL if there were errors. */ static sym_entry_type * parse_uil( char *uil_file_name ) { Uil_command_type command_desc; Uil_compile_desc_type compile_desc; Uil_status_type compile_stat; int user_mess_data = 1; int user_stat_data = 1; char *ret_val; /* Set up command description structure */ command_desc.source_file = uil_file_name; command_desc.resource_file = NULL; command_desc.listing_file = NULL; command_desc.include_dir_count = 0; /* give info on what files you want created */ command_desc.listing_file_flag = 0; /* no listing */ command_desc.resource_file_flag = 0; /* no UID file */ command_desc.machine_code_flag = 0; /* no machine code */ command_desc.report_info_msg_flag = 1; /* report info messages */ command_desc.report_warn_msg_flag = 1; /* report all warnings */ command_desc.parse_tree_flag = 1; /* create a parse tree */ command_desc.status_update_delay = 300; /* set proper delay */ command_desc.database_flag = 0; command_desc.use_setlocale_flag = 1; fprintf(stderr, "Compiling UIL file %s...\n", uil_file_name); /* Call uil compiler with appropriate paramters */ compile_stat = Uil(&command_desc, &compile_desc, (UIL_CB)message_cb, (char *)&user_mess_data, (UIL_CB)status_cb, (char *)&user_stat_data); fprintf(stderr, "\nUIL Compiler Version %d, ", compile_desc.compiler_version); fprintf(stderr, "Data Structures Version %d: ", compile_desc.data_version); /* check status and print out appropriate messages */ switch (compile_stat) { case Uil_k_success_status: fprintf(stderr, "no errors.\n"); ret_val = compile_desc.parse_tree_root; break; case Uil_k_info_status: fprintf(stderr, "no errors, some information.\n"); ret_val = compile_desc.parse_tree_root; break; case Uil_k_warning_status: fprintf(stderr, "no errors, some warning(s).\n"); ret_val = compile_desc.parse_tree_root; break; case Uil_k_error_status: fprintf(stderr, "compile failed, some error(s).\n"); ret_val = (char *)NULL; break; case Uil_k_severe_status: fprintf(stderr, "compile failed, severe error(s).\n"); ret_val = (char *)NULL; break; } /* * Disable Uil specified signal handlers, grrr! */ signal( SIGBUS, SIG_DFL); #ifdef SIGSYS signal( SIGSYS, SIG_DFL); #endif signal( SIGFPE, SIG_DFL); return((sym_entry_type *)ret_val); } /* * message_cb: This procedure will print to stdout information on the * compilation process. Specifically if errors warnings appear. */ static Uil_continue_type message_cb( int *message_user_data, /* user message number */ int msg_number, /* to identify the error */ int msg_severity, /* severity level */ char *msg_text, /* text of message */ char *src_text, /* text of source of error */ char *ptr_text, /* source column information */ char *loc_text, /* location line */ int message_count[] ) { if (msg_number != 38) /* if not an error summary */ { fprintf(stderr, "\t Diagnostic %d: Code: %d, Severity: %d\n", *message_user_data, msg_number, msg_severity); fprintf(stderr, "%s: %s\n", loc_text, msg_text); fprintf(stderr, "\t\t Source: %s\n", src_text); } else fprintf(stderr, "Compilation results: %s\n", msg_text); *message_user_data = *message_user_data + 1; return(Uil_k_continue); } /* * status_cb: print to stdout information the status of the compilation * process. This summary will print the source file being * worked on, the number of lines, and the percentage completed */ static Uil_continue_type status_cb( char *status_user_data, int percent_complete, int lines_processed, char *current_file, int message_count[] ) { /* fprintf(stderr, "Status #%d -- Lines: %d, File: %s, Percentage: %d%%\n", *status_user_data, lines_processed, current_file, percent_complete); */ *status_user_data = *status_user_data + 1; return(Uil_k_continue); } /* * Stack management to reverse order of section, list and other * sequences in the UIL parse tree */ #define STACK_INIT 32 #define STACK_INCR 16 typedef struct _uil_sym_stack_struct { sym_entry_type **stack_entries; int stack_ptr; int stack_size; } UilSymStackStruct, *UilSymStack; static UilSymStack *stack_stack; static int stack_stack_ptr; static int stack_stack_size; static void init_sym_stacks( void ) { stack_stack_size = STACK_INIT; stack_stack = (UilSymStack *) malloc(sizeof(UilSymStack) * stack_stack_size); if (stack_stack == (UilSymStack *)NULL) { fprintf(stderr, "loaduil: malloc failed.\n"); exit(1); } stack_stack_ptr = 0; } static void cleanup_sym_stacks( void ) { free((void *)stack_stack); stack_stack_ptr = 0; stack_stack_size = 0; } static void sym_stack_push( void ) { UilSymStack new_stack; /* * Build new stack */ new_stack = (UilSymStack)malloc(sizeof(UilSymStackStruct)); if (new_stack == (UilSymStack)NULL) { fprintf(stderr, "loaduil: malloc failed.\n"); exit(1); } new_stack->stack_size = STACK_INIT; new_stack->stack_entries = (sym_entry_type **) malloc(sizeof(sym_entry_type *) * new_stack->stack_size); if (new_stack->stack_entries == (sym_entry_type **)NULL) { fprintf(stderr, "loaduil: malloc failed.\n"); exit(1); } new_stack->stack_ptr = 0; /* * Push new stack on stack-stack */ if (stack_stack_ptr == stack_stack_size) { stack_stack_size += STACK_INCR; stack_stack = (UilSymStack *) realloc((void *)stack_stack, sizeof(UilSymStack)*stack_stack_size); if (stack_stack == (UilSymStack *)NULL) { fprintf(stderr, "loaduil: realloc failed.\n"); exit(1); } } stack_stack[stack_stack_ptr++] = new_stack; } static void sym_stack_pop( void ) { if (stack_stack_ptr > 0) free((void *)stack_stack[--stack_stack_ptr]); } /* * Pushes a symbol table entry into a stack * * sym_entry pointer to symbol table to push */ static void uil_sym_push( sym_entry_type *sym_entry ) { UilSymStack cur_stack = stack_stack[stack_stack_ptr - 1]; if (cur_stack->stack_ptr == cur_stack->stack_size) { cur_stack->stack_size += STACK_INCR; cur_stack->stack_entries = (sym_entry_type **) realloc((void *)cur_stack->stack_entries, sizeof(sym_entry_type *) * cur_stack->stack_size); if (cur_stack->stack_entries == (sym_entry_type **)NULL) { fprintf(stderr, "loaduil: realloc failed.\n"); exit(1); } } cur_stack->stack_entries[cur_stack->stack_ptr++] = sym_entry; } /* * Pops a symbol table entry from a stack * * It returns * sym_entry pointer to symbol table popped * NULL when no more to pop */ static sym_entry_type * uil_sym_pop( void ) { UilSymStack cur_stack = stack_stack[stack_stack_ptr - 1]; if (cur_stack->stack_ptr == 0) return((sym_entry_type *) NULL); else return(cur_stack->stack_entries[--cur_stack->stack_ptr]); } static LList unresolved_refs; static void init_unresolved_refs( void ) { unresolved_refs = util_llist_create(); } extern void abuil_add_unresolved_ref( void *entry ) { util_llist_insert_after(unresolved_refs, entry); } static void resolve_unresolved_refs( void ) { util_llist_iterate(unresolved_refs, object_for_widget); util_llist_destroy(unresolved_refs); } static void object_for_widget( void *client_data ) { RefResolve *rr = (RefResolve *)client_data; sym_widget_entry_type *field_widget; ABObj obj_ref; if (rr == (RefResolve *)NULL) return; field_widget = (sym_widget_entry_type *) obj_get_attach_value(rr->obj, rr->dir); if (field_widget == NULL) return; obj_ref = (ABObj)field_widget->header.user_data; obj_set_attach_value(rr->obj, rr->dir, obj_ref); XtFree((char *)rr); } /* * Recursively goes through the uil parse tree, freeing each node * accessible from the root node in postfix order. */ static void free_uil_tree( sym_entry_type *node_entry ) { sym_value_entry_type *val_node; sym_widget_entry_type *widget_node; sym_module_entry_type *module_node; sym_list_entry_type *list_node; sym_obj_entry_type *list_entry; sym_root_entry_type *root_node; sym_include_file_entry_type *ifile_node; sym_section_entry_type *section_node; /* * No action on null node. Else freeing is based on the kind * of the current node. */ if (node_entry == NULL) return; switch (node_entry->header.b_tag) { case sym_k_value_entry: val_node = (sym_value_entry_type *) node_entry; free_uil_tree((sym_entry_type *) val_node->az_charset_value); free_uil_tree((sym_entry_type *) val_node->az_first_table_value); free_uil_tree((sym_entry_type *) val_node->az_next_table_value); free_uil_tree((sym_entry_type *) val_node->az_exp_op1); free_uil_tree((sym_entry_type *) val_node->az_exp_op2); break; case sym_k_widget_entry: case sym_k_gadget_entry: case sym_k_child_entry: widget_node = (sym_widget_entry_type *) node_entry; free_uil_tree((sym_entry_type *) widget_node->az_callbacks); free_uil_tree((sym_entry_type *) widget_node->az_arguments); free_uil_tree((sym_entry_type *) widget_node->az_controls); free_uil_tree((sym_entry_type *) widget_node->az_create_proc); break; case sym_k_module_entry: module_node = (sym_module_entry_type *) node_entry; free_uil_tree((sym_entry_type *) module_node->az_version); free_uil_tree((sym_entry_type *) module_node->az_character_set); free_uil_tree((sym_entry_type *) module_node->az_case_sense); free_uil_tree((sym_entry_type *) module_node->az_def_obj); break; case sym_k_list_entry: list_node = (sym_list_entry_type *) node_entry; for (list_entry = (sym_obj_entry_type *)list_node->obj_header.az_next; list_entry != NULL; ) { list_entry = (sym_obj_entry_type *)list_entry->obj_header.az_next; free_uil_tree((sym_entry_type *) list_entry); } break; case sym_k_root_entry: root_node = (sym_root_entry_type *) node_entry; free_uil_tree((sym_entry_type *) root_node->module_hdr); free_uil_tree((sym_entry_type *) root_node->sections); break; case sym_k_include_file_entry: ifile_node = (sym_include_file_entry_type *) node_entry; free_uil_tree((sym_entry_type *) ifile_node->sections); break; case sym_k_section_entry: section_node = (sym_section_entry_type *) node_entry; switch (section_node->header.b_type) { case sym_k_section_tail: break; default: free_uil_tree((sym_entry_type *) section_node->entries); free_uil_tree((sym_entry_type *) section_node->next); break; } break; } XtFree((char*)node_entry); }