diff options
Diffstat (limited to 'Build/source/texk/web2c/mplibdir/memio.w')
-rw-r--r-- | Build/source/texk/web2c/mplibdir/memio.w | 514 |
1 files changed, 0 insertions, 514 deletions
diff --git a/Build/source/texk/web2c/mplibdir/memio.w b/Build/source/texk/web2c/mplibdir/memio.w deleted file mode 100644 index 2c85ae10282..00000000000 --- a/Build/source/texk/web2c/mplibdir/memio.w +++ /dev/null @@ -1,514 +0,0 @@ -% $Id: psout.w 616 2008-07-09 14:05:55Z taco $ -% -% Copyright 2008-2009 Taco Hoekwater. -% -% This program is free software: you can redistribute it and/or modify -% it under the terms of the GNU Lesser General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% This program is distributed in the hope that it will be useful, -% but WITHOUT ANY WARRANTY; without even the implied warranty of -% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -% GNU Lesser General Public License for more details. -% -% You should have received a copy of the GNU Lesser General Public License -% along with this program. If not, see <http://www.gnu.org/licenses/>. -% -% TeX is a trademark of the American Mathematical Society. -% METAFONT is a trademark of Addison-Wesley Publishing Company. -% PostScript is a trademark of Adobe Systems Incorporated. - -% Here is TeX material that gets inserted after \input webmac - -\font\tenlogo=logo10 % font used for the METAFONT logo -\def\MP{{\tenlogo META}\-{\tenlogo POST}} -\def\title{MetaPost MEM reading and writing} -\def\topofcontents{\hsize 5.5in - \vglue -30pt plus 1fil minus 1.5in - \def\?##1]{\hbox to 1in{\hfil##1.\ }} - } -\def\botofcontents{\vskip 0pt plus 1fil minus 1.5in} -\pdfoutput=1 -\pageno=3 - -@ As usual, need true and false. - -@d true 1 -@d false 0 -@d null 0 /* the null pointer */ -@d incr(A) (A)=(A)+1 /* increase a variable by unity */ -@d decr(A) (A)=(A)-1 /* decrease a variable by unity */ -@d qo(A) (A) /* to read eight bits from a quarterword */ -@d qi(A) (quarterword)(A) /* to store eight bits in a quarterword */ -@d max_quarterword 0x3FFF /* largest allowable value in a |quarterword| */ -@d max_halfword 0xFFFFFFF /* largest allowable value in a |halfword| */ -@d max_str_ref 127 /* ``infinite'' number of references */ - - -@c -#include <w2c/config.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "mplib.h" -#include "mpmp.h" -static void swap_items (char *p, int nitems, size_t size); -/* If we have these macros, use them, as they provide a better guide to - the endianess when cross-compiling. */ -#if defined (BYTE_ORDER) && defined (BIG_ENDIAN) && defined (LITTLE_ENDIAN) -#ifdef WORDS_BIGENDIAN -#undef WORDS_BIGENDIAN -#endif -#if BYTE_ORDER == BIG_ENDIAN -#define WORDS_BIGENDIAN -#endif -#endif -/* More of the same, but now NeXT-specific. */ -#ifdef NeXT -#ifdef WORDS_BIGENDIAN -#undef WORDS_BIGENDIAN -#endif -#ifdef __BIG_ENDIAN__ -#define WORDS_BIGENDIAN -#endif -#endif -#include "mpmemio.h" /* internal header */ - -@ @(mpmemio.h@>= -extern void mp_store_mem_file (MP mp); - -@ @c void mp_store_mem_file (MP mp) { - integer k; /* all-purpose index */ - pointer p,q; /* all-purpose pointers */ - integer x; /* something to dump */ - four_quarters w; /* four ASCII codes */ - memory_word WW; - @<Create the |mem_ident|, open the mem file, - and inform the user that dumping has begun@>; - @<Dump constants for consistency check@>; - @<Dump the string pool@>; - @<Dump the dynamic memory@>; - @<Dump the table of equivalents and the hash table@>; - @<Dump a few more things and the closing check word@>; - @<Close the mem file@>; -} - -@ Corresponding to the procedure that dumps a mem file, we also have a function -that reads~one~in. The function returns |false| if the dumped mem is -incompatible with the present \MP\ table sizes, etc. - -@d too_small(A) { wake_up_terminal; - wterm_ln("---! Must increase the "); wterm((A)); -@.Must increase the x@> - goto OFF_BASE; - } - -@(mpmemio.h@>= -extern boolean mp_load_mem_file (MP mp); - -@ @c -boolean mp_load_mem_file (MP mp) { - integer k; /* all-purpose index */ - pointer p,q; /* all-purpose pointers */ - integer x; /* something undumped */ - str_number s; /* some temporary string */ - four_quarters w; /* four ASCII codes */ - memory_word WW; - @<Undump the string pool@>; - @<Undump the dynamic memory@>; - @<Undump the table of equivalents and the hash table@>; - @<Undump a few more things and the closing check word@>; - return true; /* it worked! */ -OFF_BASE: - wake_up_terminal; - wterm_ln("(Fatal mem file error; I'm stymied)\n"); -@.Fatal mem file error@> - return false; -} - -@ If we want mem files to be shareable between different endianness architectures, -we have to swap some of the items so that everything turns out right. -Code borrowed from |texmfmp.c|. - -Make the NITEMS items pointed at by P, each of size SIZE, be the - opposite-endianness of whatever they are now. */ - -@d SWAP(x, y) temp = (x); (x) = (y); (y) = temp - -@c -static void -swap_items (char *p, int nitems, size_t size) -{ - char temp; -#if !defined (WORDS_BIGENDIAN) - /* Since `size' does not change, we can write a while loop for each - case, and avoid testing `size' for each time. */ - switch (size) - { - /* 16-byte items happen on the DEC Alpha machine when we are not - doing sharable memory dumps. */ - case 16: - while (nitems--) - { - SWAP (p[0], p[15]); - SWAP (p[1], p[14]); - SWAP (p[2], p[13]); - SWAP (p[3], p[12]); - SWAP (p[4], p[11]); - SWAP (p[5], p[10]); - SWAP (p[6], p[9]); - SWAP (p[7], p[8]); - p += size; - } - break; - - case 8: - while (nitems--) - { - SWAP (p[0], p[7]); - SWAP (p[1], p[6]); - SWAP (p[2], p[5]); - SWAP (p[3], p[4]); - p += size; - } - break; - - case 4: - while (nitems--) - { - SWAP (p[0], p[3]); - SWAP (p[1], p[2]); - p += size; - } - break; - - case 2: - while (nitems--) - { - SWAP (p[0], p[1]); - p += size; - } - break; - - case 1: - /* Nothing to do. */ - break; - - default: - fprintf (stderr, "Can't swap a %d-byte item for (un)dumping", (int)size); - exit(1); - } -#endif -} - -@ Mem files consist of |memory_word| items, and we use the following -macros to dump words of different types: - -@d dump_wd(A) { WW=(A); swap_items((char *)&WW,1,sizeof(WW)); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } -@d dump_int(A) { int cint=(A); swap_items((char *)&cint,1,sizeof(cint)); (mp->write_binary_file)(mp,mp->mem_file,&cint,sizeof(cint)); } -@d dump_hh(A) { WW.hh=(A); swap_items((char *)&WW,1,sizeof(WW)); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } -@d dump_qqqq(A) { WW.qqqq=(A); swap_items((char *)&WW,1,sizeof(WW)); (mp->write_binary_file)(mp,mp->mem_file,&WW,sizeof(WW)); } -@d dump_string(A) { dump_int((int)(strlen(A)+1)); - (mp->write_binary_file)(mp,mp->mem_file,A,strlen(A)+1); } - -@ The inverse macros are slightly more complicated, since we need to check -the range of the values we are reading in. We say `|undump(a)(b)(x)|' to -read an integer value |x| that is supposed to be in the range |a<=x<=b|. - -@d mgeti(A) do { - size_t wanted = sizeof(A); - void *A_ptr = &A; - (mp->read_binary_file)(mp, mp->mem_file,&A_ptr,&wanted); - if (wanted!=sizeof(A)) goto OFF_BASE; - swap_items(A_ptr,1,wanted); -} while (0) - -@d mgetw(A) do { - size_t wanted = sizeof(A); - void *A_ptr = &A; - (mp->read_binary_file)(mp, mp->mem_file,&A_ptr,&wanted); - if (wanted!=sizeof(A)) goto OFF_BASE; - swap_items(A_ptr,1,wanted); -} while (0) - -@d undump_wd(A) { mgetw(WW); A=WW; } -@d undump_int(A) { int cint; mgeti(cint); A=cint; } -@d undump_hh(A) { mgetw(WW); A=WW.hh; } -@d undump_qqqq(A) { mgetw(WW); A=WW.qqqq; } -@d undump_strings(A,B,C) { - undump_int(x); if ( (x<(A)) || (x>(B)) ) goto OFF_BASE; else C=str(x); } -@d undump(A,B,C) { undump_int(x); - if ( (x<(A)) || (x>(int)(B)) ) goto OFF_BASE; else C=x; } -@d undump_size(A,B,C,D) { undump_int(x); - if (x<(A)) goto OFF_BASE; - if (x>(B)) too_small((C)); else D=x; } -@d undump_string(A) { - size_t the_wanted; - void *the_string; - integer XX=0; - undump_int(XX); - the_wanted = (size_t)XX; - the_string = mp_xmalloc(mp,(size_t)XX,1); - (mp->read_binary_file)(mp,mp->mem_file,&the_string,&the_wanted); - A = (char *)the_string; - if (the_wanted!=(size_t)XX) goto OFF_BASE; -} - -@ The next few sections of the program should make it clear how we use the -dump/undump macros. - -@<Dump constants for consistency check@>= -x = metapost_magic; dump_int(x); -dump_int(mp->mem_top); -dump_int((integer)mp->hash_size); -dump_int(mp->hash_prime) -dump_int(mp->param_size); -dump_int(mp->max_in_open); - -@ Sections of a \.{WEB} program that are ``commented out'' still contribute -strings to the string pool; therefore \.{INIMP} and \MP\ will have -the same strings. (And it is, of course, a good thing that they do.) -@.WEB@> -@^string pool@> - -@(mpmemio.h@>= -extern int mp_undump_constants (MP mp); - -@ @c -int mp_undump_constants (MP mp) { - integer x; - undump_int(x); - if (x!=metapost_magic) return x; - undump_int(x); mp->mem_top = x; - undump_int(x); mp->hash_size = (unsigned)x; - undump_int(x); mp->hash_prime = x; - undump_int(x); mp->param_size = x; - undump_int(x); mp->max_in_open = x; - return metapost_magic; - OFF_BASE: - return -1; -} - -@ We do string pool compaction to avoid dumping unused strings. - -@d dump_four_ASCII - w.b0=qi(mp->str_pool[k]); w.b1=qi(mp->str_pool[k+1]); - w.b2=qi(mp->str_pool[k+2]); w.b3=qi(mp->str_pool[k+3]); - dump_qqqq(w) - -@<Dump the string pool@>= -mp_do_compaction(mp, mp->pool_size); -dump_int(mp->pool_ptr); -dump_int(mp->max_str_ptr); -dump_int(mp->str_ptr); -k=0; -while ( (mp->next_str[k]==k+1) && (k<=mp->max_str_ptr) ) - k++; -dump_int(k); -while ( k<=mp->max_str_ptr ) { - dump_int(mp->next_str[k]); incr(k); -} -k=0; -while (1) { - dump_int(mp->str_start[k]); /* TODO: valgrind warning here */ - if ( k==mp->str_ptr ) { - break; - } else { - k=mp->next_str[k]; - } -} -k=0; -while (k+4<mp->pool_ptr ) { - dump_four_ASCII; k=k+4; -} -k=mp->pool_ptr-4; dump_four_ASCII; -mp_print_ln(mp); mp_print(mp, "at most "); mp_print_int(mp, mp->max_str_ptr); -mp_print(mp, " strings of total length "); -mp_print_int(mp, mp->pool_ptr) - -@ @d undump_four_ASCII - undump_qqqq(w); - mp->str_pool[k]=(ASCII_code)qo(w.b0); mp->str_pool[k+1]=(ASCII_code)qo(w.b1); - mp->str_pool[k+2]=(ASCII_code)qo(w.b2); mp->str_pool[k+3]=(ASCII_code)qo(w.b3) - -@<Undump the string pool@>= -undump_int(mp->pool_ptr); -mp_reallocate_pool(mp, mp->pool_ptr) ; -undump_int(mp->max_str_ptr); -mp_reallocate_strings (mp,mp->max_str_ptr) ; -undump(0,mp->max_str_ptr,mp->str_ptr); -undump(0,mp->max_str_ptr+1,s); -for (k=0;k<=s-1;k++) - mp->next_str[k]=k+1; -for (k=s;k<=mp->max_str_ptr;k++) - undump(s+1,mp->max_str_ptr+1,mp->next_str[k]); -mp->fixed_str_use=0; -k=0; -while (1) { - undump(0,mp->pool_ptr,mp->str_start[k]); - if ( k==mp->str_ptr ) break; - mp->str_ref[k]=max_str_ref; - incr(mp->fixed_str_use); - mp->last_fixed_str=k; k=mp->next_str[k]; -} -k=0; -while ( k+4<mp->pool_ptr ) { - undump_four_ASCII; k=k+4; -} -k=mp->pool_ptr-4; undump_four_ASCII; -mp->init_str_use=mp->fixed_str_use; mp->init_pool_ptr=mp->pool_ptr; -mp->max_pool_ptr=mp->pool_ptr; -mp->strs_used_up=mp->fixed_str_use; -mp->pool_in_use=mp->str_start[mp->str_ptr]; mp->strs_in_use=mp->fixed_str_use; -mp->max_pl_used=mp->pool_in_use; mp->max_strs_used=mp->strs_in_use; -mp->pact_count=0; mp->pact_chars=0; mp->pact_strs=0; - -@ By sorting the list of available spaces in the variable-size portion of -|mem|, we are usually able to get by without having to dump very much -of the dynamic memory. - -We recompute |var_used| and |dyn_used|, so that \.{INIMP} dumps valid -information even when it has not been gathering statistics. - -@<Dump the dynamic memory@>= -mp_sort_avail(mp); mp->var_used=0; -dump_int(mp->lo_mem_max); dump_int(mp->rover); -p=0; q=mp->rover; x=0; -do { - for (k=p;k<= q+1;k++) - dump_wd(mp->mem[k]); - x=x+q+2-p; mp->var_used=mp->var_used+q-p; - p=q+node_size(q); q=rmp_link(q); -} while (q!=mp->rover); -mp->var_used=mp->var_used+mp->lo_mem_max-p; -mp->dyn_used=mp->mem_end+1-mp->hi_mem_min; -for (k=p;k<= mp->lo_mem_max;k++ ) - dump_wd(mp->mem[k]); -x=x+mp->lo_mem_max+1-p; -dump_int(mp->hi_mem_min); dump_int(mp->avail); -for (k=mp->hi_mem_min;k<=mp->mem_end;k++ ) - dump_wd(mp->mem[k]); -x=x+mp->mem_end+1-mp->hi_mem_min; -p=mp->avail; -while ( p!=null ) { - decr(mp->dyn_used); p=mp_link(p); -} -dump_int(mp->var_used); dump_int(mp->dyn_used); -mp_print_ln(mp); mp_print_int(mp, x); -mp_print(mp, " memory locations dumped; current usage is "); -mp_print_int(mp, mp->var_used); mp_print_char(mp, xord('&')); mp_print_int(mp, mp->dyn_used) - -@ @<Undump the dynamic memory@>= -undump(lo_mem_stat_max+1000,hi_mem_stat_min-1,mp->lo_mem_max); -undump(lo_mem_stat_max+1,mp->lo_mem_max,mp->rover); -p=0; q=mp->rover; -do { - for (k=p;k<= q+1; k++) - undump_wd(mp->mem[k]); - p=q+node_size(q); - if ( (p>mp->lo_mem_max)||((q>=rmp_link(q))&&(rmp_link(q)!=mp->rover)) ) - goto OFF_BASE; - q=rmp_link(q); -} while (q!=mp->rover); -for (k=p;k<=mp->lo_mem_max;k++ ) - undump_wd(mp->mem[k]); -undump(mp->lo_mem_max+1,hi_mem_stat_min,mp->hi_mem_min); -undump(null,mp->mem_top,mp->avail); mp->mem_end=mp->mem_top; -mp->last_pending=spec_head; -for (k=mp->hi_mem_min;k<= mp->mem_end;k++) - undump_wd(mp->mem[k]); -undump_int(mp->var_used); undump_int(mp->dyn_used) - -@ A different scheme is used to compress the hash table, since its lower region -is usually sparse. When |text(p)<>0| for |p<=hash_used|, we output three -words: |p|, |hash[p]|, and |eqtb[p]|. The hash table is, of course, densely -packed for |p>=hash_used|, so the remaining entries are output in~a~block. - -@<Dump the table of equivalents and the hash table@>= -dump_int(mp->hash_used); -mp->st_count=frozen_inaccessible-1-mp->hash_used; -for (p=1;p<=mp->hash_used;p++) { - if ( text(p)!=0 ) { - dump_int(p); dump_hh(mp->hash[p]); dump_hh(mp->eqtb[p]); incr(mp->st_count); - } -} -for (p=mp->hash_used+1;p<=(int)hash_end;p++) { - dump_hh(mp->hash[p]); dump_hh(mp->eqtb[p]); -} -dump_int(mp->st_count); -mp_print_ln(mp); mp_print_int(mp, mp->st_count); mp_print(mp, " symbolic tokens") - -@ @<Undump the table of equivalents and the hash table@>= -undump(1,frozen_inaccessible,mp->hash_used); -p=0; -do { - undump(p+1,mp->hash_used,p); - undump_hh(mp->hash[p]); undump_hh(mp->eqtb[p]); -} while (p!=mp->hash_used); -for (p=mp->hash_used+1;p<=(int)hash_end;p++ ) { - undump_hh(mp->hash[p]); undump_hh(mp->eqtb[p]); -} -undump_int(mp->st_count) - -@ We have already printed a lot of statistics, so we set |mp_tracing_stats:=0| -to prevent them appearing again. - -@<Dump a few more things and the closing check word@>= -dump_int(mp->max_internal); -dump_int(mp->int_ptr); -for (k=1;k<= mp->int_ptr;k++ ) { - dump_int(mp->internal[k]); - dump_int(mp->int_type[k]); - dump_string(mp->int_name[k]); -} -dump_int(mp->start_sym); -dump_int(mp->interaction); -dump_string(mp->mem_ident); -dump_int(mp->bg_loc); dump_int(mp->eg_loc); dump_int(mp->serial_no); dump_int(69073); -mp->internal[mp_tracing_stats]=0 - -@ @<Undump a few more things and the closing check word@>= -undump_int(x); -if (x>mp->max_internal) mp_grow_internals(mp,x); -undump_int(mp->int_ptr); -for (k=1;k<= mp->int_ptr;k++) { - undump_int(mp->internal[k]); - undump_int(mp->int_type[k]); - undump_string(mp->int_name[k]); -} -undump(0,frozen_inaccessible,mp->start_sym); -if (mp->interaction==mp_unspecified_mode) { - undump(mp_unspecified_mode,mp_error_stop_mode,mp->interaction); -} else { - undump(mp_unspecified_mode,mp_error_stop_mode,x); -} -undump_string(mp->mem_ident); -undump(1,hash_end,mp->bg_loc); -undump(1,hash_end,mp->eg_loc); -undump_int(mp->serial_no); -undump_int(x); -if (x!=69073) goto OFF_BASE - -@ @<Create the |mem_ident|...@>= -{ - char *tmp = mp_xmalloc(mp,11,1); - mp_xfree(mp->mem_ident); - mp->mem_ident = mp_xmalloc(mp,256,1); - mp_snprintf(tmp,11,"%04d.%02d.%02d", - (int)mp_round_unscaled(mp, mp->internal[mp_year]), - (int)mp_round_unscaled(mp, mp->internal[mp_month]), - (int)mp_round_unscaled(mp, mp->internal[mp_day])); - mp_snprintf(mp->mem_ident,256," (mem=%s %s)",mp->job_name, tmp); - mp_xfree(tmp); - mp_pack_job_name(mp, ".mem"); - while (! mp_w_open_out(mp, &mp->mem_file) ) - mp_prompt_file_name(mp, "mem file name", ".mem"); - mp_print_nl(mp, "Beginning to dump on file "); -@.Beginning to dump...@> - mp_print(mp, mp->name_of_file); - mp_print_nl(mp, mp->mem_ident); -} - -@ @<Close the mem file@>= -(mp->close_file)(mp,mp->mem_file) |