00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <sys/stat.h>
00027 #include <fcntl.h>
00028 #include <sys/mman.h>
00029 #include <sys/types.h>
00030 #include <unistd.h>
00031
00032 #include "gspin-tree.h"
00033 #include "gspin-list.h"
00034 #include "gspin-tel.h"
00035 #include "gspin-assert.h"
00036 #include "gspin-io.h"
00037 #include "gspin-mempool.h"
00038
00039 #ifdef Is_True_On
00040 void flag_reachable_nodes(gs_t t) {
00041 if (t == NULL)
00042 return;
00043 if (gs_em(t) == true)
00044 return;
00045 _gs_em(t, true);
00046 int j;
00047 for (j = 0; j < gs_code_arity(gs_code(t)); j++)
00048 flag_reachable_nodes(gs_operand(t, j));
00049 }
00050 #endif
00051
00053
00054
00055
00056
00057
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 char *mem_seg = NULL;
00075
00076 gs_void_t gs_write (const gs_string_t filename)
00077 {
00078 gs_count_t gs_length, unsigned_char_length, mem_seg_length;
00079 gs_int_t fd, lseek_rv, write_rv;
00080
00081 #ifdef Is_True_On
00082 flag_reachable_nodes((gs_t) gs_mempool[GS_ARENA].firstblock->mem);
00083 #endif
00084
00085 gs_arena_t *gs_arena = &gs_mempool[GS_ARENA];
00086 gs_arena_t *gs_unsigned_char_arena = &gs_mempool[IB_STRING_ARENA];
00087
00088 gs_length = gs_arena->current_index;
00089 unsigned_char_length = gs_unsigned_char_arena->current_index;
00090 mem_seg_length = gs_length + unsigned_char_length;
00091
00092 fd = open (filename, O_TRUNC|O_CREAT|O_RDWR, 0666);
00093 GS_ASSERT (!(fd < 0), "open failed.\n");
00094 lseek_rv = lseek (fd, mem_seg_length - 1, SEEK_SET);
00095 GS_ASSERT (lseek_rv != -1, "lseek failed.\n");
00096 write_rv = write (fd, " ", 1);
00097 GS_ASSERT (write_rv == 1, "write failed.\n");
00098 mem_seg = mmap (0, mem_seg_length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
00099 GS_ASSERT (mem_seg != MAP_FAILED, "mmap failure.\n");
00100
00101
00102 int i = 0;
00103 int size;
00104 gs_t p_in_memseg;
00105 gs_t t = (gs_t) gs_mempool_idx2address(GS_ARENA, 0);
00106 while (i < gs_arena->current_index) {
00107 p_in_memseg = (gs_t) (mem_seg + i);
00108 size = gspin_node_size(gs_code(t));
00109 memcpy(p_in_memseg, t, size);
00110 #ifdef Is_True_On
00111 _gs_em(p_in_memseg, false);
00112 if (gs_em(t) == false) {
00113 printf("leaked node: ");
00114 gs_dump(t);
00115 }
00116 #endif
00117
00118 if (gs_code_arity(gs_code(t)) > 0) {
00119 int j;
00120 for (j = 0; j < gs_code_arity(gs_code(t)); j++)
00121 if (gs_operand(t, j) != NULL)
00122 gs_set_operand(p_in_memseg, j,
00123 (gs_t) gs_mempool_address2byteofst(GS_ARENA, (char *)gs_operand(t, j)));
00124 }
00125 else if (gs_code(t) == IB_STRING) {
00126 gs_string_t s = gs_s(t);
00127 _gs_u(p_in_memseg,
00128 gs_length + gs_mempool_address2byteofst(IB_STRING_ARENA, s));
00129 memcpy (mem_seg + gs_u(p_in_memseg), s, gs_slen(p_in_memseg));
00130 }
00131
00132 i += gspin_node_size(gs_code(t));
00133 t = (gs_t) gs_mempool_idx2address(GS_ARENA, i);
00134 while (i < gs_arena->current_index && gs_code(t) == DOT) {
00135 i += 4;
00136 t = (gs_t) gs_mempool_idx2address(GS_ARENA, i);
00137 }
00138 }
00139
00140 close (fd);
00141 return;
00142 }
00143
00144 gs_unsigned_char_t *gs_read (const gs_string_t filename)
00145 {
00146 gs_int_t fd, fstat_rv;
00147 struct stat statbuf;
00148 char *p, *string_section;
00149
00150 fd = open (filename, O_RDONLY);
00151 GS_ASSERT (fd != -1, "open failed.\n");
00152 fstat_rv = fstat (fd, &statbuf);
00153
00154
00155 GS_ASSERT (fstat_rv == 0, "fstat failed.\n");
00156 mem_seg = mmap (0, statbuf.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
00157 GS_ASSERT (mem_seg != MAP_FAILED, "mmap failure.\n");
00158 GS_ASSERT (mem_seg != NULL, "mem_seg null!.\n");
00159
00160
00161 p = mem_seg;
00162 string_section = (char *) (~0L);
00163 while (p - mem_seg < statbuf.st_size && p < string_section) {
00164 gs_t q = (gs_t) p;
00165 if (gs_code_arity(gs_code(q)) > 0) {
00166 int j;
00167 for (j = 0; j < gs_code_arity(gs_code(q)); j++)
00168 if (gs_operand(q, j) != NULL) {
00169 GS_ASSERT((long)gs_operand(q, j) < statbuf.st_size,
00170 "right offset out of bounds!.\n");
00171 gs_set_operand(q, j, (gs_t) (mem_seg + (int) gs_operand(q,j)));
00172 }
00173 }
00174 else if (gs_code(q) == IB_STRING) {
00175 if (string_section == (char *) (~0L))
00176 string_section = mem_seg + gs_u(q);
00177 GS_ASSERT(gs_u(q) < statbuf.st_size, "left offset out of bounds!.\n");
00178 _gs_s_no_alloc (q, (gs_unsigned_char_t *) (mem_seg + gs_u(q)));
00179 }
00180
00181 p += gspin_node_size(gs_code(q));
00182 while (p - mem_seg < statbuf.st_size && p < string_section &&
00183 gs_code((gs_t) p) == DOT)
00184 p += 4;
00185 }
00186
00187 close (fd);
00188 return mem_seg;
00189 }
00190
00191 gs_t gs_read_file (const gs_string_t filename)
00192 {
00193 gs_t p;
00194 GS_ASSERT (filename != NULL, "open failed.\n");
00195 p = (gs_t) gs_read (filename);
00196 gs_program = p;
00197 return p;
00198 }