comparison src/specifier.c @ 5015:d95c102a96d3

cleanups for specifier font stages, from ben-unicode-internal (preparation for eliminating shadowed warnings) -------------------- ChangeLog entries follow: -------------------- src/ChangeLog addition: 2010-02-08 Ben Wing <ben@xemacs.org> * faces.c: * faces.c (face_property_matching_instance): * faces.c (ensure_face_cachel_contains_charset): * faces.h (FACE_FONT): * lisp.h: * lisp.h (enum font_specifier_matchspec_stages): * objects-msw.c: * objects-msw.c (mswindows_font_spec_matches_charset): * objects-msw.c (mswindows_find_charset_font): * objects-tty.c: * objects-tty.c (tty_font_spec_matches_charset): * objects-tty.c (tty_find_charset_font): * objects-xlike-inc.c: * objects-xlike-inc.c (XFUN): * objects-xlike-inc.c (xft_find_charset_font): * objects.c: * objects.c (font_instantiate): * objects.c (FROB): * specifier.c: * specifier.c (charset_matches_specifier_tag_set_p): * specifier.c (call_charset_predicate): * specifier.c (define_specifier_tag): * specifier.c (Fdefine_specifier_tag): * specifier.c (setup_charset_initial_specifier_tags): * specifier.c (specifier_instance_from_inst_list): * specifier.c (FROB): * specifier.c (vars_of_specifier): * specifier.h: Rename the specifier-font-matching stages in preparation for eliminating shadowed warnings, some other related fixes from ben-unicode-internal. 1. Rename raw enums: initial -> STAGE_INITIAL final -> STAGE_FINAL impossible -> NUM_MATCHSPEC_STAGES 2. Move `enum font_specifier_matchspec_stages' from specifier.h to lisp.h. 3. Whitespace changes to match coding standards. 4. Eliminate unused second argument STAGE in charset predicates that don't use it -- the code that calls the charset predicates is now smart enough to supply the right number of arguments automatically. 5. Add some long(ish) comments and authorial notices, esp. in objects.c. 6. In specifier.c, change Vcharset_tag_lists from a vector over leading bytes to a hash table over charsets. This change is unnecessary currently but doesn't hurt and will be required when we merge in Unicode-internal. 7. In specifier.c, extract out the code that calls charset predicates into a function call_charset_predicate().
author Ben Wing <ben@xemacs.org>
date Mon, 08 Feb 2010 16:51:25 -0600
parents ae48681c47fa
children 2ade80e8c640
comparison
equal deleted inserted replaced
5014:c2e0c3af5fe3 5015:d95c102a96d3
1 /* Specifier implementation 1 /* Specifier implementation
2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
3 Copyright (C) 1995, 1996, 2002, 2005 Ben Wing. 3 Copyright (C) 1995, 1996, 2002, 2005, 2010 Ben Wing.
4 Copyright (C) 1995 Sun Microsystems, Inc. 4 Copyright (C) 1995 Sun Microsystems, Inc.
5 5
6 This file is part of XEmacs. 6 This file is part of XEmacs.
7 7
8 XEmacs is free software; you can redistribute it and/or modify it 8 XEmacs is free software; you can redistribute it and/or modify it
31 #include "lisp.h" 31 #include "lisp.h"
32 32
33 #include "buffer.h" 33 #include "buffer.h"
34 #include "chartab.h" 34 #include "chartab.h"
35 #include "device-impl.h" 35 #include "device-impl.h"
36 #include "elhash.h"
36 #include "frame.h" 37 #include "frame.h"
37 #include "glyphs.h" 38 #include "glyphs.h"
38 #include "opaque.h" 39 #include "opaque.h"
39 #include "rangetab.h" 40 #include "rangetab.h"
40 #include "specifier.h" 41 #include "specifier.h"
45 Lisp_Object Qremove_locale, Qremove_locale_type; 46 Lisp_Object Qremove_locale, Qremove_locale_type;
46 47
47 Lisp_Object Qconsole_type, Qdevice_class; 48 Lisp_Object Qconsole_type, Qdevice_class;
48 49
49 static Lisp_Object Vuser_defined_tags; 50 static Lisp_Object Vuser_defined_tags;
51 /* This is a hash table mapping charsets to "tag lists". A tag list here
52 is an assoc list mapping charset tags to size-two vectors (one for the
53 initial stage, one for the final stage) containing t or nil, indicating
54 whether the charset tag matches the charset for the given stage. These
55 values are determined at the time a charset tag is defined by calling
56 the charset predicate on all the existing charsets, and at the time a
57 charset is defined by calling the predicate on all existing charset
58 tags. */
50 static Lisp_Object Vcharset_tag_lists; 59 static Lisp_Object Vcharset_tag_lists;
51 60
52 typedef struct specifier_type_entry specifier_type_entry; 61 typedef struct specifier_type_entry specifier_type_entry;
53 struct specifier_type_entry 62 struct specifier_type_entry
54 { 63 {
980 989
981 return 1; 990 return 1;
982 } 991 }
983 992
984 static int 993 static int
985 charset_matches_specifier_tag_set_p (Lisp_Object USED_IF_MULE (charset), 994 charset_matches_specifier_tag_set_p (Lisp_Object charset, Lisp_Object tag_set,
986 Lisp_Object tag_set,
987 enum font_specifier_matchspec_stages 995 enum font_specifier_matchspec_stages
988 stage) 996 stage)
989 { 997 {
990 Lisp_Object rest; 998 Lisp_Object rest;
991 int res = 0; 999 int res = 0;
992 1000
993 assert(stage != impossible); 1001 assert(stage < NUM_MATCHSPEC_STAGES);
994 1002
995 LIST_LOOP (rest, tag_set) 1003 LIST_LOOP (rest, tag_set)
996 { 1004 {
997 Lisp_Object tag = XCAR (rest); 1005 Lisp_Object tag = XCAR (rest);
998 Lisp_Object assoc; 1006 Lisp_Object assoc;
1007 Lisp_Object tag_list = Fgethash (charset, Vcharset_tag_lists, Qnil);
999 1008
1000 /* In the event that, during the creation of a charset, no specifier 1009 /* In the event that, during the creation of a charset, no specifier
1001 tags exist for which CHARSET-PREDICATE has been specified, then 1010 tags exist for which CHARSET-PREDICATE has been specified, then
1002 that charset's entry in Vcharset_tag_lists will be nil, and this 1011 that charset's entry in Vcharset_tag_lists will be nil, and this
1003 charset shouldn't match. */ 1012 charset shouldn't match. */
1004 1013
1005 if (NILP (XVECTOR_DATA(Vcharset_tag_lists)[XCHARSET_LEADING_BYTE(charset) 1014 if (NILP (tag_list))
1006 - MIN_LEADING_BYTE]))
1007 { 1015 {
1008 return 0; 1016 return 0;
1009 } 1017 }
1010 1018
1011 /* Now, find out what the pre-calculated value is. */ 1019 /* Now, find out what the pre-calculated value is. */
1012 assoc = assq_no_quit(tag, 1020 assoc = assq_no_quit (tag, tag_list);
1013 XVECTOR_DATA(Vcharset_tag_lists) 1021
1014 [XCHARSET_LEADING_BYTE(charset) 1022 if (!(NILP (assoc)))
1015 - MIN_LEADING_BYTE]); 1023 {
1016 1024 assert (VECTORP (XCDR (assoc)));
1017 if (!(NILP(assoc)) && !(NILP(XCDR(assoc))))
1018 {
1019 assert(VECTORP(XCDR(assoc)));
1020 1025
1021 /* In the event that a tag specifies a charset, then the specifier 1026 /* In the event that a tag specifies a charset, then the specifier
1022 must match for (this stage and this charset) for all 1027 must match for (this stage and this charset) for all
1023 charset-specifying tags. */ 1028 charset-specifying tags. */
1024 if (NILP(XVECTOR_DATA(XCDR(assoc))[stage])) 1029 if (NILP (XVECTOR_DATA (XCDR (assoc))[stage]))
1025 { 1030 {
1026 /* It doesn't match for this tag, even though the tag 1031 /* It doesn't match for this tag, even though the tag
1027 specifies a charset. Return 0. */ 1032 specifies a charset. Return 0. */
1028 return 0; 1033 return 0;
1029 } 1034 }
1057 invalid_argument ("Invalid tag set", tag_set); 1062 invalid_argument ("Invalid tag set", tag_set);
1058 1063
1059 return device_matches_specifier_tag_set_p (device, tag_set) ? Qt : Qnil; 1064 return device_matches_specifier_tag_set_p (device, tag_set) ? Qt : Qnil;
1060 } 1065 }
1061 1066
1067 /* Call CHARSET_PREDICATE on CHARSET, evaluating it at both stages (initial
1068 and final) and returning a size-two vector of the results. */
1069
1070 static Lisp_Object
1071 call_charset_predicate (Lisp_Object charset_predicate, Lisp_Object charset)
1072 {
1073 struct gcpro gcpro1;
1074 Lisp_Object charpres = make_vector (NUM_MATCHSPEC_STAGES, Qnil);
1075 GCPRO1 (charpres);
1076 int max_args = XINT (Ffunction_max_args (charset_predicate));
1077
1078
1079 #define DEFINE_SPECIFIER_TAG_FROB(stage, enumstage) \
1080 do { \
1081 if (max_args > 1) \
1082 { \
1083 XVECTOR_DATA (charpres)[enumstage] = \
1084 call2_trapping_problems \
1085 ("Error during specifier tag charset predicate," \
1086 " stage " #stage, charset_predicate, \
1087 charset, Q##stage, 0); \
1088 } \
1089 else \
1090 { \
1091 XVECTOR_DATA (charpres)[enumstage] = \
1092 call1_trapping_problems \
1093 ("Error during specifier tag charset predicate," \
1094 " stage " #stage, charset_predicate, \
1095 charset, 0); \
1096 } \
1097 \
1098 if (UNBOUNDP (XVECTOR_DATA (charpres)[enumstage])) \
1099 { \
1100 XVECTOR_DATA (charpres)[enumstage] = Qnil; \
1101 } \
1102 else if (!NILP (XVECTOR_DATA (charpres)[enumstage])) \
1103 { \
1104 /* Don't want refs to random other objects. */ \
1105 XVECTOR_DATA (charpres)[enumstage] = Qt; \
1106 } \
1107 } while (0)
1108
1109 DEFINE_SPECIFIER_TAG_FROB (initial, STAGE_INITIAL);
1110 DEFINE_SPECIFIER_TAG_FROB (final, STAGE_FINAL);
1111
1112 #undef DEFINE_SPECIFIER_TAG_FROB
1113
1114 UNGCPRO;
1115
1116 return charpres;
1117 }
1118
1062 Lisp_Object 1119 Lisp_Object
1063 define_specifier_tag(Lisp_Object tag, Lisp_Object device_predicate, 1120 define_specifier_tag (Lisp_Object tag, Lisp_Object device_predicate,
1064 Lisp_Object charset_predicate) 1121 Lisp_Object charset_predicate)
1065 { 1122 {
1066 Lisp_Object assoc = assq_no_quit (tag, Vuser_defined_tags), 1123 Lisp_Object assoc = assq_no_quit (tag, Vuser_defined_tags),
1067 concons, devcons, charpres = Qnil; 1124 concons, devcons;
1068 int recompute_devices = 0, recompute_charsets = 0, i, max_args = -1; 1125 int recompute_devices = 0, recompute_charsets = 0;
1069 1126
1070 if (NILP (assoc)) 1127 if (NILP (assoc))
1071 { 1128 {
1072 recompute_devices = recompute_charsets = 1; 1129 recompute_devices = recompute_charsets = 1;
1073 Vuser_defined_tags = Fcons (list3 (tag, device_predicate, 1130 Vuser_defined_tags = Fcons (list3 (tag, device_predicate,
1079 /* Initially set the value to t in case of error 1136 /* Initially set the value to t in case of error
1080 in device_predicate */ 1137 in device_predicate */
1081 DEVICE_USER_DEFINED_TAGS (d) = 1138 DEVICE_USER_DEFINED_TAGS (d) =
1082 Fcons (Fcons (tag, Qt), DEVICE_USER_DEFINED_TAGS (d)); 1139 Fcons (Fcons (tag, Qt), DEVICE_USER_DEFINED_TAGS (d));
1083 } 1140 }
1084
1085 if (!NILP (charset_predicate))
1086 {
1087 max_args = XINT(Ffunction_max_args(charset_predicate));
1088 if (max_args < 1)
1089 {
1090 invalid_argument
1091 ("Charset predicate must be able to take an argument", tag);
1092 }
1093 }
1094 } 1141 }
1095 else if (!NILP (device_predicate) && !NILP (XCADR (assoc))) 1142 else if (!NILP (device_predicate) && !NILP (XCADR (assoc)))
1096 { 1143 {
1097 recompute_devices = 1; 1144 recompute_devices = 1;
1098 XCDR (assoc) = list2(device_predicate, charset_predicate); 1145 XCDR (assoc) = list2 (device_predicate, charset_predicate);
1099 } 1146 }
1100 else if (!NILP (charset_predicate) || !NILP(XCADDR (assoc))) 1147 else if (!NILP (charset_predicate) || !NILP (XCADDR (assoc)))
1101 { 1148 {
1102 max_args = XINT(Ffunction_max_args(charset_predicate));
1103 if (max_args < 1)
1104 {
1105 invalid_argument
1106 ("Charset predicate must be able to take an argument", tag);
1107 }
1108
1109 /* If there exists a charset_predicate for the tag currently (even if 1149 /* If there exists a charset_predicate for the tag currently (even if
1110 the new charset_predicate is nil), or if we're adding one, we need 1150 the new charset_predicate is nil), or if we're adding one, we need
1111 to recompute. This contrasts with the device predicates, where we 1151 to recompute. This contrasts with the device predicates, where we
1112 don't need to recompute if the old and new device predicates are 1152 don't need to recompute if the old and new device predicates are
1113 both nil. */ 1153 both nil. */
1114 1154
1115 recompute_charsets = 1; 1155 recompute_charsets = 1;
1116 XCDR (assoc) = list2(device_predicate, charset_predicate); 1156 XCDR (assoc) = list2 (device_predicate, charset_predicate);
1117 } 1157 }
1118 1158
1119 /* Recompute the tag values for all devices and charsets, if necessary. In 1159 /* Recompute the tag values for all devices and charsets, if necessary. In
1120 the special case where both the old and new device_predicates are nil, 1160 the special case where both the old and new device_predicates are nil,
1121 we know that we don't have to do it for the device. (It's probably 1161 we know that we don't have to do it for the device. (It's probably
1139 } 1179 }
1140 } 1180 }
1141 1181
1142 if (recompute_charsets) 1182 if (recompute_charsets)
1143 { 1183 {
1144 if (NILP(charset_predicate)) 1184
1145 { 1185 LIST_LOOP_2 (charset_name, Fcharset_list ())
1146 charpres = Qnil; 1186 {
1147 } 1187 Lisp_Object charset = Fget_charset (charset_name);
1148 1188 Lisp_Object tag_list = Fgethash (charset, Vcharset_tag_lists, Qnil);
1149 for (i = 0; i < NUM_LEADING_BYTES; ++i) 1189 Lisp_Object charpres;
1150 { 1190
1151 if (NILP(charset_by_leading_byte(MIN_LEADING_BYTE + i))) 1191 if (NILP (charset_predicate))
1192 continue;
1193
1194 charpres = call_charset_predicate (charset_predicate, charset);
1195
1196 assoc = assq_no_quit (tag, tag_list);
1197 if (!NILP (assoc))
1152 { 1198 {
1153 continue; 1199 assert (CONSP (assoc));
1154 }
1155
1156 assoc = assq_no_quit (tag,
1157 XVECTOR_DATA(Vcharset_tag_lists)[i]);
1158
1159 if (!NILP(charset_predicate))
1160 {
1161 struct gcpro gcpro1;
1162 charpres = make_vector(impossible, Qnil);
1163 GCPRO1 (charpres);
1164
1165 /* If you want to extend the number of stages available, here
1166 in setup_charset_initial_specifier_tags, and in specifier.h
1167 is where you want to go. */
1168
1169 #define DEFINE_SPECIFIER_TAG_FROB(stage) do { \
1170 if (max_args > 1) \
1171 { \
1172 XVECTOR_DATA(charpres)[stage] = \
1173 call2_trapping_problems \
1174 ("Error during specifier tag charset predicate," \
1175 " stage " #stage, charset_predicate, \
1176 charset_by_leading_byte(MIN_LEADING_BYTE + i), \
1177 Q##stage, 0); \
1178 } \
1179 else \
1180 { \
1181 XVECTOR_DATA(charpres)[stage] = \
1182 call1_trapping_problems \
1183 ("Error during specifier tag charset predicate," \
1184 " stage " #stage, charset_predicate, \
1185 charset_by_leading_byte(MIN_LEADING_BYTE + i), \
1186 0); \
1187 } \
1188 \
1189 if (UNBOUNDP(XVECTOR_DATA(charpres)[stage])) \
1190 { \
1191 XVECTOR_DATA(charpres)[stage] = Qnil; \
1192 } \
1193 else if (!NILP(XVECTOR_DATA(charpres)[stage])) \
1194 { \
1195 /* Don't want refs to random other objects. */ \
1196 XVECTOR_DATA(charpres)[stage] = Qt; \
1197 } \
1198 } while (0)
1199
1200 DEFINE_SPECIFIER_TAG_FROB (initial);
1201 DEFINE_SPECIFIER_TAG_FROB (final);
1202
1203 #undef DEFINE_SPECIFIER_TAG_FROB
1204
1205 UNGCPRO;
1206 }
1207
1208 if (!NILP(assoc))
1209 {
1210 assert(CONSP(assoc));
1211 XCDR (assoc) = charpres; 1200 XCDR (assoc) = charpres;
1212 } 1201 }
1213 else 1202 else
1214 { 1203 {
1215 XVECTOR_DATA(Vcharset_tag_lists)[i] 1204 Fputhash (charset, Fcons (Fcons (tag, charpres), tag_list),
1216 = Fcons(Fcons(tag, charpres), 1205 Vcharset_tag_lists);
1217 XVECTOR_DATA (Vcharset_tag_lists)[i]);
1218 } 1206 }
1219 } 1207 }
1220 } 1208 }
1221 return Qt; 1209 return Qt;
1222 } 1210 }
1257 available as a built-in specifier tag; this is probably something we should 1245 available as a built-in specifier tag; this is probably something we should
1258 change. 1246 change.
1259 */ 1247 */
1260 (tag, device_predicate, charset_predicate)) 1248 (tag, device_predicate, charset_predicate))
1261 { 1249 {
1262 int max_args;
1263
1264 CHECK_SYMBOL (tag); 1250 CHECK_SYMBOL (tag);
1265 if (valid_device_class_p (tag) || 1251 if (valid_device_class_p (tag) ||
1266 valid_console_type_p (tag) || 1252 valid_console_type_p (tag) ||
1267 EQ (tag, Qinitial) || EQ (tag, Qfinal)) 1253 EQ (tag, Qinitial) || EQ (tag, Qfinal))
1268 invalid_change ("Cannot redefine built-in specifier tags", tag); 1254 invalid_change ("Cannot redefine built-in specifier tags", tag);
1271 if (NILP (tag) || EQ (tag, Qt) || EQ (tag, Qall) || EQ (tag, Qglobal)) 1257 if (NILP (tag) || EQ (tag, Qt) || EQ (tag, Qall) || EQ (tag, Qglobal))
1272 invalid_change ("Cannot define nil, t, `all', or `global'", tag); 1258 invalid_change ("Cannot define nil, t, `all', or `global'", tag);
1273 1259
1274 if (!NILP (charset_predicate)) 1260 if (!NILP (charset_predicate))
1275 { 1261 {
1276 max_args = XINT(Ffunction_max_args(charset_predicate)); 1262 Lisp_Object min_args = Ffunction_min_args (charset_predicate);
1277 if (max_args != 1) 1263 Lisp_Object max_args = Ffunction_max_args (charset_predicate);
1264 if (!(INTP (min_args) && XINT (min_args) == 1 &&
1265 INTP (max_args) && XINT (max_args) == 1))
1278 { 1266 {
1279 /* We only allow the stage argument to be specifed from C. */ 1267 /* We only allow the stage argument to be specifed from C. */
1280 invalid_change ("Charset predicate must take one argument", 1268 invalid_change ("Charset predicate must take one argument",
1281 tag); 1269 tag);
1282 } 1270 }
1331 Lisp_Object rest, charset_predicate, tag, new_value; 1319 Lisp_Object rest, charset_predicate, tag, new_value;
1332 Lisp_Object charset_tag_list = Qnil; 1320 Lisp_Object charset_tag_list = Qnil;
1333 1321
1334 LIST_LOOP (rest, Vuser_defined_tags) 1322 LIST_LOOP (rest, Vuser_defined_tags)
1335 { 1323 {
1336 tag = XCAR(XCAR(rest)); 1324 tag = XCAR (XCAR (rest));
1337 charset_predicate = XCADDR(XCAR (rest)); 1325 charset_predicate = XCADDR (XCAR (rest));
1338 1326
1339 if (NILP(charset_predicate)) 1327 if (NILP (charset_predicate))
1340 { 1328 {
1341 continue; 1329 continue;
1342 } 1330 }
1343 1331
1344 new_value = make_vector(impossible, Qnil); 1332 new_value = call_charset_predicate (charset_predicate, charset);
1345 1333 charset_tag_list = Fcons (Fcons (tag, new_value), charset_tag_list);
1346 #define SETUP_CHARSET_TAGS_FROB(stage) do { \ 1334 }
1347 \ 1335
1348 XVECTOR_DATA(new_value)[stage] = call2_trapping_problems \ 1336 Fputhash (charset, charset_tag_list, Vcharset_tag_lists);
1349 ("Error during specifier tag charset predicate," \
1350 " stage " #stage, \
1351 charset_predicate, charset, Q##stage, 0); \
1352 \
1353 if (UNBOUNDP(XVECTOR_DATA(new_value)[stage])) \
1354 { \
1355 XVECTOR_DATA(new_value)[stage] = Qnil; \
1356 } \
1357 else if (!NILP(XVECTOR_DATA(new_value)[stage])) \
1358 { \
1359 /* Don't want random other objects hanging around. */ \
1360 XVECTOR_DATA(new_value)[stage] = Qt; \
1361 } \
1362 \
1363 } while (0)
1364
1365 SETUP_CHARSET_TAGS_FROB (initial);
1366 SETUP_CHARSET_TAGS_FROB (final);
1367 /* More later? */
1368
1369 #undef SETUP_CHARSET_TAGS_FROB
1370
1371 charset_tag_list = Fcons(Fcons(tag, new_value), charset_tag_list);
1372 }
1373
1374 XVECTOR_DATA
1375 (Vcharset_tag_lists)[XCHARSET_LEADING_BYTE(charset) - MIN_LEADING_BYTE]
1376 = charset_tag_list;
1377 } 1337 }
1378 1338
1379 /* VM calls this, in vm-multiple-frames-possible-p, in the event that you're 1339 /* VM calls this, in vm-multiple-frames-possible-p, in the event that you're
1380 considering taking it out. */ 1340 considering taking it out. */
1381 1341
2810 /* This function can GC */ 2770 /* This function can GC */
2811 Lisp_Specifier *sp; 2771 Lisp_Specifier *sp;
2812 Lisp_Object device, charset = Qnil, rest; 2772 Lisp_Object device, charset = Qnil, rest;
2813 int count = specpdl_depth (), respected_charsets = 0; 2773 int count = specpdl_depth (), respected_charsets = 0;
2814 struct gcpro gcpro1, gcpro2; 2774 struct gcpro gcpro1, gcpro2;
2815 enum font_specifier_matchspec_stages stage = initial; 2775 enum font_specifier_matchspec_stages stage = STAGE_INITIAL;
2816 2776
2817 GCPRO2 (specifier, inst_list); 2777 GCPRO2 (specifier, inst_list);
2818 2778
2819 sp = XSPECIFIER (specifier); 2779 sp = XSPECIFIER (specifier);
2820 device = DOMAIN_DEVICE (domain); 2780 device = DOMAIN_DEVICE (domain);
2827 specbind (Qinhibit_quit, Qt); 2787 specbind (Qinhibit_quit, Qt);
2828 2788
2829 #ifdef MULE 2789 #ifdef MULE
2830 /* #### FIXME Does this font-specific stuff need to be here and not in 2790 /* #### FIXME Does this font-specific stuff need to be here and not in
2831 the font-specifier-specific code? --ben */ 2791 the font-specifier-specific code? --ben */
2832 if (CONSP(matchspec) && (CHARSETP(Ffind_charset(XCAR(matchspec))))) 2792 if (CONSP (matchspec) && (CHARSETP (Ffind_charset (XCAR (matchspec)))))
2833 { 2793 {
2834 charset = Ffind_charset(XCAR(matchspec)); 2794 charset = Ffind_charset (XCAR (matchspec));
2835 2795
2836 #ifdef DEBUG_XEMACS 2796 #ifdef DEBUG_XEMACS
2837 /* This is mostly to have somewhere to set debug breakpoints. */ 2797 /* This is mostly to have somewhere to set debug breakpoints. */
2838 if (!EQ (charset, Vcharset_ascii)) 2798 if (!EQ (charset, Vcharset_ascii))
2839 { 2799 {
2840 (void) 0; 2800 (void) 0;
2841 } 2801 }
2842 #endif /* DEBUG_XEMACS */ 2802 #endif /* DEBUG_XEMACS */
2843 2803
2844 if (!NILP(XCDR(matchspec))) 2804 if (!NILP (XCDR (matchspec)))
2845 { 2805 {
2846 2806
2847 #define FROB(new_stage) if (EQ(Q##new_stage, XCDR(matchspec))) \ 2807 #define FROB(new_stage, enumstage) \
2848 { \ 2808 if (EQ (Q##new_stage, XCDR (matchspec))) \
2849 stage = new_stage; \ 2809 { \
2810 stage = enumstage; \
2850 } 2811 }
2851 2812
2852 FROB(initial) 2813 FROB (initial, STAGE_INITIAL)
2853 else FROB(final) 2814 else FROB (final, STAGE_FINAL)
2854 else assert(0); 2815 else assert(0);
2855 #undef FROB 2816 #undef FROB
2856 2817
2857 } 2818 }
2858 } 2819 }
3921 staticpro (&Vuser_defined_tags); 3882 staticpro (&Vuser_defined_tags);
3922 3883
3923 Vunlock_ghost_specifiers = Qnil; 3884 Vunlock_ghost_specifiers = Qnil;
3924 staticpro (&Vunlock_ghost_specifiers); 3885 staticpro (&Vunlock_ghost_specifiers);
3925 3886
3926 Vcharset_tag_lists = make_vector(NUM_LEADING_BYTES, Qnil); 3887 Vcharset_tag_lists =
3888 make_lisp_hash_table (50, HASH_TABLE_NON_WEAK, HASH_TABLE_EQ);
3927 staticpro (&Vcharset_tag_lists); 3889 staticpro (&Vcharset_tag_lists);
3928 } 3890 }