4 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
5 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
6 * the full copyright text.
13 static char rcsid[] = "$XConsortium: UilDB.c /main/11 1996/11/21 20:03:11 drk $"
18 * (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
25 * UIL Bindary Database :
33 * This file contains routines which change the internal tables of UIL based on
34 * a binary data base parameter in the command line
44 #ifndef X_NOT_STDC_ENV
49 #include <Mrm/MrmAppl.h>
54 #define X_INCLUDE_PWD_H
55 #define XOS_USE_XT_LOCKING
56 #include <X11/Xos_r.h>
69 * DEFINE and MACRO DEFINITIONS
72 #define _check_read( __number_returned ) \
73 if (( (__number_returned) != 1) || (feof(dbfile)) || (ferror(dbfile)) ) \
74 { diag_issue_diagnostic( d_bad_database, diag_k_no_source, diag_k_no_column ); }
81 * EXTERNAL VARIABLE DECLARATIONS
87 * GLOBAL VARIABLE DECLARATIONS
94 * OWN VARIABLE DECLARATIONS
100 void db_incorporate()
105 * PROCEDURE DESCRIPTION:
107 * This routine incorporate the binary database passed in the command line.
131 int return_num_items;
137 return_num_items = fread (&globals, sizeof(_db_globals), 1, dbfile);
138 _check_read (return_num_items);
141 * Some heuristics to see if this is a reasonable database.
142 * The magic numbers are about 10 times as big as the DXm database
143 * for DECWindows V3. The diagnostic does a fatal exit.
145 if ( globals.uil_max_arg>5000 ||
146 globals.uil_max_charset>200 ||
147 globals.charset_lang_table_max>1000 ||
148 globals.uil_max_object>500 ||
149 globals.uil_max_reason>1000 ||
150 globals.uil_max_enumval>3000 ||
151 globals.uil_max_enumset>1000 ||
152 globals.key_k_keyword_count>10000 ||
153 globals.key_k_keyword_max_length>200 ||
154 globals.uil_max_child>250)
155 diag_issue_diagnostic (d_bad_database,
159 uil_max_arg = globals.uil_max_arg ;
160 uil_max_charset = globals.uil_max_charset ;
161 charset_lang_table_max = globals.charset_lang_table_max ;
162 uil_max_object = globals.uil_max_object ;
163 uil_max_reason = globals.uil_max_reason ;
164 uil_max_enumval = globals.uil_max_enumval ;
165 uil_max_enumset = globals.uil_max_enumset ;
166 key_k_keyword_count = globals.key_k_keyword_count ;
167 key_k_keyword_max_length = globals.key_k_keyword_max_length ;
168 uil_max_child = globals.uil_max_child;
169 num_bits = (uil_max_object +7) / 8;
171 if (globals.version > DB_Compiled_Version)
172 diag_issue_diagnostic( d_future_version, diag_k_no_source, diag_k_no_column );
176 return_num_items = fread (&header, sizeof(_db_header), 1, dbfile);
177 if (feof(dbfile)) break;
178 _check_read (return_num_items);
179 switch (header.table_id)
182 constraint_tab = (unsigned char *) XtMalloc (header.table_size);
183 return_num_items = fread (constraint_tab,
184 sizeof(unsigned char) * header.num_items,
186 _check_read (return_num_items);
188 case Argument_Type_Table_Value:
190 * NOTE: The first entry is not used but we copy it anyway
192 argument_type_table = (unsigned char *) XtMalloc (header.table_size);
193 return_num_items = fread (argument_type_table,
194 sizeof(unsigned char) * header.num_items,
196 _check_read (return_num_items);
198 case Child_Class_Table:
200 * NOTE: The first entry is not used but we copy it anyway
203 (unsigned char *) XtMalloc (header.table_size);
205 fread (child_class_table,
206 sizeof(unsigned char) * header.num_items, 1, dbfile);
207 _check_read (return_num_items);
209 case Charset_Wrdirection_Table:
210 charset_writing_direction_table = (unsigned char *) XtMalloc (header.table_size);
211 return_num_items = fread (charset_writing_direction_table,
212 sizeof(unsigned char) * header.num_items,
214 _check_read (return_num_items);
216 case Charset_Parsdirection_Table:
217 charset_parsing_direction_table = (unsigned char *) XtMalloc (header.table_size);
218 return_num_items = fread (charset_parsing_direction_table,
219 sizeof(unsigned char) * header.num_items,
221 _check_read (return_num_items);
223 case Charset_Charsize_Table:
224 charset_character_size_table = (unsigned char *) XtMalloc (header.table_size);
225 return_num_items = fread (charset_character_size_table,
226 sizeof(unsigned char) * header.num_items,
228 _check_read (return_num_items);
231 case Key_Table_Case_Ins:
232 db_read_ints_and_string (&header);
234 case Allowed_Argument_Table:
235 case Allowed_Child_Table:
236 case Allowed_Control_Table:
237 case Allowed_Reason_Table:
238 db_read_char_table (&header);
240 case Charset_Xmstring_Names_Table:
241 case Charset_Lang_Names_Table:
242 case Uil_Widget_Names:
243 case Uil_Children_Names:
244 case Uil_Argument_Names:
245 case Uil_Reason_Names:
246 case Uil_Enumval_names:
247 case Uil_Charset_Names:
248 case Uil_Widget_Funcs:
249 case Uil_Argument_Toolkit_Names:
250 case Uil_Reason_Toolkit_Names:
251 db_read_length_and_string (&header);
253 case Charset_Lang_Codes_Table:
254 charset_lang_codes_table = (unsigned short int *) XtMalloc (header.table_size);
255 return_num_items = fread (charset_lang_codes_table,
258 _check_read (return_num_items);
260 case Argument_Enum_Set_Table:
261 argument_enumset_table = (unsigned short int *) XtMalloc (header.table_size);
262 return_num_items = fread (argument_enumset_table,
265 _check_read (return_num_items);
267 case Related_Argument_Table:
268 related_argument_table = (unsigned short int *) XtMalloc (header.table_size);
269 return_num_items = fread (related_argument_table,
272 _check_read (return_num_items);
274 case Uil_Gadget_Funcs:
275 uil_gadget_variants = (unsigned short int *) XtMalloc (header.table_size);
276 return_num_items = fread (uil_gadget_variants,
279 _check_read (return_num_items);
281 case Uil_Urm_Nondialog_Class:
282 uil_urm_nondialog_class = (unsigned short int *) XtMalloc (header.table_size);
283 return_num_items = fread (uil_urm_nondialog_class,
286 _check_read (return_num_items);
288 case Uil_Urm_Subtree_Resource:
289 uil_urm_subtree_resource = (unsigned short int *) XtMalloc (header.table_size);
290 return_num_items = fread (uil_urm_subtree_resource,
293 _check_read (return_num_items);
296 db_read_int_and_shorts(&header);
298 case Enumval_Values_Table:
299 enumval_values_table = (int *) XtMalloc (header.table_size);
300 return_num_items = fread (enumval_values_table,
303 _check_read (return_num_items);
306 diag_issue_diagnostic( d_bad_database, diag_k_no_source, diag_k_no_column );
315 void db_read_ints_and_string(header)
316 _db_header_ptr header;
321 * PROCEDURE DESCRIPTION:
323 * This routine reads in tables of integers and one string unsigned chars and places them into
324 * memory. It will Malloc new space for the table. The tables supported
328 * Key_Table_Case_Ins:
353 int return_num_items, i, string_size=0;
354 key_keytable_entry_type *table;
357 switch (header->table_id)
360 * NOTE: Calloc is used here to protect against bad
364 key_table = (key_keytable_entry_type *) XtCalloc (1, header->table_size);
367 case Key_Table_Case_Ins:
368 key_table_case_ins = (key_keytable_entry_type *) XtCalloc (1, header->table_size);
369 table = key_table_case_ins;
372 diag_issue_internal_error ("Bad table_id in db_read_ints_and_string");
376 * Get the entire table with one read.
377 * Then loop through the table and up the length of the strings.
378 * Get all the strings with one read.
379 * Reassign the addresses
381 return_num_items = fread(table, header->table_size, 1, dbfile);
382 _check_read (return_num_items);
384 for ( i=0 ; i<header->num_items; i++)
387 * Add one for the null character on the string
389 string_size += table[i].b_length + 1;
392 string_table = XtMalloc (sizeof (char) * string_size);
393 return_num_items = fread(string_table,
394 sizeof(unsigned char) * string_size,
396 _check_read (return_num_items);
398 for ( i=0 ; i<header->num_items; i++)
400 table[i].at_name = string_table;
401 string_table += table[i].b_length + 1;
409 void db_read_char_table(header)
410 _db_header_ptr header;
415 * PROCEDURE DESCRIPTION:
417 * This routine reads in tables of unsigned chars and places them into
418 * memory. It will Malloc new space for the table. The tables supported
421 * Allowed_Argument_Table:
422 * Allowed_Child_Table:
423 * Allowed_Control_Table:
424 * Allowed_Reason_Table:
450 int return_num_items, i;
451 unsigned char *table;
453 switch (header->table_id)
456 * NOTE: Calloc is used here to protect against bad
459 case Allowed_Argument_Table:
460 allowed_argument_table = (unsigned char **) XtCalloc (1, header->table_size);
461 ptr = allowed_argument_table;
463 case Allowed_Child_Table:
464 allowed_child_table =
465 (unsigned char **) XtCalloc (1, header->table_size);
466 ptr = allowed_child_table;
468 case Allowed_Control_Table:
469 allowed_control_table = (unsigned char **) XtCalloc (1, header->table_size);
470 ptr = allowed_control_table;
472 case Allowed_Reason_Table:
473 allowed_reason_table = (unsigned char **) XtCalloc (1, header->table_size);
474 ptr = allowed_reason_table;
477 diag_issue_internal_error ("Bad table_id in db_read_char_table");
481 * Read in the entire table contents in one whack.
482 * Then go through the table and set the addresses
484 table = (unsigned char *) XtMalloc (sizeof (unsigned char) * header->num_items * num_bits);
485 return_num_items = fread(table,
486 sizeof(char) * num_bits * header->num_items,
488 _check_read (return_num_items);
489 for ( i=1 ; i<=header->num_items; i++ )
500 void db_read_length_and_string(header)
501 _db_header_ptr header;
506 * PROCEDURE DESCRIPTION:
508 * This routine reads in length and strings of unsigned chars and places them into
509 * memory. It will Malloc new space for the table. The tables supported
512 * Charset_Xmstring_Names_Table:
513 * Charset_Lang_Names_Table:
515 * Uil_Children_Names:
516 * Uil_Argument_Names:
521 * Uil_Argument_Toolkit_Names:
522 * Uil_Reason_Toolkit_Names:
547 int return_num_items, i, string_size=0;
552 switch (header->table_id)
555 * NOTE: Calloc is used here because it might be possible to
556 * have a string of zero length, particularly for the
557 * first record. Ergo we Calloc to protect against bad
560 case Charset_Xmstring_Names_Table:
561 charset_xmstring_names_table = (char **) XtCalloc (1, header->table_size);
562 table = charset_xmstring_names_table;
564 case Charset_Lang_Names_Table:
565 charset_lang_names_table = (char **) XtCalloc (1, header->table_size);
566 table = charset_lang_names_table;
568 case Uil_Widget_Names:
569 uil_widget_names = (char **) XtCalloc (1, header->table_size);
570 table = uil_widget_names ;
572 case Uil_Children_Names:
573 uil_child_names = (char **) XtCalloc (1, header->table_size);
574 table = uil_child_names ;
576 case Uil_Argument_Names:
577 uil_argument_names = (char **) XtCalloc (1, header->table_size);
578 table = uil_argument_names;
580 case Uil_Reason_Names:
581 uil_reason_names = (char **) XtCalloc (1, header->table_size);
582 table = uil_reason_names;
584 case Uil_Enumval_names:
585 uil_enumval_names = (char **) XtCalloc (1, header->table_size);
586 table = uil_enumval_names;
588 case Uil_Charset_Names:
589 uil_charset_names = (char **) XtCalloc (1, header->table_size);
590 table = uil_charset_names;
592 case Uil_Widget_Funcs:
593 uil_widget_funcs = (char **) XtCalloc (1, header->table_size);
594 table = uil_widget_funcs;
596 case Uil_Argument_Toolkit_Names:
597 uil_argument_toolkit_names = (char **) XtCalloc (1, header->table_size);
598 table = uil_argument_toolkit_names;
600 case Uil_Reason_Toolkit_Names:
601 uil_reason_toolkit_names = (char **) XtCalloc (1, header->table_size);
602 table = uil_reason_toolkit_names;
605 diag_issue_internal_error ("Bad table_id in db_read_length_and_string");
609 * Get the lengths of all the strings with one read.
610 * Then loop through the table and up the length of the strings.
611 * Get all the strings with one read.
612 * Reassign the addresses using the length table and string table.
613 * Cleanup by Freeing length table.
615 * NOTE: In some tables the counting starts at 1 not 0 so you
616 * have to be carefull.
619 lengths = (int *) XtMalloc (sizeof (int) * (header->num_items + 1));
620 return_num_items = fread(lengths,
621 sizeof(int) * (header->num_items + 1),
623 _check_read (return_num_items);
624 for ( i=0 ; i<=header->num_items; i++)
627 * Add one for the null terminator
631 string_size += lengths[i] + 1;
635 string_table = XtMalloc (sizeof (unsigned char) * string_size);
636 return_num_items = fread(string_table,
637 sizeof(unsigned char) * string_size,
639 _check_read (return_num_items);
640 for ( i=0 ; i<=header->num_items; i++)
644 table[i] = string_table;
645 /* BEGIN HaL Fix CR 5618 */
646 if ((header->table_id == Uil_Widget_Names) &&
647 (strcmp(table[i], "user_defined") == 0))
648 uil_sym_user_defined_object = i;
649 /* END HaL Fix CR 5618 */
650 string_table += lengths[i] + 1;
654 XtFree ((char *)lengths);
661 void db_read_int_and_shorts(header)
662 _db_header_ptr header;
667 * PROCEDURE DESCRIPTION:
669 * This routine reads in a structure consisting of one integer and a
670 * pointer to a table of integer and places them into
671 * memory. It will Malloc new space for the table. The tables supported
699 int return_num_items, i, int_table_size=0;
700 UilEnumSetDescDef *table;
701 unsigned short int *int_table;
703 switch (header->table_id)
706 enum_set_table = (UilEnumSetDescDef *) XtCalloc (1, header->table_size);
707 table = enum_set_table;
710 diag_issue_internal_error ("Bad table_id in db_read_int_shorts");
714 * Get the entire table with one read.
715 * Then loop through the table and add up the number of ints in each int table.
716 * Get all the integer tables with one read.
717 * Reassign the addresses of the tables.
719 return_num_items = fread(table, header->table_size, 1, dbfile);
720 _check_read (return_num_items);
721 for ( i=0 ; i<=header->num_items; i++)
723 int_table_size += table[i].values_cnt;
726 int_table = (unsigned short int *) XtCalloc (1, sizeof (short) * int_table_size);
727 return_num_items = fread(int_table,
728 sizeof(short) * int_table_size,
730 _check_read (return_num_items);
731 for ( i=0 ; i<=header->num_items; i++)
733 if (table[i].values_cnt)
735 table[i].values = int_table;
736 int_table += table[i].values_cnt;
750 * PROCEDURE DESCRIPTION:
752 * This routine opens the binary database file in a platform-dependent way,
753 * performing i18n language switching in order to do so.
755 * Per the latest agreement on semantics, this routine does:
756 * - first, try to open in the local directory (that is, with
758 * - second, try language switching and open
762 * name A system-dependent string specifying the IDB file
785 char *resolvedname; /* current resolved name */
786 SubstitutionRec subs[3];
790 * Use XtFindFile instead of XtResolvePathName. XtResolvePathName requires a
791 * display which UIL doesn't have. At the current time there is no support for
792 * $LANG in the path string. If such support was deamed necessary, the %L, %l,
793 * %t, %c values would be set up as subs here using globals from the fetch of
794 * LANG variable used to determine the default codeset (or vice versa depending
795 * on which is called first)
797 * If the last 4 characters of the file name are not .bdb
798 * then pass in the suffix of .bdb. If a file isn't found with the suffix passed
799 * in then try without the suffix.
803 * Make sure 'S' is the last one so we can remove the suffix for the first pass.
806 subs[0].substitution = Uil_cmd_z_command.ac_database;
808 subs[1].substitution = "wmd";
810 subs[2].substitution = ".wmd";
812 wmdPath = init_wmd_path(Uil_cmd_z_command.ac_database);
817 * Check and see if the .wmd suffix is already on the file. If not then try to
818 * resolve the pathname with .wmd suffix first. If that fails or the suffix is
819 * already on the file then just try to resolve the pathname.
821 if ( strcmp (&Uil_cmd_z_command.ac_database[strlen(Uil_cmd_z_command.ac_database)-4],".wmd") != 0 )
822 resolvedname = XtFindFile(wmdPath,
825 (XtFilePredicate)NULL);
828 * No .wmd suffix or a failure to resolve the pathname with the .wmd suffix
829 * Try without the suffix.
831 subs[2].substitution = "";
832 if (resolvedname == 0)
833 resolvedname = XtFindFile(wmdPath,
836 (XtFilePredicate)NULL);
838 if (resolvedname == 0)
840 diag_issue_diagnostic( d_wmd_open,
841 diag_k_no_source, diag_k_no_column,
842 Uil_cmd_z_command.ac_database);
845 dbfile = fopen (resolvedname, "r");
847 /* If the file is not found, a fatal error is generated. */
850 diag_issue_diagnostic( d_src_open,
851 diag_k_no_source, diag_k_no_column,
861 String get_root_dir_name()
864 _Xgetpwparams pwd_buf;
865 struct passwd *pwd_value;
866 static char *ptr = NULL;
871 if((ptr = (char *)getenv("HOME")) == NULL)
873 if((ptr = (char *)getenv(USER_VAR)) != NULL)
875 pwd_value = _XGetpwnam(ptr, pwd_buf);
880 pwd_value = _XGetpwuid(uid, pwd_buf);
882 if (pwd_value != NULL)
884 ptr = pwd_value->pw_dir;
893 outptr = XtMalloc (strlen(ptr) + 2);
894 strcpy (outptr, ptr);
895 strcat (outptr, "/");
900 * XAPPLRES_DEFAULT and UIDPATH_DEFAULT are intentionally split to support
901 * SCCS. DO NOT reformat the lines else %-N-%-S could be converted by SCCS into
902 * something totally bizarre causing MrmOpenHierarchy failures.
905 /* The following are usually defined in the Makefile */
908 #define LIBDIR "/usr/lib/X11"
911 #define INCDIR "/usr/include/X11"
914 static char libdir[] = LIBDIR;
915 static char incdir[] = INCDIR;
917 static char XAPPLRES_DEFAULT[] = "\
931 static char WMDPATH_DEFAULT[] = "\
943 static char ABSOLUTE_PATH[] = "\
947 String init_wmd_path(filename)
956 if (filename[0] == '/')
958 wmd_path = XtMalloc(strlen(ABSOLUTE_PATH));
959 strcpy (wmd_path, ABSOLUTE_PATH);
963 path = (char *)getenv ("WMDPATH");
966 homedir = get_root_dir_name();
967 old_path = (char *)getenv ("XAPPLRESDIR");
968 if (old_path == NULL)
970 wmd_path = XtCalloc(1, 2*strlen(homedir) +
971 strlen(libdir) + strlen(incdir) +
972 strlen(WMDPATH_DEFAULT));
973 sprintf( wmd_path, WMDPATH_DEFAULT,
974 homedir, homedir, libdir, incdir);
978 wmd_path = XtCalloc(1, 1*strlen(old_path) + 2*strlen(homedir) +
979 strlen(libdir) + strlen(incdir) +
980 strlen(XAPPLRES_DEFAULT));
981 sprintf(wmd_path, XAPPLRES_DEFAULT,
983 homedir, homedir, libdir, incdir);
989 wmd_path = XtMalloc(strlen(path) + 1);
990 strcpy (wmd_path, path);