~ubuntu-branches/ubuntu/hardy/dbacl/hardy

« back to all changes in this revision

Viewing changes to src/dbacl.c

  • Committer: Bazaar Package Importer
  • Author(s): Zak B. Elep
  • Date: 2006-03-26 22:35:35 UTC
  • mfrom: (1.1.2 upstream) (2.1.1 etch)
  • Revision ID: james.westby@ubuntu.com-20060326223535-bo3m96paoczzz59n
Tags: 1.12-1
* New upstream release
  + `dbacl -V' now exits with status 0.  (Closes: #339394)
* debian/rules:
  + Upstream now fixes TREC file permissions.  However some new scripts got
    added, so this time its a a+x fix instead of a-x.
* debian/patches:
  + Removed 10_slang2_conversion.patch from Clint, now merged upstream.
  + Updated 20_autotools_update.patch .

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
 
43
43
#if defined HAVE_UNISTD_H
44
44
#include <unistd.h> 
 
45
#include <sys/types.h>
45
46
#endif
46
47
 
47
48
#include <locale.h>
69
70
extern hash_count_t default_max_grow_tokens;
70
71
 
71
72
hash_bit_count_t decimation;
 
73
token_count_t ftreshold = 0;
72
74
 
73
75
learner_t learner;
74
76
dirichlet_t dirichlet;
132
134
 * MISCELLANEOUS FUNCTIONS                                 *
133
135
 ***********************************************************/
134
136
 
135
 
static void usage(char **argv) {
 
137
static void usage(/*@unused@*/ char **argv) {
136
138
  fprintf(stderr, 
137
139
          "\n");
138
140
  fprintf(stderr, 
176
178
/* note: don't forget to flush after each line */
177
179
void line_score_categories(char *textbuf) {
178
180
  category_count_t i;
179
 
  int map;
 
181
  category_count_t map;
180
182
  score_t c, cmax;
181
183
 
182
184
  if( !textbuf ) { return; }
219
221
          if( u_options & (1<<U_OPTION_VERBOSE) ) {
220
222
            fprintf(stdout, "%s %6.2" FMT_printf_score_t " * %-4.1f ", 
221
223
                    cat[i].filename, 
222
 
                    -CVT_BITS(cat[i].score/cat[i].complexity), 
 
224
                    -nats2bits(cat[i].score/cat[i].complexity), 
223
225
                    cat[i].complexity);
224
226
          } else {
225
227
            fprintf(stdout, "%s %6.2" FMT_printf_score_t " ", 
226
 
                    cat[i].filename, -CVT_BITS(cat[i].score));
 
228
                    cat[i].filename, -nats2bits(cat[i].score));
227
229
          }
228
230
        }
229
231
        fprintf(stdout, "%s", textbuf);
247
249
    cat[i].score_s2 = 0.0;
248
250
    cat[i].score_div = 0.0;
249
251
    cat[i].score_shannon = 0.0;
 
252
    cat[i].score_exp = 0.0;
250
253
    cat[i].complexity = 0.0;
251
254
    cat[i].fcomplexity = 0;
252
255
  }
266
269
  for(i = 0; i < cat_count; i++) {
267
270
    if(cmax < cat[i].score) {
268
271
      cmax = cat[i].score;
269
 
      exit_code = i;
 
272
      exit_code = (int)i;
270
273
    }
271
274
    /* finish sample variance calculation */
272
275
    cat[i].score_s2 = (cat[i].complexity * cat[i].score_s2 -
322
325
          fprintf(stdout, "%s ( %5.2" FMT_printf_score_t 
323
326
                  " # %5.2" FMT_printf_score_t " )* %-.1f ", 
324
327
                  cat[i].filename, 
325
 
                  -CVT_BITS(cat[i].score/cat[i].complexity),
326
 
                  CVT_BITS(sqrt(cat[i].score_s2/cat[i].complexity)),
 
328
                  -nats2bits(cat[i].score/cat[i].complexity),
 
329
                  nats2bits(sqrt(cat[i].score_s2/cat[i].complexity)),
327
330
                  cat[i].complexity);
328
331
        } else {
329
332
          fprintf(stdout, "%s %5.2" FMT_printf_score_t " * %-.1f ", 
330
333
                  cat[i].filename, 
331
 
                  -CVT_BITS(cat[i].score/cat[i].complexity),
 
334
                  -nats2bits(cat[i].score/cat[i].complexity),
332
335
                  cat[i].complexity);
333
336
        }
334
337
        if( u_options & (1<<U_OPTION_CONFIDENCE) ) {
338
341
      } else {
339
342
        fprintf(stdout, "%s %5.2" FMT_printf_score_t " ", 
340
343
                cat[i].filename,
341
 
                -CVT_BITS(cat[i].score));
 
344
                -nats2bits(cat[i].score));
342
345
      }
343
346
    }
344
347
    fprintf(stdout, "\n");
345
348
 
346
349
    if( u_options & (1<<U_OPTION_APPEND) ) {
347
 
      no_title = 1;
 
350
      no_title = (bool_t)1;
348
351
      for(i = 0; i < cat_count; i++) {
349
352
        if( cat[i].model_num_docs > 0 ) {
350
353
          if( no_title ) {
351
354
            fprintf(stdout, "# mean_complexity ");
352
 
            no_title = 0;
 
355
            no_title = (bool_t)0;
353
356
          }
354
357
          fprintf(stdout, "%s %5.2" FMT_printf_score_t " ", 
355
358
                  cat[i].filename, 
368
371
          fprintf(stdout, "%s ( %5.2" FMT_printf_score_t " + "
369
372
                  "%-5.2" FMT_printf_score_t,
370
373
                  cat[i].filename, 
371
 
                  CVT_BITS(cat[i].score_div),
372
 
                  CVT_BITS(cat[i].score_shannon));
 
374
                  nats2bits(cat[i].score_div),
 
375
                  nats2bits(cat[i].score_shannon));
373
376
          if( u_options & (1<<U_OPTION_VAR) ) {
374
377
            fprintf(stdout, " # %5.2" FMT_printf_score_t,
375
 
                    CVT_BITS(sqrt(cat[i].score_s2/cat[i].complexity)));
 
378
                    nats2bits(sqrt(cat[i].score_s2/cat[i].complexity)));
376
379
          }
377
380
          fprintf(stdout, " )* %-6.1f", cat[i].complexity);
378
381
          if( u_options & (1<<U_OPTION_CONFIDENCE) ) {
395
398
 
396
399
        cmax = 1.0;
397
400
        for(i = 0; i < cat_count; i++) {
398
 
          if( i != exit_code ) {
 
401
          if( (int)i != exit_code ) {
399
402
            /* c is a standard normal variable */
400
403
            c = (-cat[i].score/cat[i].complexity - 
401
404
                 -cat[exit_code].score/cat[exit_code].complexity) /
429
432
 * FILE MANAGEMENT FUNCTIONS                               *
430
433
 ***********************************************************/
431
434
 
432
 
bool_t check_magic_write(char *path, char *magic, int len) {
 
435
bool_t check_magic_write(char *path, char *magic, size_t len) {
433
436
  FILE *output;
434
437
  char buf[MAGIC_BUFSIZE];
435
438
 
441
444
      errormsg(E_ERROR,"the file %s is already used for something, "
442
445
               "use another filename. Nothing written.\n", path);
443
446
      fclose(output);
444
 
      return 0;
 
447
      return (bool_t)0;
445
448
    } else {
446
449
      /* it's an existing category file */
447
450
      fclose(output);
448
451
    }
449
452
  }
450
 
  return 1;
 
453
  return (bool_t)1;
451
454
}
452
455
 
453
456
/* the standard tmpfile() call doesn't tell the filename,
458
461
   3) if you want a particular directory, prepend it to tmplate.
459
462
   4) file is opened for read/write, but truncated to zero.
460
463
*/
461
 
FILE *mytmpfile(const char *tmplate, char **tmpname) {
 
464
/*@null@*/ 
 
465
FILE *mytmpfile(const char *tmplate, /*@out@*/ char **tmpname) {
462
466
  FILE *result = NULL;
463
 
  int i, fd, l;
 
467
  size_t l;
 
468
  int i, fd;
 
469
 
464
470
  l = strlen(tmplate);
465
471
  *tmpname = (char *)malloc(sizeof(char)*(l + 8));
466
472
  if( *tmpname ) {
492
498
bool_t myrename(const char *src, const char *dest) {
493
499
#if defined ATOMIC_CATSAVE
494
500
  /* the rename is atomic on posix */
495
 
  return (rename(src, dest) == 0);
 
501
  return (bool_t)(rename(src, dest) == 0);
496
502
#else
497
 
  return 1; /* just pretend */
 
503
  return (bool_t)1; /* just pretend */
498
504
#endif
499
505
}
500
506
 
506
512
  token_order_t s;
507
513
  char *p;
508
514
 
509
 
  bool_t ok = 1;
 
515
  bool_t ok = (bool_t)1;
510
516
 
511
517
  /* print out standard category file headers */
512
518
  ok = ok && 
514
520
                 (m_options & (1<<M_OPTION_REFMODEL)) ? "(ref)" : ""));
515
521
  ok = ok &&
516
522
    (0 < fprintf(output, 
517
 
                 MAGIC2_o, learner->divergence, learner->logZ, learner->max_order,
 
523
                 MAGIC2_o, learner->divergence, learner->logZ, 
 
524
                 (short int)learner->max_order,
518
525
                 (m_options & (1<<M_OPTION_MULTINOMIAL)) ? "multinomial" : "hierarchical" ));
519
526
  ok = ok &&
520
527
    (0 < fprintf(output, MAGIC3, 
532
539
  /* print out any regexes we might need */
533
540
  for(c = 0; c < regex_count; c++) {
534
541
    /* write the bitmap */
 
542
    smb[0] = '\0';
535
543
    for(p = smb, s = 1; s <= MAX_SUBMATCH; s++) {
536
544
      if( re[c].submatches & (1<<s) ) {
537
 
        *p++ = s + '0';
 
545
        *p++ = (char)s + '0';
538
546
      }
539
547
    }
540
548
    *p = '\0';
572
580
  char *tempname = NULL;
573
581
 
574
582
  bool_t ok;
575
 
  int n;
 
583
  size_t n;
576
584
  c_item_t ci;
577
585
  c_item_t *ci_ptr;
578
586
  myweight_t shval;
579
 
  myweight_t *shval_ptr;
 
587
  myweight_t *shval_ptr = NULL;
580
588
 
581
 
  size_t mmap_offset = 0;
 
589
  long mmap_offset = 0;
582
590
  size_t mmap_length = 0;
583
591
  byte_t *mmap_start = NULL;
584
592
  
589
597
  
590
598
  /* don't overwrite data files */
591
599
  if( !check_magic_write(learner->filename, MAGIC1, 10) ) {
592
 
    exit(0);
 
600
    exit(1);
593
601
  }
594
602
  
595
603
  /* In case we have both the -m and -o switches we try to write the
599
607
     Also, we don't try to create the file - if the file doesn't exist,
600
608
     we won't gain much time by using mmap on that single occasion. */
601
609
  if( *online && (u_options & (1<<U_OPTION_MMAP)) ) {
602
 
    ok = 0; 
 
610
    ok = (bool_t)0; 
603
611
    output = fopen(learner->filename, "r+b");
604
612
    if( output ) {
605
 
      ok = 1;
 
613
      ok = (bool_t)1;
606
614
      if( out_iobuf ) {
607
 
        setvbuf(output, (char *)out_iobuf, _IOFBF, BUFFER_MAG * system_pagesize);
 
615
        setvbuf(output, (char *)out_iobuf, (int)_IOFBF, (size_t)(BUFFER_MAG * system_pagesize));
608
616
      }
609
617
 
610
618
      ok = ok && write_category_headers(learner, output);
613
621
      }
614
622
      /* now mmap the file and write out the arrays real quick */
615
623
      mmap_offset = ftell(output);
616
 
      if( mmap_offset == -1 ) { 
 
624
      if( mmap_offset == (long)-1 ) { 
617
625
        ok = 0;
618
626
        goto skip_mmap; 
619
627
      }
620
 
      mmap_length = mmap_offset + (ASIZE * ASIZE * SIZEOF_DIGRAMS) + 
 
628
      mmap_length = (size_t)mmap_offset + (ASIZE * ASIZE * SIZEOF_DIGRAMS) + 
621
629
        learner->max_tokens * sizeof(c_item_t);
622
630
 
623
 
      ok = ok && (-1 != ftruncate(fileno(output), mmap_length));
 
631
      ok = ok && (-1 != ftruncate(fileno(output), (off_t)mmap_length));
624
632
      if( !ok ) { 
625
633
        goto skip_mmap; 
626
634
      }
627
635
 
628
636
      mmap_start = (byte_t *)MMAP(0, mmap_length, 
629
637
                        PROT_READ|PROT_WRITE, MAP_SHARED, fileno(output), 0);
 
638
      if( mmap_start == MAP_FAILED ) { mmap_start = NULL; }
630
639
      if( !mmap_start ) { 
631
640
        ok = 0; 
632
641
        goto skip_mmap;
682
691
 
683
692
  /* this keeps track to see if writing is successful, 
684
693
     it's not foolproof, but probably good enough */
685
 
  ok = 1; 
 
694
  ok = (bool_t)1; 
686
695
 
687
696
  output = mytmpfile(learner->filename, &tempname);
688
697
  if( output ) {
689
698
 
690
699
    if( out_iobuf ) {
691
 
      setvbuf(output, (char *)out_iobuf, _IOFBF, BUFFER_MAG * system_pagesize);
 
700
      setvbuf(output, (char *)out_iobuf, (int)_IOFBF, (size_t)(BUFFER_MAG * system_pagesize));
692
701
    }
693
702
 
694
703
    ok = ok && write_category_headers(learner, output);
707
716
        for(j = 0; j < ASIZE; j++) {
708
717
          shval = HTON_DIGRAM(PACK_DIGRAMS(learner->dig[i][j]));
709
718
          for(n = 0; n < 1; ) {
710
 
            if( 0 > (n = fwrite(&shval, SIZEOF_DIGRAMS, 1, output)) ) {
 
719
            if( 0 > (n = fwrite(&shval, SIZEOF_DIGRAMS, (size_t)1, output)) ) {
711
720
              ok = 0;
712
721
              goto skip_remaining;
713
722
            } 
728
737
        ci.lam = HTON_LAMBDA(ci.lam);
729
738
 
730
739
        for(n = 0; n < 1; ) {
731
 
          if( 0 > (n = fwrite(&ci, sizeof(ci), 1, output)) ) {
 
740
          if( 0 > (n = fwrite(&ci, sizeof(ci), (size_t)1, output)) ) {
732
741
            ok = 0;
733
742
            goto skip_remaining;
734
743
          } 
780
789
      (xcat->max_order == learner->max_order) &&
781
790
      (xcat->max_hash_bits == learner->max_hash_bits) ) {
782
791
    max = 0;
 
792
    buf[0] = '\0';
783
793
    /* we only overwrite the header if there's exactly enough space */
784
794
    /* we must overwrite 3 lines which all start with # */
785
795
    q = p = strchr((char *)xcat->mmap_start + 1, '#');
786
796
    if( p ) {
787
 
      n = snprintf(buf, REPLBUF - max, MAGIC2_o, 
788
 
                   learner->divergence, learner->logZ, learner->max_order,
 
797
      n = snprintf(buf, (size_t)(REPLBUF - max), MAGIC2_o, 
 
798
                   learner->divergence, learner->logZ, 
 
799
                   (short int)learner->max_order,
789
800
                   (m_options & (1<<M_OPTION_MULTINOMIAL)) ? "multinomial" : "hierarchical" );
790
801
      max += n;
791
802
    }
792
803
    q = strchr(q + 1, '#');
793
804
    if( q && (max < REPLBUF) ) {
794
 
      n = snprintf(buf + max, REPLBUF - max, MAGIC3, 
 
805
      n = snprintf(buf + max, (size_t)(REPLBUF - max), MAGIC3, 
795
806
                   (short int)learner->max_hash_bits, 
796
807
                   (long int)learner->full_token_count, 
797
808
                   (long int)learner->unique_token_count,
800
811
    }
801
812
    q = strchr(q + 1, '#');
802
813
    if( q && (max < REPLBUF) ) {
803
 
      n = snprintf(buf + max, REPLBUF - max, MAGIC8_o, 
 
814
      n = snprintf(buf + max, (size_t)(REPLBUF - max), MAGIC8_o, 
804
815
                   learner->shannon, 
805
816
                   learner->alpha, learner->beta,
806
817
                   learner->mu, learner->s2);
814
825
        unlink the category */
815
826
 
816
827
      /* header */
817
 
      memcpy(p, buf, max);
 
828
      memcpy(p, buf, (size_t)max);
818
829
 
819
830
      /* character frequencies */
820
831
      shval_ptr = (myweight_t *)(xcat->mmap_start + xcat->mmap_offset - 
857
868
bool_t tmp_seek_start(learner_t *learner) {
858
869
  if( learner->tmp.mmap_start ) {
859
870
    learner->tmp.mmap_cursor = learner->tmp.mmap_offset;
860
 
    return 1;
 
871
    return (bool_t)1;
861
872
  } else if( learner->tmp.file ) {
862
873
    clearerr(learner->tmp.file);
863
874
    return (fseek(learner->tmp.file, learner->tmp.offset, SEEK_SET) == 0);
864
875
  }
865
 
  return 0;
 
876
  return (bool_t)0;
866
877
}
867
878
 
868
879
bool_t tmp_seek_end(learner_t *learner) {
869
880
  if( learner->tmp.mmap_start ) {
870
881
    learner->tmp.mmap_cursor = learner->tmp.mmap_offset + learner->tmp.used;
871
 
    return 1;
 
882
    return (bool_t)1;
872
883
  } else if( learner->tmp.file ) {
873
884
    return (fseek(learner->tmp.file, 
874
885
                  learner->tmp.offset + learner->tmp.used, SEEK_SET) == 0);
875
886
  }
876
 
  return 0;
 
887
  return (bool_t)0;
877
888
}
878
889
 
879
890
long tmp_get_pos(learner_t *learner) {
882
893
  } else if( learner->tmp.file ) {
883
894
    return ftell(learner->tmp.file) - learner->tmp.offset;
884
895
  }
885
 
  return 0;
 
896
  return (bool_t)0;
886
897
}
887
898
 
888
899
size_t tmp_read_block(learner_t *learner, byte_t *buf, size_t bufsiz,
889
900
                      const byte_t **startp) {
890
 
  size_t left = learner->tmp.used - tmp_get_pos(learner);
891
 
  if( bufsiz > left ) { bufsiz = (left >= 0) ? left : 0; }
 
901
  long left = learner->tmp.used - tmp_get_pos(learner);
 
902
  if( bufsiz > (size_t)left ) { bufsiz = (left >= 0) ? (size_t)left : 0; }
892
903
  if( learner->tmp.mmap_start ) {
893
904
/*     memcpy(buf, learner->tmp.mmap_start + learner->tmp.mmap_cursor, bufsiz); */
894
905
    *startp = learner->tmp.mmap_start + learner->tmp.mmap_cursor;
931
942
        (byte_t *)MMAP(learner->tmp.mmap_start, learner->tmp.mmap_length,
932
943
                       PROT_READ|PROT_WRITE, MAP_SHARED,
933
944
                       fileno(learner->tmp.file), offset);
 
945
      if( learner->tmp.mmap_start == MAP_FAILED ) { learner->tmp.mmap_start = NULL; }
934
946
      if( !learner->tmp.mmap_start ) {
935
947
        if( u_options & (1<<U_OPTION_VERBOSE) ) {
936
948
          errormsg(E_WARNING, "could not mmap token file after resize\n");
954
966
                MADV_SEQUENTIAL|MADV_WILLNEED);
955
967
      }
956
968
      /* if there was a fatal error, we simply don't return */
957
 
      return 1;
 
969
      return (bool_t)1;
958
970
    }
959
971
  }
960
 
  return 0;
 
972
  return (bool_t)0;
961
973
}
962
974
 
963
975
/* assume we are at the end of the token list and there is enough room */
1110
1122
    mmap_start =
1111
1123
      (byte_t *)MMAP(0, mmap_hash_offset,
1112
1124
                     PROT_READ|PROT_WRITE, MAP_SHARED, fileno(input), 0);
 
1125
    if( mmap_start == MAP_FAILED ) { mmap_start = NULL; }
1113
1126
    if( mmap_start ) {
1114
1127
      /* first we overwrite the learner struct with the contents of
1115
1128
         the mmapped region */
1121
1134
        (byte_t *)MMAP(mmap_start,
1122
1135
                       mmap_hash_offset + sizeof(l_item_t) * learner->max_tokens,
1123
1136
                       PROT_READ|PROT_WRITE, MAP_SHARED, fileno(input), 0);
 
1137
      if( mmap_start == MAP_FAILED ) { mmap_start = NULL; }
1124
1138
      if( mmap_start ) {
1125
1139
        /* now fill some member variables */
1126
1140
        learner->mmap_start = mmap_start;
1318
1332
  if( input ) {
1319
1333
 
1320
1334
    if( out_iobuf ) {
1321
 
      setvbuf(input, (char *)out_iobuf, _IOFBF, BUFFER_MAG * system_pagesize);
 
1335
      setvbuf(input, (char *)out_iobuf, (int)_IOFBF, (size_t)(BUFFER_MAG * system_pagesize));
1322
1336
    }
1323
1337
 
1324
1338
    if( !fgets(buf, MAGIC_BUFSIZE, input) ||
1375
1389
          (byte_t *)MMAP(0, learner->tmp.mmap_length,
1376
1390
                         PROT_READ|PROT_WRITE, MAP_SHARED,
1377
1391
                         fileno(learner->tmp.file), offset);
 
1392
        if( learner->tmp.mmap_start == MAP_FAILED ) { learner->tmp.mmap_start = NULL; }
1378
1393
        if( learner->tmp.mmap_start ) {
1379
1394
          MLOCK(learner->tmp.mmap_start, learner->tmp.mmap_length);
1380
1395
          MADVISE(learner->tmp.mmap_start, learner->tmp.mmap_length,
1470
1485
  if( output ) {
1471
1486
 
1472
1487
    if( out_iobuf ) {
1473
 
      setvbuf(output, (char *)out_iobuf, _IOFBF, BUFFER_MAG * system_pagesize);
 
1488
      setvbuf(output, (char *)out_iobuf, (int)_IOFBF, (size_t)(BUFFER_MAG * system_pagesize));
1474
1489
    }
1475
1490
 
1476
1491
    ok = 1;
1702
1717
                  "%s ( %5.2" FMT_printf_score_t " + "
1703
1718
                  "%-5.2" FMT_printf_score_t " )* %-d \n",
1704
1719
                  "reservoir",
1705
 
                  -CVT_BITS(score),
1706
 
                  CVT_BITS(empl->shannon),
 
1720
                  -nats2bits(score),
 
1721
                  nats2bits(empl->shannon),
1707
1722
                  empl->top);
1708
1723
        }
1709
1724
 
1749
1764
            " alpha %" FMT_printf_score_t 
1750
1765
            " beta %" FMT_printf_score_t "\n",
1751
1766
            (long int)effective_count, 
1752
 
            CVT_BITS(learner->shannon), 
1753
 
            CVT_BITS(learner->mu), 
1754
 
            CVT_BITS(learner->s2), 
1755
 
            CVT_BITS(learner->alpha),
1756
 
            CVT_BITS(learner->beta));
 
1767
            nats2bits(learner->shannon), 
 
1768
            nats2bits(learner->mu), 
 
1769
            nats2bits(learner->s2), 
 
1770
            nats2bits(learner->alpha),
 
1771
            nats2bits(learner->beta));
1757
1772
  }
1758
1773
 
1759
1774
}
1902
1917
 
1903
1918
      if( i->count < K_TOKEN_COUNT_MAX ) { 
1904
1919
        i->count++; 
 
1920
        if( learner->t_max < i->count ) {
 
1921
          learner->t_max = i->count;
 
1922
        }
1905
1923
        if( m_options & (1<<M_OPTION_CALCENTROPY) ) {
1906
1924
          if( (learner->doc.emp.top < learner->doc.emp.max) ||
1907
1925
              emplist_grow(&learner->doc.emp) ) {
1969
1987
  learner->max_hash_bits = default_max_hash_bits;
1970
1988
  learner->full_token_count = 0;
1971
1989
  learner->unique_token_count = 0;
 
1990
  learner->t_max = 0;
 
1991
  learner->b_count = 0;
1972
1992
  learner->logZ = 0.0;
1973
1993
  learner->shannon = 0.0;
1974
1994
  learner->alpha = 0.0;
2057
2077
      learner->tmpiobuf = (void *)valloc(BUFFER_MAG * system_pagesize);
2058
2078
#endif
2059
2079
      if( learner->tmp.iobuf ) {
2060
 
        setvbuf(learner->tmp.file, (char *)learner->tmp.iobuf, _IOFBF, 
2061
 
                BUFFER_MAG * system_pagesize);
 
2080
        setvbuf(learner->tmp.file, (char *)learner->tmp.iobuf, (int)_IOFBF, 
 
2081
                (size_t)(BUFFER_MAG * system_pagesize));
2062
2082
      }
2063
2083
    }
2064
2084
 
2104
2124
      learner->doc.reservoir[i].stack = NULL;
2105
2125
    }
2106
2126
  }
 
2127
 
 
2128
  if( learner->tmp.file ) {
 
2129
    fclose(learner->tmp.file);
 
2130
    learner->tmp.file = NULL;
 
2131
  }
 
2132
 
 
2133
  cleanup_tempfiles();
2107
2134
}
2108
2135
 
2109
2136
/* calculates the most probable Dirichlet parameters 
2910
2937
 
2911
2938
            old_lam = UNPACK_LAMBDA(i->lam);
2912
2939
 
2913
 
 
2914
 
            /* "iterative scaling" lower bound */
2915
 
            new_lam = (log((score_t)i->count) - logXi -  
2916
 
                      UNPACK_RWEIGHTS(i->tmp.min.dref))/R + logzonr -
2917
 
              UNPACK_LWEIGHTS(i->tmp.min.ltrms);
 
2940
            if( (i->typ.order == 1) || (i->count > ftreshold) ) {
 
2941
              /* "iterative scaling" lower bound */
 
2942
              new_lam = (log((score_t)i->count) - logXi -  
 
2943
                         UNPACK_RWEIGHTS(i->tmp.min.dref))/R + logzonr -
 
2944
                UNPACK_LWEIGHTS(i->tmp.min.ltrms);
 
2945
            } else {
 
2946
              new_lam = 0.0;
 
2947
            }
2918
2948
 
2919
2949
            if( isnan(new_lam) ) {
2920
2950
              /* precision problem, just ignore, don't change lambda */
3009
3039
          learner->alpha, learner->beta,
3010
3040
          learner->mu, learner->s2);
3011
3041
 
 
3042
  fprintf(out, MAGIC9, (long int)learner->t_max, (long int)learner->b_count);
 
3043
 
3012
3044
  /* print out any regexes we might need */
3013
3045
  for(c = 0; c < regex_count; c++) {
3014
3046
    /* write the bitmap */
3027
3059
 
3028
3060
  fprintf(out, MAGIC6); 
3029
3061
 
3030
 
  fprintf(out, "# lambda | dig_ref | count | id     | token\n");
 
3062
  fprintf(out, MAGIC_DUMP);
3031
3063
 
3032
3064
 
3033
3065
  /* now go through hash printing values */
3046
3078
          /* now write weight in hash */
3047
3079
          id = hash_full_token(tok);
3048
3080
          k = find_in_learner(learner, id); /* guaranteed to be found */
3049
 
          fprintf(out, "%9.3f %9.3f %7d %8lx ", 
 
3081
          fprintf(out, MAGIC_DUMPTBL_o, 
3050
3082
                  (weight_t)UNPACK_LAMBDA(k->lam), 
3051
3083
                  UNPACK_RWEIGHTS(k->tmp.min.dref), k->count, 
3052
3084
                  (long unsigned int)k->id);
3156
3188
    errormsg(E_WARNING,
3157
3189
            "no tokens matched - have I learned nothing?\n");
3158
3190
    tmp_close(learner);
3159
 
    exit(1); /* exit code for success */
 
3191
    exit(0); /* exit code for success */
3160
3192
  }
3161
3193
 
3162
3194
  if( skewed_constraints_warning ) {
3385
3417
      m_options |= (1<<M_OPTION_CHAR_GRAPH);
3386
3418
    } else if( !strcasecmp(optarg, "adp") ) {
3387
3419
      m_options |= (1<<M_OPTION_CHAR_ADP);
 
3420
    } else if( !strcasecmp(optarg, "char") ) {
 
3421
      m_options |= (1<<M_OPTION_CHAR_CHAR);
3388
3422
    } else {
3389
3423
      errormsg(E_WARNING,
3390
3424
               "unrecognized option \"%s\", ignoring.\n", 
3412
3446
               "maximum reached, random text category omitted\n");
3413
3447
    } else if( u_options & (1<<U_OPTION_LEARN) ) {
3414
3448
      errormsg(E_ERROR,"cannot use options -l and -R together\n");
3415
 
      exit(0);
 
3449
      exit(1);
3416
3450
    } else {
3417
3451
      u_options |= (1<<U_OPTION_CLASSIFY);
3418
3452
 
3512
3546
    fprintf(stdout, "Feature memory requirements: %d bytes (classifying), %d bytes (learning)\n", 
3513
3547
            (int)sizeof(c_item_t), (int)sizeof(l_item_t));
3514
3548
    fprintf(stdout, "To change these settings, recompile from source.\n");
3515
 
    exit(1);
 
3549
    exit(0);
3516
3550
    break;
3517
3551
  case 'X':
3518
3552
    m_options |= (1<<M_OPTION_CALCENTROPY);
3556
3590
               "maximum reached, category ignored\n");
3557
3591
    } else if( u_options & (1<<U_OPTION_LEARN) ) {
3558
3592
      errormsg(E_ERROR, "cannot use options -l and -c together\n");
3559
 
      exit(0);
 
3593
      exit(1);
3560
3594
    } else {
3561
3595
      u_options |= (1<<U_OPTION_CLASSIFY);
3562
3596
 
3639
3673
      errormsg(E_WARNING, "maximum reached, filter ignored\n");
3640
3674
    } else if( u_options & (1<<U_OPTION_LEARN) ) {
3641
3675
      errormsg(E_ERROR, "cannot use options -l and -f together\n");
3642
 
      exit(0);
 
3676
      exit(1);
3643
3677
    } else if( !*optarg ) {
3644
3678
      errormsg(E_ERROR, "filter must be category name or number\n");
3645
 
      exit(0);
 
3679
      exit(1);
3646
3680
    } else {
3647
3681
      u_options |= (1<<U_OPTION_FILTER);
3648
3682
      filter[filter_count] = -1;
3661
3695
      if( filter[filter_count] < 0 ) { /* still not recognized */
3662
3696
        errormsg(E_ERROR, "unrecognized category in -f option [%s]\n", 
3663
3697
                 optarg);
3664
 
        exit(0);
 
3698
        exit(1);
3665
3699
      }
3666
3700
      filter_count++;
3667
3701
    }
3686
3720
    if( u_options & (1<<U_OPTION_CLASSIFY) ) {
3687
3721
      errormsg(E_ERROR,
3688
3722
               "cannot use options -l and -c together\n");
3689
 
      exit(0);
 
3723
      exit(1);
3690
3724
    } else if( u_options & (1<<U_OPTION_LEARN) ) {
3691
3725
      errormsg(E_ERROR,
3692
3726
               "option -l can only occur once\n");
3693
 
      exit(0);
 
3727
      exit(1);
3694
3728
    } else if( !*optarg ) {
3695
3729
      errormsg(E_ERROR, "category name must not be empty\n");
3696
3730
    } else {
3698
3732
      learner.filename = sanitize_path(optarg, extn);
3699
3733
      if( !*learner.filename ) {
3700
3734
        errormsg(E_ERROR, "category needs a name\n");
3701
 
        exit(0);
 
3735
        exit(1);
3702
3736
      }
3703
3737
    }
3704
3738
    c++;
3729
3763
    m_options &= ~(1<<M_OPTION_I18N);
3730
3764
#endif
3731
3765
    break;
 
3766
  case 'z':
 
3767
    ftreshold = atoi(optarg);
 
3768
    c++;
 
3769
    break;
3732
3770
  default:
3733
3771
    c--;
3734
3772
    break;
3743
3781
  if( ((u_options>>U_OPTION_CLASSIFY) & 1) + 
3744
3782
      ((u_options>>U_OPTION_LEARN) & 1) != 1 ) {
3745
3783
    errormsg(E_ERROR, "please use either -c or -l option.\n");
3746
 
    exit(0);
 
3784
    exit(1);
3747
3785
  }
3748
3786
 
3749
3787
  if( *online && (m_options & (1<<M_OPTION_CALCENTROPY)) ) {
3777
3815
      ((m_options>>M_OPTION_MBOX_FORMAT) & 1) > 1 ) {
3778
3816
    errormsg(E_ERROR,
3779
3817
            "please use only one of either -T text or -T email options.\n");
3780
 
    exit(0);
 
3818
    exit(1);
3781
3819
  }
3782
3820
 
3783
3821
  if( ((m_options>>M_OPTION_XML) & 1) + 
3784
3822
      ((m_options>>M_OPTION_HTML) & 1) > 1 ) {
3785
3823
    errormsg(E_ERROR,
3786
3824
            "please use only one of either -T xml or -T html options.\n");
3787
 
    exit(0);
 
3825
    exit(1);
3788
3826
  }
3789
3827
 
3790
3828
 
3793
3831
    if( !(m_options & (1<<M_OPTION_XML)) ) {
3794
3832
      m_options |= (1<<M_OPTION_HTML);
3795
3833
    }
 
3834
 
3796
3835
    /* for mboxes, only compute ngrams for each line individually */ 
3797
 
    m_options &= ~(1<<M_OPTION_NGRAM_STRADDLE_NL);
 
3836
/*     m_options &= ~(1<<M_OPTION_NGRAM_STRADDLE_NL); */
 
3837
 
3798
3838
    /* always pretend the -X switch was used */
3799
3839
/*     if( u_options & (1<<U_OPTION_LEARN) ) { */
3800
3840
/*       m_options |= (1<<M_OPTION_CALCENTROPY); */
3854
3894
      !(m_options & (1<<M_OPTION_CHAR_ALNUM)) &&
3855
3895
      !(m_options & (1<<M_OPTION_CHAR_CEF)) &&
3856
3896
      !(m_options & (1<<M_OPTION_CHAR_ADP)) &&
 
3897
      !(m_options & (1<<M_OPTION_CHAR_CHAR)) &&
3857
3898
      !(m_options & (1<<M_OPTION_CHAR_GRAPH)) ) {
3858
3899
    if( m_options & (1<<M_OPTION_MBOX_FORMAT) ) {
3859
3900
      m_options |= (1<<M_OPTION_CHAR_ADP);
3920
3961
 
3921
3962
  /* parse the options */
3922
3963
  while( (op = getopt(argc, argv, 
3923
 
                      "01Aac:Dde:f:G:g:H:h:ijL:l:mMNno:q:RrST:UVvw:x:X")) > -1 ) {
 
3964
                      "01Aac:Dde:f:G:g:H:h:ijL:l:mMNno:q:RrST:UVvw:x:Xz:")) > -1 ) {
3924
3965
    set_option(op, optarg);
3925
3966
  }
3926
3967
 
3928
3969
  sanitize_options();
3929
3970
 
3930
3971
  /* set up callbacks */
3931
 
 
3932
3972
  if( u_options & (1<<U_OPTION_CLASSIFY) ) {
3933
3973
 
3934
3974
    preprocess_fun = classifier_preprocess_fun;
3959
3999
 
3960
4000
  } else { /* something wrong ? */
3961
4001
    usage(argv);
3962
 
    exit(0);
 
4002
    exit(1);
3963
4003
  }
3964
4004
 
3965
4005
  /* handles some common filtering options */
4051
4091
 
4052
4092
      errormsg(E_ERROR, "couldn't open %s\n", argv[optind]);
4053
4093
      usage(argv);
4054
 
      exit(0);
 
4094
      exit(1);
4055
4095
 
4056
4096
    }
4057
4097
    optind++;