aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeodor Zlatanov2009-08-05 09:19:21 +0000
committerTeodor Zlatanov2009-08-05 09:19:21 +0000
commitf19a0f5b11e41baf46ce11fd447744ceb97ef754 (patch)
treed770ff782b6b974389b8188b81b898133ddfca51 /src
parent74edaf1f3e6b0ff6669d481162cdd62828997f17 (diff)
downloademacs-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')
-rw-r--r--src/ChangeLog9
-rw-r--r--src/lread.c95
-rw-r--r--src/print.c66
3 files changed, 170 insertions, 0 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a33144b7a33..0a0973635dd 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
12009-08-05 Teodor Zlatanov <tzz@lifelogs.com>
2
3 * lread.c (read1, syms_of_lread): Read hashtables back from the
4 readable format.
5
6 * print.c (print_preprocess, print_object): Print hashtables fully
7 and readably.
8 (syms_of_print): Provide 'hashtable-print-readable.
9
12009-08-02 Adrian Robert <Adrian.B.Robert@gmail.com> 102009-08-02 Adrian Robert <Adrian.B.Robert@gmail.com>
2 11
3 * nsfont.m (ns_descriptor_to_entity): Handle case when descriptor has 12 * nsfont.m (ns_descriptor_to_entity): Handle case when descriptor has
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/>. */
80extern int errno; 80extern int errno;
81#endif 81#endif
82 82
83/* hash table read constants */
84Lisp_Object Qhash_table, Qdata;
85Lisp_Object Qtest, Qsize;
86Lisp_Object Qweakness;
87Lisp_Object Qrehash_size;
88Lisp_Object Qrehash_threshold;
89extern Lisp_Object QCtest, QCsize, QCrehash_size, QCrehash_threshold, QCweakness;
90
83Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list; 91Lisp_Object Qread_char, Qget_file_char, Qstandard_input, Qcurrent_load_list;
84Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist; 92Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input, Vafter_load_alist;
85Lisp_Object Qascii_character, Qload, Qload_file_name; 93Lisp_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
diff --git a/src/print.c b/src/print.c
index e78f593c7b5..ce63b63acd3 100644
--- a/src/print.c
+++ b/src/print.c
@@ -1341,6 +1341,7 @@ print_preprocess (obj)
1341 loop: 1341 loop:
1342 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj) 1342 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
1343 || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj) 1343 || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj)
1344 || HASH_TABLE_P (obj)
1344 || (! NILP (Vprint_gensym) 1345 || (! NILP (Vprint_gensym)
1345 && SYMBOLP (obj) 1346 && SYMBOLP (obj)
1346 && !SYMBOL_INTERNED_P (obj))) 1347 && !SYMBOL_INTERNED_P (obj)))
@@ -1536,6 +1537,7 @@ print_object (obj, printcharfun, escapeflag)
1536 /* Detect circularities and truncate them. */ 1537 /* Detect circularities and truncate them. */
1537 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj) 1538 if (STRINGP (obj) || CONSP (obj) || VECTORP (obj)
1538 || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj) 1539 || COMPILEDP (obj) || CHAR_TABLE_P (obj) || SUB_CHAR_TABLE_P (obj)
1540 || HASH_TABLE_P (obj)
1539 || (! NILP (Vprint_gensym) 1541 || (! NILP (Vprint_gensym)
1540 && SYMBOLP (obj) 1542 && SYMBOLP (obj)
1541 && !SYMBOL_INTERNED_P (obj))) 1543 && !SYMBOL_INTERNED_P (obj)))
@@ -2031,6 +2033,7 @@ print_object (obj, printcharfun, escapeflag)
2031 else if (HASH_TABLE_P (obj)) 2033 else if (HASH_TABLE_P (obj))
2032 { 2034 {
2033 struct Lisp_Hash_Table *h = XHASH_TABLE (obj); 2035 struct Lisp_Hash_Table *h = XHASH_TABLE (obj);
2036#if 0
2034 strout ("#<hash-table", -1, -1, printcharfun, 0); 2037 strout ("#<hash-table", -1, -1, printcharfun, 0);
2035 if (SYMBOLP (h->test)) 2038 if (SYMBOLP (h->test))
2036 { 2039 {
@@ -2047,6 +2050,67 @@ print_object (obj, printcharfun, escapeflag)
2047 sprintf (buf, " 0x%lx", (unsigned long) h); 2050 sprintf (buf, " 0x%lx", (unsigned long) h);
2048 strout (buf, -1, -1, printcharfun, 0); 2051 strout (buf, -1, -1, printcharfun, 0);
2049 PRINTCHAR ('>'); 2052 PRINTCHAR ('>');
2053#endif
2054 /* Implement a readable output, e.g.:
2055 #s(hash-table size 2 test equal data (k1 v1 k2 v2)) */
2056 /* Always print the size. */
2057 sprintf (buf, "#s(hash-table size %ld",
2058 (long) XVECTOR (h->next)->size);
2059 strout (buf, -1, -1, printcharfun, 0);
2060
2061 if (!NILP (h->test))
2062 {
2063 strout (" test ", -1, -1, printcharfun, 0);
2064 print_object (h->test, printcharfun, 0);
2065 }
2066
2067 if (!NILP (h->weak))
2068 {
2069 strout (" weakness ", -1, -1, printcharfun, 0);
2070 print_object (h->weak, printcharfun, 0);
2071 }
2072
2073 if (!NILP (h->rehash_size))
2074 {
2075 strout (" rehash-size ", -1, -1, printcharfun, 0);
2076 print_object (h->rehash_size, printcharfun, 0);
2077 }
2078
2079 if (!NILP (h->rehash_threshold))
2080 {
2081 strout (" rehash-threshold ", -1, -1, printcharfun, 0);
2082 print_object (h->rehash_threshold, printcharfun, 0);
2083 }
2084
2085 strout (" data ", -1, -1, printcharfun, 0);
2086
2087 /* Print the data here as a plist. */
2088 int i;
2089
2090 int real_size = HASH_TABLE_SIZE (h);
2091 int size = real_size;
2092
2093 /* Don't print more elements than the specified maximum. */
2094 if (NATNUMP (Vprint_length)
2095 && XFASTINT (Vprint_length) < size)
2096 size = XFASTINT (Vprint_length);
2097
2098 PRINTCHAR ('(');
2099 for (i = 0; i < size; i++)
2100 if (!NILP (HASH_HASH (h, i)))
2101 {
2102 if (i) PRINTCHAR (' ');
2103 print_object (HASH_KEY (h, i), printcharfun, 0);
2104 PRINTCHAR (' ');
2105 print_object (HASH_VALUE (h, i), printcharfun, 0);
2106 }
2107
2108 if (size < real_size)
2109 strout (" ...", 4, 4, printcharfun, 0);
2110
2111 PRINTCHAR (')');
2112 PRINTCHAR (')');
2113
2050 } 2114 }
2051 else if (BUFFERP (obj)) 2115 else if (BUFFERP (obj))
2052 { 2116 {
@@ -2354,6 +2418,8 @@ that represents the number without losing information. */);
2354 Qfloat_output_format = intern ("float-output-format"); 2418 Qfloat_output_format = intern ("float-output-format");
2355 staticpro (&Qfloat_output_format); 2419 staticpro (&Qfloat_output_format);
2356 2420
2421 Fprovide (intern ("hashtable-print-readable"), Qnil);
2422
2357 DEFVAR_LISP ("print-length", &Vprint_length, 2423 DEFVAR_LISP ("print-length", &Vprint_length,
2358 doc: /* Maximum length of list to print before abbreviating. 2424 doc: /* Maximum length of list to print before abbreviating.
2359A value of nil means no limit. See also `eval-expression-print-length'. */); 2425A value of nil means no limit. See also `eval-expression-print-length'. */);