Files
cdesktop/cde/programs/dtappbuilder/src/libABil/abuil_load.c
T

1527 lines
37 KiB
C

/*
* 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 <stdint.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <ab_private/util_ds.h>
#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)(uintptr_t) 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)(uintptr_t) 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);
}