Mercurial > hg > xemacs-beta
comparison src/specifier.c @ 398:74fd4e045ea6 r21-2-29
Import from CVS: tag r21-2-29
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:13:30 +0200 |
parents | bbff43aa5eb7 |
children | a86b2b5e0111 |
comparison
equal
deleted
inserted
replaced
397:f4aeb21a5bad | 398:74fd4e045ea6 |
---|---|
62 typedef struct | 62 typedef struct |
63 { | 63 { |
64 Dynarr_declare (specifier_type_entry); | 64 Dynarr_declare (specifier_type_entry); |
65 } specifier_type_entry_dynarr; | 65 } specifier_type_entry_dynarr; |
66 | 66 |
67 specifier_type_entry_dynarr *the_specifier_type_entry_dynarr; | 67 static specifier_type_entry_dynarr *the_specifier_type_entry_dynarr; |
68 | |
69 static const struct lrecord_description ste_description_1[] = { | |
70 { XD_LISP_OBJECT, offsetof (specifier_type_entry, symbol) }, | |
71 { XD_STRUCT_PTR, offsetof (specifier_type_entry, meths), 1, &specifier_methods_description }, | |
72 { XD_END } | |
73 }; | |
74 | |
75 static const struct struct_description ste_description = { | |
76 sizeof (specifier_type_entry), | |
77 ste_description_1 | |
78 }; | |
79 | |
80 static const struct lrecord_description sted_description_1[] = { | |
81 XD_DYNARR_DESC (specifier_type_entry_dynarr, &ste_description), | |
82 { XD_END } | |
83 }; | |
84 | |
85 static const struct struct_description sted_description = { | |
86 sizeof (specifier_type_entry_dynarr), | |
87 sted_description_1 | |
88 }; | |
68 | 89 |
69 static Lisp_Object Vspecifier_type_list; | 90 static Lisp_Object Vspecifier_type_list; |
70 | 91 |
71 static Lisp_Object Vcached_specifiers; | 92 static Lisp_Object Vcached_specifiers; |
72 /* Do NOT mark through this, or specifiers will never be GC'd. */ | 93 /* Do NOT mark through this, or specifiers will never be GC'd. */ |
139 | 160 |
140 for (rest = Vall_specifiers; | 161 for (rest = Vall_specifiers; |
141 !NILP (rest); | 162 !NILP (rest); |
142 rest = XSPECIFIER (rest)->next_specifier) | 163 rest = XSPECIFIER (rest)->next_specifier) |
143 { | 164 { |
144 struct Lisp_Specifier *sp = XSPECIFIER (rest); | 165 Lisp_Specifier *sp = XSPECIFIER (rest); |
145 /* This effectively changes the specifier specs. | 166 /* This effectively changes the specifier specs. |
146 However, there's no need to call | 167 However, there's no need to call |
147 recompute_cached_specifier_everywhere() or the | 168 recompute_cached_specifier_everywhere() or the |
148 after-change methods because the only specs we | 169 after-change methods because the only specs we |
149 are removing are for dead objects, and they can | 170 are removing are for dead objects, and they can |
166 | 187 |
167 for (rest = Vall_specifiers; | 188 for (rest = Vall_specifiers; |
168 !NILP (rest); | 189 !NILP (rest); |
169 rest = XSPECIFIER (rest)->next_specifier) | 190 rest = XSPECIFIER (rest)->next_specifier) |
170 { | 191 { |
171 struct Lisp_Specifier *sp = XSPECIFIER (rest); | 192 Lisp_Specifier *sp = XSPECIFIER (rest); |
172 | 193 |
173 /* Make sure we're actually going to be changing something. | 194 /* Make sure we're actually going to be changing something. |
174 Fremove_specifier() always calls | 195 Fremove_specifier() always calls |
175 recompute_cached_specifier_everywhere() (#### but should | 196 recompute_cached_specifier_everywhere() (#### but should |
176 be smarter about this). */ | 197 be smarter about this). */ |
178 Fremove_specifier (rest, buffer, Qnil, Qnil); | 199 Fremove_specifier (rest, buffer, Qnil, Qnil); |
179 } | 200 } |
180 } | 201 } |
181 | 202 |
182 static Lisp_Object | 203 static Lisp_Object |
183 mark_specifier (Lisp_Object obj, void (*markobj) (Lisp_Object)) | 204 mark_specifier (Lisp_Object obj) |
184 { | 205 { |
185 struct Lisp_Specifier *specifier = XSPECIFIER (obj); | 206 Lisp_Specifier *specifier = XSPECIFIER (obj); |
186 | 207 |
187 markobj (specifier->global_specs); | 208 mark_object (specifier->global_specs); |
188 markobj (specifier->device_specs); | 209 mark_object (specifier->device_specs); |
189 markobj (specifier->frame_specs); | 210 mark_object (specifier->frame_specs); |
190 markobj (specifier->window_specs); | 211 mark_object (specifier->window_specs); |
191 markobj (specifier->buffer_specs); | 212 mark_object (specifier->buffer_specs); |
192 markobj (specifier->magic_parent); | 213 mark_object (specifier->magic_parent); |
193 markobj (specifier->fallback); | 214 mark_object (specifier->fallback); |
194 if (!GHOST_SPECIFIER_P (XSPECIFIER (obj))) | 215 if (!GHOST_SPECIFIER_P (XSPECIFIER (obj))) |
195 MAYBE_SPECMETH (specifier, mark, (obj, markobj)); | 216 MAYBE_SPECMETH (specifier, mark, (obj)); |
196 return Qnil; | 217 return Qnil; |
197 } | 218 } |
198 | 219 |
199 /* The idea here is that the specifier specs point to locales | 220 /* The idea here is that the specifier specs point to locales |
200 (windows, buffers, frames, and devices), and we want to make sure | 221 (windows, buffers, frames, and devices), and we want to make sure |
214 We now use weak lists for this purpose. | 235 We now use weak lists for this purpose. |
215 | 236 |
216 */ | 237 */ |
217 | 238 |
218 void | 239 void |
219 prune_specifiers (int (*obj_marked_p) (Lisp_Object)) | 240 prune_specifiers (void) |
220 { | 241 { |
221 Lisp_Object rest, prev = Qnil; | 242 Lisp_Object rest, prev = Qnil; |
222 | 243 |
223 for (rest = Vall_specifiers; | 244 for (rest = Vall_specifiers; |
224 !GC_NILP (rest); | 245 !NILP (rest); |
225 rest = XSPECIFIER (rest)->next_specifier) | 246 rest = XSPECIFIER (rest)->next_specifier) |
226 { | 247 { |
227 if (! obj_marked_p (rest)) | 248 if (! marked_p (rest)) |
228 { | 249 { |
229 struct Lisp_Specifier* sp = XSPECIFIER (rest); | 250 Lisp_Specifier* sp = XSPECIFIER (rest); |
230 /* A bit of assertion that we're removing both parts of the | 251 /* A bit of assertion that we're removing both parts of the |
231 magic one altogether */ | 252 magic one altogether */ |
232 assert (!GC_MAGIC_SPECIFIER_P(sp) | 253 assert (!MAGIC_SPECIFIER_P(sp) |
233 || (GC_BODILY_SPECIFIER_P(sp) && obj_marked_p (sp->fallback)) | 254 || (BODILY_SPECIFIER_P(sp) && marked_p (sp->fallback)) |
234 || (GC_GHOST_SPECIFIER_P(sp) && obj_marked_p (sp->magic_parent))); | 255 || (GHOST_SPECIFIER_P(sp) && marked_p (sp->magic_parent))); |
235 /* This specifier is garbage. Remove it from the list. */ | 256 /* This specifier is garbage. Remove it from the list. */ |
236 if (GC_NILP (prev)) | 257 if (NILP (prev)) |
237 Vall_specifiers = sp->next_specifier; | 258 Vall_specifiers = sp->next_specifier; |
238 else | 259 else |
239 XSPECIFIER (prev)->next_specifier = sp->next_specifier; | 260 XSPECIFIER (prev)->next_specifier = sp->next_specifier; |
240 } | 261 } |
241 else | 262 else |
244 } | 265 } |
245 | 266 |
246 static void | 267 static void |
247 print_specifier (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | 268 print_specifier (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) |
248 { | 269 { |
249 struct Lisp_Specifier *sp = XSPECIFIER (obj); | 270 Lisp_Specifier *sp = XSPECIFIER (obj); |
250 char buf[100]; | 271 char buf[100]; |
251 int count = specpdl_depth (); | 272 int count = specpdl_depth (); |
252 Lisp_Object the_specs; | 273 Lisp_Object the_specs; |
253 | 274 |
254 if (print_readably) | 275 if (print_readably) |
276 } | 297 } |
277 | 298 |
278 static void | 299 static void |
279 finalize_specifier (void *header, int for_disksave) | 300 finalize_specifier (void *header, int for_disksave) |
280 { | 301 { |
281 struct Lisp_Specifier *sp = (struct Lisp_Specifier *) header; | 302 Lisp_Specifier *sp = (Lisp_Specifier *) header; |
282 /* don't be snafued by the disksave finalization. */ | 303 /* don't be snafued by the disksave finalization. */ |
283 if (!for_disksave && !GC_GHOST_SPECIFIER_P(sp) && sp->caching) | 304 if (!for_disksave && !GHOST_SPECIFIER_P(sp) && sp->caching) |
284 { | 305 { |
285 xfree (sp->caching); | 306 xfree (sp->caching); |
286 sp->caching = 0; | 307 sp->caching = 0; |
287 } | 308 } |
288 } | 309 } |
289 | 310 |
290 static int | 311 static int |
291 specifier_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) | 312 specifier_equal (Lisp_Object obj1, Lisp_Object obj2, int depth) |
292 { | 313 { |
293 struct Lisp_Specifier *s1 = XSPECIFIER (obj1); | 314 Lisp_Specifier *s1 = XSPECIFIER (obj1); |
294 struct Lisp_Specifier *s2 = XSPECIFIER (obj2); | 315 Lisp_Specifier *s2 = XSPECIFIER (obj2); |
295 int retval; | 316 int retval; |
296 Lisp_Object old_inhibit_quit = Vinhibit_quit; | 317 Lisp_Object old_inhibit_quit = Vinhibit_quit; |
297 | 318 |
298 /* This function can be called from within redisplay. | 319 /* This function can be called from within redisplay. |
299 internal_equal can trigger a quit. That leads to Bad Things. */ | 320 internal_equal can trigger a quit. That leads to Bad Things. */ |
317 } | 338 } |
318 | 339 |
319 static unsigned long | 340 static unsigned long |
320 specifier_hash (Lisp_Object obj, int depth) | 341 specifier_hash (Lisp_Object obj, int depth) |
321 { | 342 { |
322 struct Lisp_Specifier *s = XSPECIFIER (obj); | 343 Lisp_Specifier *s = XSPECIFIER (obj); |
323 | 344 |
324 /* specifier hashing is a bit problematic because there are so | 345 /* specifier hashing is a bit problematic because there are so |
325 many places where data can be stored. We pick what are perhaps | 346 many places where data can be stored. We pick what are perhaps |
326 the most likely places where interesting stuff will be. */ | 347 the most likely places where interesting stuff will be. */ |
327 return HASH5 ((HAS_SPECMETH_P (s, hash) ? | 348 return HASH5 ((HAS_SPECMETH_P (s, hash) ? |
331 internal_hash (s->frame_specs, depth + 1), | 352 internal_hash (s->frame_specs, depth + 1), |
332 internal_hash (s->buffer_specs, depth + 1)); | 353 internal_hash (s->buffer_specs, depth + 1)); |
333 } | 354 } |
334 | 355 |
335 static size_t | 356 static size_t |
336 sizeof_specifier (CONST void *header) | 357 sizeof_specifier (const void *header) |
337 { | 358 { |
338 if (GHOST_SPECIFIER_P ((struct Lisp_Specifier *) header)) | 359 if (GHOST_SPECIFIER_P ((Lisp_Specifier *) header)) |
339 return sizeof (struct Lisp_Specifier); | 360 return offsetof (Lisp_Specifier, data); |
340 else | 361 else |
341 { | 362 { |
342 CONST struct Lisp_Specifier *p = (CONST struct Lisp_Specifier *) header; | 363 const Lisp_Specifier *p = (const Lisp_Specifier *) header; |
343 return sizeof (*p) + p->methods->extra_data_size - 1; | 364 return offsetof (Lisp_Specifier, data) + p->methods->extra_data_size; |
344 } | 365 } |
345 } | 366 } |
367 | |
368 static const struct lrecord_description specifier_methods_description_1[] = { | |
369 { XD_LISP_OBJECT, offsetof (struct specifier_methods, predicate_symbol) }, | |
370 { XD_END } | |
371 }; | |
372 | |
373 const struct struct_description specifier_methods_description = { | |
374 sizeof (struct specifier_methods), | |
375 specifier_methods_description_1 | |
376 }; | |
377 | |
378 static const struct lrecord_description specifier_caching_description_1[] = { | |
379 { XD_END } | |
380 }; | |
381 | |
382 static const struct struct_description specifier_caching_description = { | |
383 sizeof (struct specifier_caching), | |
384 specifier_caching_description_1 | |
385 }; | |
386 | |
387 static const struct lrecord_description specifier_description[] = { | |
388 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, methods), 1, &specifier_methods_description }, | |
389 { XD_LO_LINK, offsetof (Lisp_Specifier, next_specifier) }, | |
390 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, global_specs) }, | |
391 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, device_specs) }, | |
392 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, frame_specs) }, | |
393 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, window_specs) }, | |
394 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, buffer_specs) }, | |
395 { XD_STRUCT_PTR, offsetof (Lisp_Specifier, caching), 1, &specifier_caching_description }, | |
396 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, magic_parent) }, | |
397 { XD_LISP_OBJECT, offsetof (Lisp_Specifier, fallback) }, | |
398 { XD_SPECIFIER_END } | |
399 }; | |
400 | |
401 const struct lrecord_description specifier_empty_extra_description[] = { | |
402 { XD_END } | |
403 }; | |
346 | 404 |
347 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier, | 405 DEFINE_LRECORD_SEQUENCE_IMPLEMENTATION ("specifier", specifier, |
348 mark_specifier, print_specifier, | 406 mark_specifier, print_specifier, |
349 finalize_specifier, | 407 finalize_specifier, |
350 specifier_equal, specifier_hash, | 408 specifier_equal, specifier_hash, |
409 specifier_description, | |
351 sizeof_specifier, | 410 sizeof_specifier, |
352 struct Lisp_Specifier); | 411 Lisp_Specifier); |
353 | 412 |
354 /************************************************************************/ | 413 /************************************************************************/ |
355 /* Creating specifiers */ | 414 /* Creating specifiers */ |
356 /************************************************************************/ | 415 /************************************************************************/ |
357 | 416 |
411 static Lisp_Object | 470 static Lisp_Object |
412 make_specifier_internal (struct specifier_methods *spec_meths, | 471 make_specifier_internal (struct specifier_methods *spec_meths, |
413 size_t data_size, int call_create_meth) | 472 size_t data_size, int call_create_meth) |
414 { | 473 { |
415 Lisp_Object specifier; | 474 Lisp_Object specifier; |
416 struct Lisp_Specifier *sp = (struct Lisp_Specifier *) | 475 Lisp_Specifier *sp = (Lisp_Specifier *) |
417 alloc_lcrecord (sizeof (struct Lisp_Specifier) + | 476 alloc_lcrecord (offsetof (Lisp_Specifier, data) + data_size, |
418 data_size - 1, lrecord_specifier); | 477 &lrecord_specifier); |
419 | 478 |
420 sp->methods = spec_meths; | 479 sp->methods = spec_meths; |
421 sp->global_specs = Qnil; | 480 sp->global_specs = Qnil; |
422 sp->device_specs = Qnil; | 481 sp->device_specs = Qnil; |
423 sp->frame_specs = Qnil; | 482 sp->frame_specs = Qnil; |
1585 build_up_processed_list (Lisp_Object specifier, Lisp_Object locale, | 1644 build_up_processed_list (Lisp_Object specifier, Lisp_Object locale, |
1586 Lisp_Object inst_list) | 1645 Lisp_Object inst_list) |
1587 { | 1646 { |
1588 /* The return value of this function must be GCPRO'd. */ | 1647 /* The return value of this function must be GCPRO'd. */ |
1589 Lisp_Object rest, list_to_build_up = Qnil; | 1648 Lisp_Object rest, list_to_build_up = Qnil; |
1590 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 1649 Lisp_Specifier *sp = XSPECIFIER (specifier); |
1591 struct gcpro gcpro1; | 1650 struct gcpro gcpro1; |
1592 | 1651 |
1593 GCPRO1 (list_to_build_up); | 1652 GCPRO1 (list_to_build_up); |
1594 LIST_LOOP (rest, inst_list) | 1653 LIST_LOOP (rest, inst_list) |
1595 { | 1654 { |
1596 Lisp_Object tag_set = XCAR (XCAR (rest)); | 1655 Lisp_Object tag_set = XCAR (XCAR (rest)); |
1597 Lisp_Object instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt); | |
1598 Lisp_Object sub_inst_list = Qnil; | 1656 Lisp_Object sub_inst_list = Qnil; |
1657 Lisp_Object instantiator; | |
1599 struct gcpro ngcpro1, ngcpro2; | 1658 struct gcpro ngcpro1, ngcpro2; |
1659 | |
1660 if (HAS_SPECMETH_P (sp, copy_instantiator)) | |
1661 instantiator = SPECMETH (sp, copy_instantiator, | |
1662 (XCDR (XCAR (rest)))); | |
1663 else | |
1664 instantiator = Fcopy_tree (XCDR (XCAR (rest)), Qt); | |
1600 | 1665 |
1601 NGCPRO2 (instantiator, sub_inst_list); | 1666 NGCPRO2 (instantiator, sub_inst_list); |
1602 /* call the will-add method; it may GC */ | 1667 /* call the will-add method; it may GC */ |
1603 sub_inst_list = HAS_SPECMETH_P (sp, going_to_add) ? | 1668 sub_inst_list = HAS_SPECMETH_P (sp, going_to_add) ? |
1604 SPECMETH (sp, going_to_add, | 1669 SPECMETH (sp, going_to_add, |
1636 | 1701 |
1637 static void | 1702 static void |
1638 specifier_add_spec (Lisp_Object specifier, Lisp_Object locale, | 1703 specifier_add_spec (Lisp_Object specifier, Lisp_Object locale, |
1639 Lisp_Object inst_list, enum spec_add_meth add_meth) | 1704 Lisp_Object inst_list, enum spec_add_meth add_meth) |
1640 { | 1705 { |
1641 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 1706 Lisp_Specifier *sp = XSPECIFIER (specifier); |
1642 enum spec_locale_type type = locale_type_from_locale (locale); | 1707 enum spec_locale_type type = locale_type_from_locale (locale); |
1643 Lisp_Object *orig_inst_list, tem; | 1708 Lisp_Object *orig_inst_list, tem; |
1644 Lisp_Object list_to_build_up = Qnil; | 1709 Lisp_Object list_to_build_up = Qnil; |
1645 struct gcpro gcpro1; | 1710 struct gcpro gcpro1; |
1646 | 1711 |
2307 global value. */ | 2372 global value. */ |
2308 | 2373 |
2309 void | 2374 void |
2310 set_specifier_fallback (Lisp_Object specifier, Lisp_Object fallback) | 2375 set_specifier_fallback (Lisp_Object specifier, Lisp_Object fallback) |
2311 { | 2376 { |
2312 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 2377 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2313 assert (SPECIFIERP (fallback) || | 2378 assert (SPECIFIERP (fallback) || |
2314 !NILP (Fvalid_inst_list_p (fallback, Fspecifier_type (specifier)))); | 2379 !NILP (Fvalid_inst_list_p (fallback, Fspecifier_type (specifier)))); |
2315 if (SPECIFIERP (fallback)) | 2380 if (SPECIFIERP (fallback)) |
2316 assert (EQ (Fspecifier_type (specifier), Fspecifier_type (fallback))); | 2381 assert (EQ (Fspecifier_type (specifier), Fspecifier_type (fallback))); |
2317 if (BODILY_SPECIFIER_P (sp)) | 2382 if (BODILY_SPECIFIER_P (sp)) |
2357 Lisp_Object inst_list, | 2422 Lisp_Object inst_list, |
2358 Error_behavior errb, int no_quit, | 2423 Error_behavior errb, int no_quit, |
2359 Lisp_Object depth) | 2424 Lisp_Object depth) |
2360 { | 2425 { |
2361 /* This function can GC */ | 2426 /* This function can GC */ |
2362 struct Lisp_Specifier *sp; | 2427 Lisp_Specifier *sp; |
2363 Lisp_Object device; | 2428 Lisp_Object device; |
2364 Lisp_Object rest; | 2429 Lisp_Object rest; |
2365 int count = specpdl_depth (); | 2430 int count = specpdl_depth (); |
2366 struct gcpro gcpro1, gcpro2; | 2431 struct gcpro gcpro1, gcpro2; |
2367 | 2432 |
2440 Lisp_Object window = Qnil; | 2505 Lisp_Object window = Qnil; |
2441 Lisp_Object frame = Qnil; | 2506 Lisp_Object frame = Qnil; |
2442 Lisp_Object device = Qnil; | 2507 Lisp_Object device = Qnil; |
2443 Lisp_Object tag = Qnil; | 2508 Lisp_Object tag = Qnil; |
2444 struct device *d; | 2509 struct device *d; |
2445 struct Lisp_Specifier *sp; | 2510 Lisp_Specifier *sp; |
2446 | 2511 |
2447 sp = XSPECIFIER (specifier); | 2512 sp = XSPECIFIER (specifier); |
2448 | 2513 |
2449 /* Attempt to determine buffer, window, frame, and device from the | 2514 /* Attempt to determine buffer, window, frame, and device from the |
2450 domain. */ | 2515 domain. */ |
2483 from Lisp). */ | 2548 from Lisp). */ |
2484 depth = Qzero; | 2549 depth = Qzero; |
2485 goto do_fallback; | 2550 goto do_fallback; |
2486 } | 2551 } |
2487 | 2552 |
2488 retry: | 2553 retry: |
2489 /* First see if we can generate one from the window specifiers. */ | 2554 /* First see if we can generate one from the window specifiers. */ |
2490 if (!NILP (window)) | 2555 if (!NILP (window)) |
2491 CHECK_INSTANCE_ENTRY (window, matchspec, LOCALE_WINDOW); | 2556 CHECK_INSTANCE_ENTRY (window, matchspec, LOCALE_WINDOW); |
2492 | 2557 |
2493 /* Next see if we can generate one from the buffer specifiers. */ | 2558 /* Next see if we can generate one from the buffer specifiers. */ |
2502 CHECK_INSTANCE_ENTRY (device, matchspec, LOCALE_DEVICE); | 2567 CHECK_INSTANCE_ENTRY (device, matchspec, LOCALE_DEVICE); |
2503 | 2568 |
2504 /* Last and least try the global specifiers. */ | 2569 /* Last and least try the global specifiers. */ |
2505 CHECK_INSTANCE_ENTRY (Qglobal, matchspec, LOCALE_GLOBAL); | 2570 CHECK_INSTANCE_ENTRY (Qglobal, matchspec, LOCALE_GLOBAL); |
2506 | 2571 |
2507 do_fallback: | 2572 do_fallback: |
2508 /* We're out of specifiers and we still haven't generated an | 2573 /* We're out of specifiers and we still haven't generated an |
2509 instance. At least try the fallback ... If this fails, | 2574 instance. At least try the fallback ... If this fails, |
2510 then we just return Qunbound. */ | 2575 then we just return Qunbound. */ |
2511 | 2576 |
2512 if (no_fallback || NILP (sp->fallback)) | 2577 if (no_fallback || NILP (sp->fallback)) |
2643 you should not use this function; use `specifier-instance' instead. | 2708 you should not use this function; use `specifier-instance' instead. |
2644 */ | 2709 */ |
2645 (specifier, domain, inst_list, default_)) | 2710 (specifier, domain, inst_list, default_)) |
2646 { | 2711 { |
2647 Lisp_Object val = Qunbound; | 2712 Lisp_Object val = Qunbound; |
2648 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 2713 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2649 struct gcpro gcpro1; | 2714 struct gcpro gcpro1; |
2650 Lisp_Object built_up_list = Qnil; | 2715 Lisp_Object built_up_list = Qnil; |
2651 | 2716 |
2652 CHECK_SPECIFIER (specifier); | 2717 CHECK_SPECIFIER (specifier); |
2653 check_valid_domain (domain); | 2718 check_valid_domain (domain); |
2675 works. | 2740 works. |
2676 */ | 2741 */ |
2677 (specifier, matchspec, domain, inst_list, default_)) | 2742 (specifier, matchspec, domain, inst_list, default_)) |
2678 { | 2743 { |
2679 Lisp_Object val = Qunbound; | 2744 Lisp_Object val = Qunbound; |
2680 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 2745 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2681 struct gcpro gcpro1; | 2746 struct gcpro gcpro1; |
2682 Lisp_Object built_up_list = Qnil; | 2747 Lisp_Object built_up_list = Qnil; |
2683 | 2748 |
2684 CHECK_SPECIFIER (specifier); | 2749 CHECK_SPECIFIER (specifier); |
2685 check_valid_specifier_matchspec (matchspec, XSPECIFIER (specifier)->methods, | 2750 check_valid_specifier_matchspec (matchspec, XSPECIFIER (specifier)->methods, |
2715 int struct_frame_offset, | 2780 int struct_frame_offset, |
2716 void (*value_changed_in_frame) | 2781 void (*value_changed_in_frame) |
2717 (Lisp_Object specifier, struct frame *f, | 2782 (Lisp_Object specifier, struct frame *f, |
2718 Lisp_Object oldval)) | 2783 Lisp_Object oldval)) |
2719 { | 2784 { |
2720 struct Lisp_Specifier *sp = XSPECIFIER (specifier); | 2785 Lisp_Specifier *sp = XSPECIFIER (specifier); |
2721 assert (!GHOST_SPECIFIER_P (sp)); | 2786 assert (!GHOST_SPECIFIER_P (sp)); |
2722 | 2787 |
2723 if (!sp->caching) | 2788 if (!sp->caching) |
2724 sp->caching = xnew_and_zero (struct specifier_caching); | 2789 sp->caching = xnew_and_zero (struct specifier_caching); |
2725 sp->caching->offset_into_struct_window = struct_window_offset; | 2790 sp->caching->offset_into_struct_window = struct_window_offset; |
3123 | 3188 |
3124 void | 3189 void |
3125 specifier_type_create (void) | 3190 specifier_type_create (void) |
3126 { | 3191 { |
3127 the_specifier_type_entry_dynarr = Dynarr_new (specifier_type_entry); | 3192 the_specifier_type_entry_dynarr = Dynarr_new (specifier_type_entry); |
3193 dumpstruct (&the_specifier_type_entry_dynarr, &sted_description); | |
3128 | 3194 |
3129 Vspecifier_type_list = Qnil; | 3195 Vspecifier_type_list = Qnil; |
3130 staticpro (&Vspecifier_type_list); | 3196 staticpro (&Vspecifier_type_list); |
3131 | 3197 |
3132 INITIALIZE_SPECIFIER_TYPE (generic, "generic", "generic-specifier-p"); | 3198 INITIALIZE_SPECIFIER_TYPE (generic, "generic", "generic-specifier-p"); |
3144 SPECIFIER_HAS_METHOD (boolean, validate); | 3210 SPECIFIER_HAS_METHOD (boolean, validate); |
3145 | 3211 |
3146 INITIALIZE_SPECIFIER_TYPE (display_table, "display-table", "display-table-p"); | 3212 INITIALIZE_SPECIFIER_TYPE (display_table, "display-table", "display-table-p"); |
3147 | 3213 |
3148 SPECIFIER_HAS_METHOD (display_table, validate); | 3214 SPECIFIER_HAS_METHOD (display_table, validate); |
3215 } | |
3216 | |
3217 void | |
3218 reinit_specifier_type_create (void) | |
3219 { | |
3220 REINITIALIZE_SPECIFIER_TYPE (generic); | |
3221 REINITIALIZE_SPECIFIER_TYPE (integer); | |
3222 REINITIALIZE_SPECIFIER_TYPE (natnum); | |
3223 REINITIALIZE_SPECIFIER_TYPE (boolean); | |
3224 REINITIALIZE_SPECIFIER_TYPE (display_table); | |
3149 } | 3225 } |
3150 | 3226 |
3151 void | 3227 void |
3152 vars_of_specifier (void) | 3228 vars_of_specifier (void) |
3153 { | 3229 { |
3155 staticpro (&Vcached_specifiers); | 3231 staticpro (&Vcached_specifiers); |
3156 | 3232 |
3157 /* Do NOT mark through this, or specifiers will never be GC'd. | 3233 /* Do NOT mark through this, or specifiers will never be GC'd. |
3158 This is the same deal as for weak hash tables. */ | 3234 This is the same deal as for weak hash tables. */ |
3159 Vall_specifiers = Qnil; | 3235 Vall_specifiers = Qnil; |
3236 pdump_wire_list (&Vall_specifiers); | |
3160 | 3237 |
3161 Vuser_defined_tags = Qnil; | 3238 Vuser_defined_tags = Qnil; |
3162 staticpro (&Vuser_defined_tags); | 3239 staticpro (&Vuser_defined_tags); |
3163 | 3240 |
3164 Vunlock_ghost_specifiers = Qnil; | 3241 Vunlock_ghost_specifiers = Qnil; |