source: trunk/gsdl/src/mgpp/text/mg_fast_comp_dict.cpp@ 2442

Last change on this file since 2442 was 2442, checked in by jrm21, 23 years ago

portability changes, use getopt from unistd.h (all POSIX systems)

  • Property svn:keywords set to Author Date Id Revision
File size: 17.9 KB
Line 
1/**************************************************************************
2 *
3 * mg_fast_comp_dict.cpp -- Program to generate a fast compression dictionary
4 * Copyright (C) 1994 Neil Sharman
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id: mg_fast_comp_dict.cpp 2442 2001-05-17 04:38:16Z jrm21 $
21 *
22 **************************************************************************/
23
24
25/*
26 $Log$
27 Revision 1.3 2001/05/17 04:38:15 jrm21
28 portability changes, use getopt from unistd.h (all POSIX systems)
29
30 Revision 1.2 2000/01/18 03:53:23 rjmcnab
31 Fixed a couple of bugs and made building silent if needed.
32
33 Revision 1.1 2000/01/14 02:26:13 sjboddie
34 Rodgers new C++ mg
35
36 Revision 1.2 1999/10/17 23:43:26 cs025
37 Changes to eradicate Xmalloc
38
39 Revision 1.1 1999/10/11 02:57:50 cs025
40 Base install of MG-PP
41
42 Revision 1.1 1999/08/10 21:18:06 sjboddie
43 renamed mg-1.3d directory mg
44
45 Revision 1.2 1998/11/25 07:55:44 rjmcnab
46
47 Modified mg to that you can specify the stemmer you want
48 to use via a command line option. You specify it to
49 mg_passes during the build process. The number of the
50 stemmer that you used is stored within the inverted
51 dictionary header and the stemmed dictionary header so
52 the correct stemmer is used in later stages of building
53 and querying.
54
55 Revision 1.1 1998/11/17 09:34:57 rjmcnab
56 *** empty log message ***
57
58 * Revision 1.3 1994/10/20 03:56:55 tes
59 * I have rewritten the boolean query optimiser and abstracted out the
60 * components of the boolean query.
61 *
62 * Revision 1.2 1994/09/20 04:41:47 tes
63 * For version 1.1
64 *
65 */
66
67#define _XOPEN_SOURCE 1
68#define _XOPEN_SOURCE_EXTENDED 1
69#include <unistd.h>
70
71#include "sysfuncs.h"
72
73#include "huffman.h"
74#include "messages.h"
75#include "memlib.h"
76#include "netorder.h" /* [RPAP - Jan 97: Endian Ordering] */
77
78#include "local_strings.h"
79#include "mg.h"
80#include "text.h"
81#include "invf.h"
82#include "mg_files.h"
83#include "locallib.h"
84#include "words.h"
85
86
87
88#define ALIGN_SIZE(p,t) (((p) + (sizeof(t)-1)) & (~(sizeof(t)-1)))
89
90#define WORDNO(p, base) ((((char*)(p))-((char*)(base)))/sizeof(u_char*))
91#define FIXUP(p) (fixup[WORDNO(p,buffer)/8] |= (1<<(WORDNO(p, buffer) & 7)))
92
93#define IS_FIXUP(p) ((fixup[WORDNO(p,buffer)/8] & (1<<(WORDNO(p, buffer) & 7))) != 0)
94
95#define FIXUP_VALS(vals) do { \
96 int i; \
97 for (i=0; i < MAX_HUFFCODE_LEN+1; i++) \
98 FIXUP(&vals[i]); \
99 } while(0)
100
101
102
103static u_long mem_for_comp_dict (char *filename);
104static void load_comp_dict (char *filename);
105static void save_fast_dict (char *filename);
106static void unfixup_buffer (void);
107
108
109static void *buffer;
110static void *cur;
111static u_char *fixup;
112static u_long mem, fixup_mem;
113
114int main (int argc, char **argv)
115{
116 int ch;
117 char *filename = "";
118 opterr = 0;
119 msg_prefix = argv[0];
120 while ((ch = getopt (argc, argv, "f:d:h")) != -1)
121 switch (ch)
122 {
123 case 'f': /* input file */
124 filename = optarg;
125 break;
126 case 'd':
127 set_basepath (optarg);
128 break;
129 case 'h':
130 case '?':
131 fprintf (stderr, "usage: %s [-f input_file] [-d data directory] [-h]\n",
132 argv[0]);
133 exit (1);
134 }
135
136 mem = mem_for_comp_dict (filename);
137
138 fixup_mem = (ALIGN_SIZE (mem, u_char *) / sizeof (u_char *) + 7) / 8;
139
140 cur = buffer = Xmalloc (mem);
141 memset (buffer, 0, mem);
142 fixup = (u_char *) Xmalloc (fixup_mem);
143 memset (fixup, 0, fixup_mem);
144
145#ifndef SILENT
146 Message ("Estimated memory for fast_dict %u", mem);
147 Message ("Estimated memory for fixups %u", fixup_mem);
148#endif
149
150 load_comp_dict (filename);
151
152#ifndef SILENT
153 Message ("Actual memory for fast_dict %u", (char *) cur - (char *) buffer);
154#endif
155
156 if ((u_long) cur > (u_long) buffer + mem)
157 FatalError (1, "The buffer was not big enough for the dictionary");
158
159 {
160 /* [RPAP - Jan 97: Endian Ordering] */
161 compression_dict *cd = (compression_dict *) buffer;
162 int i, which;
163
164 /* cfh */
165 for (which = 0; which <= 1; which++)
166 {
167 int j;
168
169 HTONSI(cd->cfh[which]->hd.num_codes);
170 HTONSI(cd->cfh[which]->hd.mincodelen);
171 HTONSI(cd->cfh[which]->hd.maxcodelen);
172 for (j = 0; j < MAX_HUFFCODE_LEN + 1; j++)
173 {
174 HTONSI(cd->cfh[which]->hd.lencount[j]);
175 HTONUL(cd->cfh[which]->hd.min_code[j]);
176 }
177 HTONUL(cd->cfh[which]->uncompressed_size);
178 for (j = 0; j < MAX_HUFFCODE_LEN + 1; j++)
179 HTONUL(cd->cfh[which]->huff_words_size[j]);
180 }
181 HTONUL(cd->MemForCompDict);
182 /* ad */
183 if (cd->cdh.novel_method == MG_NOVEL_DELTA ||
184 cd->cdh.novel_method == MG_NOVEL_HYBRID)
185 for (which = 0; which <= 1; which++)
186 {
187 int j;
188
189 HTONUL(cd->ad->afh[which].num_frags);
190 HTONUL(cd->ad->afh[which].mem_for_frags);
191 for (j = 0; j < 33; j++)
192 {
193 HTONSI(cd->ad->blk_start[which][j]);
194 HTONSI(cd->ad->blk_end[which][j]);
195 }
196 }
197 /* cdh */
198 HTONUL(cd->cdh.dict_type);
199 HTONUL(cd->cdh.novel_method);
200 for (i = 0; i < TEXT_PARAMS; i++)
201 HTONUL(cd->cdh.params[which]);
202 HTONUL(cd->cdh.num_words[0]);
203 HTONUL(cd->cdh.num_words[1]);
204 HTONUL(cd->cdh.num_word_chars[0]);
205 HTONUL(cd->cdh.num_word_chars[1]);
206 HTONUL(cd->cdh.lookback);
207 HTONSI(cd->fast_loaded);
208 }
209
210 unfixup_buffer ();
211
212 save_fast_dict (filename);
213
214 exit (0);
215}
216
217
218
219static void
220unfixup_buffer ()
221{
222 u_long *p;
223 for (p = (u_long *) buffer; (u_long) p < (u_long) cur; p++)
224 {
225 if (IS_FIXUP (p))
226 *p = *p - (u_long) buffer;
227 }
228}
229
230
231
232
233static u_long
234mem_for_aux_dict (compression_dict_header * /*cdh*/, char *filename)
235{
236 int i;
237 u_long mem = sizeof (auxiliary_dict);
238 FILE *aux;
239
240 aux = open_file (filename, TEXT_DICT_AUX_SUFFIX, "rb",
241 MAGIC_AUX_DICT, MG_ABORT); /* [RPAP - Feb 97: WIN32 Port] */
242
243 for (i = 0; i <= 1; i++)
244 {
245 aux_frags_header afh;
246 fread (&afh, sizeof (afh), 1, aux);
247 NTOHUL(afh.num_frags); /* [RPAP - Jan 97: Endian Ordering] */
248 NTOHUL(afh.mem_for_frags); /* [RPAP - Jan 97: Endian Ordering] */
249 mem += afh.num_frags * sizeof (u_char *);
250 mem = ALIGN_SIZE (mem + afh.mem_for_frags, u_char *);
251 fseek (aux, afh.mem_for_frags, SEEK_CUR);
252 }
253 fclose (aux);
254
255 return mem;
256}
257
258
259
260static u_long
261mem_for_words (FILE * dict, compression_dict_header * cdh,
262 comp_frags_header * cfh)
263{
264 u_long mem = 0;
265 long i, lookback;
266 int ptrs_reqd = 0;
267 int mem_reqd = 0;
268
269 lookback = cdh->lookback;
270
271 for (i = cfh->hd.mincodelen; i <= cfh->hd.maxcodelen; i++)
272 {
273 ptrs_reqd += (cfh->hd.lencount[i] + ((1 << lookback) - 1)) >> lookback;
274 mem_reqd += cfh->huff_words_size[i];
275 }
276
277 mem += ptrs_reqd * sizeof (u_char *);
278 mem += (MAX_HUFFCODE_LEN + 1) * sizeof (u_char **);
279 mem += mem_reqd;
280
281 for (i = 0; i < cfh->hd.num_codes; i++)
282 {
283 register int val;
284 for (val = getc (dict) & 0xf; val; val--)
285 getc (dict);
286 }
287 return ALIGN_SIZE (mem, u_char *);
288}
289
290static u_long mem_skip_hd(FILE *dict, u_long mem)
291{ huff_data hd;
292
293 mem += sizeof (hd);
294 Read_Huffman_Data (dict, &hd, NULL, NULL);
295 if (hd.clens)
296 delete hd.clens;
297 mem += hd.num_codes * sizeof (unsigned long);
298 mem += (MAX_HUFFCODE_LEN + 1) * sizeof (unsigned long *);
299 return mem;
300}
301
302static u_long mem_read_cfh(FILE *dict, compression_dict_header *cdh, comp_frags_header *cfh,
303 u_long mem)
304{
305 mem += sizeof (comp_frags_header);
306 Read_cfh (dict, cfh, NULL, NULL);
307
308 /* Don't need to count the space for the clens of the huffman data */
309
310 mem += mem_for_words (dict, cdh, cfh);
311 if (cfh->hd.clens)
312 delete cfh->hd.clens;
313
314 return mem;
315}
316
317
318static u_long
319mem_for_comp_dict (char *filename)
320{
321 u_long mem = sizeof (compression_dict);
322 compression_dict_header cdh;
323 comp_frags_header cfh;
324 FILE *dict;
325 int which;
326 int i; /* [RPAP - Jan 97: Endian Ordering] */
327
328 dict = open_file (filename, TEXT_DICT_SUFFIX, "rb",
329 MAGIC_DICT, MG_ABORT); /* [RPAP - Feb 97: WIN32 Port] */
330
331 fread (&cdh, sizeof (cdh), 1, dict);
332 /* [RPAP - Jan 97: Endian Ordering] */
333 NTOHUL(cdh.dict_type);
334 NTOHUL(cdh.novel_method);
335 for (i = 0; i < TEXT_PARAMS; i++)
336 NTOHUL(cdh.params[i]);
337 NTOHUL(cdh.num_words[0]);
338 NTOHUL(cdh.num_words[1]);
339 NTOHUL(cdh.num_word_chars[0]);
340 NTOHUL(cdh.num_word_chars[1]);
341 NTOHUL(cdh.lookback);
342
343 for (which = 0; which < 2; which++)
344 switch (cdh.dict_type)
345 {
346 case MG_COMPLETE_DICTIONARY:
347 {
348 mem = mem_read_cfh(dict, &cdh, &cfh, mem);
349 }
350 break;
351 case MG_PARTIAL_DICTIONARY:
352 {
353 // huff_data hd;
354 if (cdh.num_words[which])
355 {
356 mem = mem_read_cfh(dict, &cdh, &cfh, mem);
357 }
358
359 mem = mem_skip_hd(dict, mem);
360 mem = mem_skip_hd(dict, mem);
361 }
362 break;
363 case MG_SEED_DICTIONARY:
364 {
365 // huff_data hd;
366 if (cdh.num_words[which])
367 {
368 mem = mem_read_cfh(dict, &cdh, &cfh, mem);
369 }
370 switch (cdh.novel_method)
371 {
372 case MG_NOVEL_HUFFMAN_CHARS:
373 mem = mem_skip_hd(dict, mem);
374 mem = mem_skip_hd(dict, mem);
375 break;
376 case MG_NOVEL_DELTA:
377 break;
378 case MG_NOVEL_HYBRID:
379 break;
380 }
381 break;
382 }
383 }
384 fclose (dict);
385
386 if (cdh.novel_method == MG_NOVEL_DELTA ||
387 cdh.novel_method == MG_NOVEL_HYBRID)
388 mem += mem_for_aux_dict (&cdh, filename);
389
390 return ALIGN_SIZE (mem, u_char *);
391}
392
393
394
395void *
396getmem (u_long size, int align)
397{
398 void *res;
399 cur = (void *) (((u_long) cur + (align - 1)) & (~(align - 1)));
400 res = cur;
401 cur = (char *) cur + size;
402 if ((u_long) cur > (u_long)buffer + mem)
403 FatalError (1, "The buffer was not big enough for the dictionary");
404 return res;
405}
406
407
408
409
410
411
412
413
414
415
416
417static auxiliary_dict *
418LoadAuxDict (compression_dict_header * cdh,
419 char *filename)
420{
421 auxiliary_dict *ad;
422 int i;
423 FILE *aux;
424
425 aux = open_file (filename, TEXT_DICT_AUX_SUFFIX, "rb",
426 MAGIC_AUX_DICT, MG_ABORT); /* [RPAP - Feb 97: WIN32 Port] */
427
428 ad = (auxiliary_dict *) getmem (sizeof (auxiliary_dict), sizeof (u_char *));
429
430 for (i = 0; i <= 1; i++)
431 {
432 unsigned int j;
433 u_char *pos;
434
435 fread (&ad->afh[i], sizeof (aux_frags_header), 1, aux);
436
437 /* [RPAP - Jan 97: Endian Ordering] */
438 NTOHUL(ad->afh[i].num_frags);
439 NTOHUL(ad->afh[i].mem_for_frags);
440
441 ad->word_data[i] = (u_char *) getmem (ad->afh[i].mem_for_frags, 1);
442 FIXUP (&ad->word_data[i]);
443
444 ad->words[i] = (u_char **) getmem (ad->afh[i].num_frags * sizeof (u_char *),
445 sizeof (u_char *));
446 FIXUP (&ad->words[i]);
447
448 fread (ad->word_data[i], ad->afh[i].mem_for_frags, sizeof (u_char), aux);
449
450 pos = ad->word_data[i];
451 for (j = 0; j < ad->afh[i].num_frags; j++)
452 {
453 ad->words[i][j] = pos;
454 FIXUP (&ad->words[i][j]);
455 pos += *pos + 1;
456 }
457 if (cdh->novel_method == MG_NOVEL_HYBRID)
458 {
459 int num;
460 num = 1;
461 ad->blk_start[i][0] = 0;
462 ad->blk_end[i][0] = cdh->num_words[i] - 1;
463 while (num < 33)
464 {
465 ad->blk_start[i][num] = ad->blk_end[i][num - 1] + 1;
466 ad->blk_end[i][num] = ad->blk_start[i][num] +
467 (ad->blk_end[i][num - 1] - ad->blk_start[i][num - 1]) * 2;
468 num++;
469 }
470 }
471 }
472 fclose (aux);
473 return (ad);
474}
475
476
477
478
479
480static u_char ***
481ReadInWords (FILE * dict, compression_dict * cd,
482 comp_frags_header * cfh, u_char ** escape)
483{
484 int i, lookback;
485 int ptrs_reqd = 0;
486 int mem_reqd = 0;
487 int num_set[MAX_HUFFCODE_LEN + 1];
488 u_char *next_word[MAX_HUFFCODE_LEN + 1];
489 u_char **vals;
490 u_char ***values;
491 u_char word[MAXWORDLEN + 1];
492 u_char last_word[MAX_HUFFCODE_LEN + 1][MAXWORDLEN + 1];
493
494 lookback = cd->cdh.lookback;
495
496 for (i = cfh->hd.mincodelen; i <= cfh->hd.maxcodelen; i++)
497 {
498 ptrs_reqd += (cfh->hd.lencount[i] + ((1 << lookback) - 1)) >> lookback;
499 mem_reqd += cfh->huff_words_size[i];
500 }
501
502 vals = (u_char **) getmem (ptrs_reqd * sizeof (*vals), sizeof (u_char *));
503
504 values = (u_char ***) getmem ((MAX_HUFFCODE_LEN + 1) * sizeof (u_char **), sizeof (u_char **));
505
506 next_word[0] = (u_char *) getmem (mem_reqd, sizeof (char));
507
508 cd->MemForCompDict += ptrs_reqd * sizeof (*vals) +
509 (MAX_HUFFCODE_LEN + 1) * sizeof (u_char **) +
510 mem_reqd;
511
512 values[0] = vals;
513 FIXUP (&values[0]);
514 values[0][0] = next_word[0];
515 FIXUP (&values[0][0]);
516 for (i = 1; i <= cfh->hd.maxcodelen; i++)
517 {
518 int next_start = (values[i - 1] - vals) +
519 ((cfh->hd.lencount[i - 1] + ((1 << lookback) - 1)) >> lookback);
520 values[i] = &vals[next_start];
521 FIXUP (&values[i]);
522 next_word[i] = next_word[i - 1] + cfh->huff_words_size[i - 1];
523 values[i][0] = next_word[i];
524 FIXUP (&values[i][0]);
525 }
526
527 bzero ((char *) num_set, sizeof (num_set));
528
529 for (i = 0; i < cfh->hd.num_codes; i++)
530 {
531 register int val, copy;
532 register int len = cfh->hd.clens[i];
533 val = getc (dict);
534 copy = (val >> 4) & 0xf;
535 val &= 0xf;
536
537 fread (word + copy + 1, sizeof (u_char), val, dict);
538 *word = val + copy;
539
540 if ((num_set[len] & ((1 << lookback) - 1)) == 0)
541 {
542 values[len][num_set[len] >> lookback] = next_word[len];
543 FIXUP (&values[len][num_set[len] >> lookback]);
544 memcpy (next_word[len], word, *word + 1);
545 if (escape && i == cfh->hd.num_codes - 1)
546 {
547 *escape = next_word[len];
548 FIXUP (escape);
549 }
550 next_word[len] += *word + 1;
551 }
552 else
553 {
554 copy = prefixlen (last_word[len], word);
555 memcpy (next_word[len] + 1, word + copy + 1, *word - copy);
556 *next_word[len] = (copy << 4) + (*word - copy);
557 if (escape && i == cfh->hd.num_codes - 1)
558 {
559 *escape = next_word[len];
560 FIXUP (escape);
561 }
562 next_word[len] += (*word - copy) + 1;
563 }
564 memcpy (last_word[len], word, *word + 1);
565 num_set[len]++;
566 }
567 if (cfh->hd.clens)
568 delete cfh->hd.clens;
569 cfh->hd.clens = NULL;
570 return values;
571}
572
573
574static unsigned long **
575Generate_Fast_Huffman_Vals (huff_data * data, u_long * mem)
576{
577 int i;
578 unsigned long *fcode[MAX_HUFFCODE_LEN + 1];
579 unsigned long **values;
580 unsigned long *vals;
581
582 if (!data)
583 return (NULL);
584 vals = (unsigned long *) getmem (data->num_codes * sizeof (*vals), sizeof (long *));
585 values = (unsigned long **) getmem ((MAX_HUFFCODE_LEN + 1) * sizeof (unsigned long *),
586 sizeof (long *));
587
588 bzero ((char *) values, (MAX_HUFFCODE_LEN + 1) * sizeof (unsigned long *));
589
590 if (mem)
591 *mem += data->num_codes * sizeof (*vals) +
592 (MAX_HUFFCODE_LEN + 1) * sizeof (unsigned long *);
593
594 fcode[0] = values[0] = &vals[0];
595 FIXUP (&values[0]);
596 for (i = 1; i <= data->maxcodelen; i++)
597 {
598 fcode[i] = values[i] = &vals[(values[i - 1] - vals) + data->lencount[i - 1]];
599 FIXUP (&values[i]);
600 }
601
602 for (i = 0; i < data->num_codes; i++)
603 if (data->clens[i])
604 *fcode[(int) (data->clens[i])]++ = i;
605 return (values);
606}
607
608
609static void load_read_huffman(FILE *dict, compression_dict *cd, int which)
610{
611 huff_data *hd;
612 u_long **vals;
613
614 hd = (huff_data *) getmem (sizeof (huff_data), sizeof (char *));
615 cd->MemForCompDict += sizeof (huff_data);
616 Read_Huffman_Data (dict, hd, &cd->MemForCompDict, NULL);
617 vals = Generate_Fast_Huffman_Vals (hd, &cd->MemForCompDict);
618 cd->chars_huff[which] = hd;
619 FIXUP (&cd->chars_huff[which]);
620 cd->chars_vals[which] = vals;
621 FIXUP (&cd->chars_vals[which]);
622 if (hd->clens)
623 delete hd->clens;
624 hd->clens = NULL;
625}
626
627static void load_read_words(FILE *dict, compression_dict *cd, int which, int fixescape)
628{
629 cd->cfh[which] = (comp_frags_header *) getmem (sizeof (*cd->cfh[which]), sizeof (u_char *));
630 cd->MemForCompDict += sizeof (*cd->cfh[which]);
631 Read_cfh (dict, cd->cfh[which], &cd->MemForCompDict, NULL);
632
633 cd->values[which] = ReadInWords (dict, cd, cd->cfh[which], NULL);
634 FIXUP (&cd->cfh[which]);
635 FIXUP (&cd->values[which]);
636 if (fixescape)
637 { FIXUP(&cd->escape[which]);
638 }
639 else
640 {
641 cd->escape[which] = NULL;
642 }
643}
644
645static void
646load_comp_dict (char *filename)
647{
648 FILE *dict;
649 int which;
650 compression_dict *cd;
651
652 cd = (compression_dict *) getmem (sizeof (compression_dict), sizeof (u_char *));
653 cd->fast_loaded = 1;
654
655 dict = open_file (filename, TEXT_DICT_SUFFIX, "rb",
656 MAGIC_DICT, MG_ABORT); /* [RPAP - Feb 97: WIN32 Port] */
657
658 Read_cdh (dict, &cd->cdh, NULL, NULL);
659
660 for (which = 0; which < 2; which++)
661 switch (cd->cdh.dict_type)
662 {
663 case MG_COMPLETE_DICTIONARY:
664 {
665 load_read_words(dict, cd, which, 0);
666 }
667 break;
668 case MG_PARTIAL_DICTIONARY:
669 {
670 if (cd->cdh.num_words[which])
671 {
672 load_read_words(dict, cd, which, 1);
673 }
674
675 load_read_huffman(dict, cd, which);
676 load_read_huffman(dict, cd, which);
677 }
678 break;
679 case MG_SEED_DICTIONARY:
680 {
681 if (cd->cdh.num_words[which])
682 {
683 load_read_words(dict, cd, which, 1);
684 }
685 switch (cd->cdh.novel_method)
686 {
687 case MG_NOVEL_HUFFMAN_CHARS:
688 load_read_huffman(dict, cd, which);
689 load_read_huffman(dict, cd, which);
690 break;
691 case MG_NOVEL_DELTA:
692 break;
693 case MG_NOVEL_HYBRID:
694 break;
695 }
696 break;
697 }
698 }
699 fclose (dict);
700
701
702 if (cd->cdh.novel_method == MG_NOVEL_DELTA ||
703 cd->cdh.novel_method == MG_NOVEL_HYBRID)
704 {
705 cd->ad = LoadAuxDict (&cd->cdh, filename);
706 FIXUP (&cd->ad);
707 }
708}
709
710
711static void
712save_fast_dict (char *filename)
713{
714 FILE *fdict;
715
716 fdict = create_file (filename, TEXT_DICT_FAST_SUFFIX, "wb",
717 MAGIC_FAST_DICT, MG_ABORT); /* [RPAP - Feb 97: WIN32 Port] */
718
719 {
720 u_long *p;
721 for (p = (u_long *) buffer; (u_long) p < (u_long) cur; p++)
722 {
723 if (IS_FIXUP (p))
724 HTONUL(*p);
725 }
726 }
727
728 /* [RPAP - Jan 97: Endian Ordering] */
729 HTONUL(mem);
730 HTONUL(fixup_mem);
731
732 fwrite (&mem, sizeof (mem), 1, fdict);
733 fwrite (&fixup_mem, sizeof (fixup_mem), 1, fdict);
734
735 /* [RPAP - Jan 97: Endian Ordering] */
736 NTOHUL(mem);
737 NTOHUL(fixup_mem);
738
739 fwrite (buffer, sizeof (u_char), mem, fdict);
740 fwrite (fixup, sizeof (u_char), fixup_mem, fdict);
741
742 fclose (fdict);
743}
Note: See TracBrowser for help on using the repository browser.