diff options
| author | Teodor Zlatanov | 2009-08-05 09:19:21 +0000 |
|---|---|---|
| committer | Teodor Zlatanov | 2009-08-05 09:19:21 +0000 |
| commit | f19a0f5b11e41baf46ce11fd447744ceb97ef754 (patch) | |
| tree | d770ff782b6b974389b8188b81b898133ddfca51 /src/lread.c | |
| parent | 74edaf1f3e6b0ff6669d481162cdd62828997f17 (diff) | |
| download | emacs-f19a0f5b11e41baf46ce11fd447744ceb97ef754.tar.gz emacs-f19a0f5b11e41baf46ce11fd447744ceb97ef754.zip | |
* lread.c (read1, syms_of_lread): Read hashtables back from the
readable format.
* print.c (print_preprocess, print_object): Print hashtables fully
and readably.
(syms_of_print): Provide 'hashtable-print-readable.
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/lread.c b/src/lread.c index 0fb93031ad4..193bd6ae668 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -80,6 +80,14 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 80 | extern int errno; | 80 | extern int errno; |
| 81 | #endif | 81 | #endif |
| 82 | 82 | ||
| 83 | /* hash table read constants */ | ||
| 84 | Lisp_Object Qhash_table, Qdata; | ||
| 85 | Lisp_Object Qtest, Qsize; | ||
| 86 | Lisp_Object Qweakness; | ||
| 87 | Lisp_Object Qrehash_size; | ||
| 88 | Lisp_Object Qrehash_threshold; | ||
| 89 | extern Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness; | ||
| 90 | |||
| 83 | Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list; | 91 | Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list; |
| 84 | Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist; | 92 | Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist; |
| 85 | Lisp_Object Qascii_character, Qload, Qload_file_name; | 93 | Lisp_Object Qascii_character, Qload, Qload_file_name; |
| @@ -2346,6 +2354,78 @@ read1 (readcharfun, pch, first_in_list) | |||
| 2346 | 2354 | ||
| 2347 | case '#': | 2355 | case '#': |
| 2348 | c = READCHAR; | 2356 | c = READCHAR; |
| 2357 | if (c == 's') | ||
| 2358 | { | ||
| 2359 | c = READCHAR; | ||
| 2360 | if (c == '(') | ||
| 2361 | { | ||
| 2362 | /* Accept extended format for hashtables (extensible to | ||
| 2363 | other types), e.g. | ||
| 2364 | #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */ | ||
| 2365 | Lisp_Object tmp = read_list (0, readcharfun); | ||
| 2366 | Lisp_Object head = CAR_SAFE (tmp); | ||
| 2367 | Lisp_Object data = Qnil; | ||
| 2368 | Lisp_Object val = Qnil; | ||
| 2369 | /* The size is 2 * number of allowed keywords to | ||
| 2370 | make-hash-table. */ | ||
| 2371 | Lisp_Object params[10]; | ||
| 2372 | Lisp_Object ht; | ||
| 2373 | Lisp_Object key = Qnil; | ||
| 2374 | int param_count = 0; | ||
| 2375 | int i; | ||
| 2376 | |||
| 2377 | if (!EQ (head, Qhash_table)) | ||
| 2378 | error ("Invalid extended read marker at head of #s list " | ||
| 2379 | "(only hash-table allowed)"); | ||
| 2380 | |||
| 2381 | tmp = CDR_SAFE (tmp); | ||
| 2382 | |||
| 2383 | /* This is repetitive but fast and simple. */ | ||
| 2384 | params[param_count] = QCsize; | ||
| 2385 | params[param_count+1] = Fplist_get (tmp, Qsize); | ||
| 2386 | if (!NILP (params[param_count+1])) | ||
| 2387 | param_count+=2; | ||
| 2388 | |||
| 2389 | params[param_count] = QCtest; | ||
| 2390 | params[param_count+1] = Fplist_get (tmp, Qtest); | ||
| 2391 | if (!NILP (params[param_count+1])) | ||
| 2392 | param_count+=2; | ||
| 2393 | |||
| 2394 | params[param_count] = QCweakness; | ||
| 2395 | params[param_count+1] = Fplist_get (tmp, Qweakness); | ||
| 2396 | if (!NILP (params[param_count+1])) | ||
| 2397 | param_count+=2; | ||
| 2398 | |||
| 2399 | params[param_count] = QCrehash_size; | ||
| 2400 | params[param_count+1] = Fplist_get (tmp, Qrehash_size); | ||
| 2401 | if (!NILP (params[param_count+1])) | ||
| 2402 | param_count+=2; | ||
| 2403 | |||
| 2404 | params[param_count] = QCrehash_threshold; | ||
| 2405 | params[param_count+1] = Fplist_get (tmp, Qrehash_threshold); | ||
| 2406 | if (!NILP (params[param_count+1])) | ||
| 2407 | param_count+=2; | ||
| 2408 | |||
| 2409 | /* This is the hashtable data. */ | ||
| 2410 | data = Fplist_get (tmp, Qdata); | ||
| 2411 | |||
| 2412 | /* Now use params to make a new hashtable and fill it. */ | ||
| 2413 | ht = Fmake_hash_table (param_count, params); | ||
| 2414 | |||
| 2415 | while (CONSP (data)) | ||
| 2416 | { | ||
| 2417 | key = XCAR (data); | ||
| 2418 | data = XCDR (data); | ||
| 2419 | if (!CONSP (data)) | ||
| 2420 | error ("Odd number of elements in hashtable data"); | ||
| 2421 | val = XCAR (data); | ||
| 2422 | data = XCDR (data); | ||
| 2423 | Fputhash (key, val, ht); | ||
| 2424 | } | ||
| 2425 | |||
| 2426 | return ht; | ||
| 2427 | } | ||
| 2428 | } | ||
| 2349 | if (c == '^') | 2429 | if (c == '^') |
| 2350 | { | 2430 | { |
| 2351 | c = READCHAR; | 2431 | c = READCHAR; |
| @@ -4448,6 +4528,21 @@ to load. See also `load-dangerous-libraries'. */); | |||
| 4448 | 4528 | ||
| 4449 | Vloads_in_progress = Qnil; | 4529 | Vloads_in_progress = Qnil; |
| 4450 | staticpro (&Vloads_in_progress); | 4530 | staticpro (&Vloads_in_progress); |
| 4531 | |||
| 4532 | Qhash_table = intern ("hash-table"); | ||
| 4533 | staticpro (&Qhash_table); | ||
| 4534 | Qdata = intern ("data"); | ||
| 4535 | staticpro (&Qdata); | ||
| 4536 | Qtest = intern ("test"); | ||
| 4537 | staticpro (&Qtest); | ||
| 4538 | Qsize = intern ("size"); | ||
| 4539 | staticpro (&Qsize); | ||
| 4540 | Qweakness = intern ("weakness"); | ||
| 4541 | staticpro (&Qweakness); | ||
| 4542 | Qrehash_size = intern ("rehash-size"); | ||
| 4543 | staticpro (&Qrehash_size); | ||
| 4544 | Qrehash_threshold = intern ("rehash-threshold"); | ||
| 4545 | staticpro (&Qrehash_threshold); | ||
| 4451 | } | 4546 | } |
| 4452 | 4547 | ||
| 4453 | /* arch-tag: a0d02733-0f96-4844-a659-9fd53c4f414d | 4548 | /* arch-tag: a0d02733-0f96-4844-a659-9fd53c4f414d |