Add forgotten files 1.4.70b
[polyglot.git] / book_merge.c
index ee2d848..738d8e3 100644 (file)
 
 #include "book_merge.h"
 #include "util.h"
+#include "pgheader.h"
+
+// macros
+
+#define MAXVARIANTS 50
 
 // types
 
@@ -32,6 +37,8 @@ static book_t In1[1];
 static book_t In2[1];
 static book_t Out[1];
 
+static const char *default_header="@PG@\n1.0\n1\nnormal\n";
+
 // prototypes
 
 static void   book_clear    (book_t * book);
@@ -47,6 +54,50 @@ static void   write_integer (FILE * file, int size, uint64 n);
 
 // functions
 
+// variants_merge()
+
+static void variants_merge(char ** variants, char *variants1, char *variants2){
+
+    char *token;
+    int ret,i,j;
+    int count;
+    char *variants1_dup;
+    char *variants2_dup;
+    char *variant;
+    char *variants_list;
+
+
+    // Step 1: Initial malloc
+
+    *variants=malloc(strlen(variants1)+strlen(variants2)+1+1);
+    (*variants)[0]='\0';
+
+    // Step 2: Loop through the variant names
+
+    variants1_dup=strdup(variants1);
+    variants2_dup=strdup(variants2);
+
+    for(i=0;i<2;i++){
+       variants_list=(i==0)?variants1_dup:variants2_dup;
+       variant=strtok(variants_list,"\x0a");
+       while(variant){
+           // TODO: this does not take into account that one variant name
+           // may be contained in another.
+           if(!strstr(*variants,variant)){
+               if((*variants)[0]!=0){
+                   strcat(*variants,"\x0a");
+               }
+               strcat(*variants,variant);
+           }
+           variant=strtok(NULL,"\x0a");
+       }    
+    }
+    free(variants1_dup);
+    free(variants2_dup);
+
+}
+
+
 // book_merge()
 
 void book_merge(int argc, char * argv[]) {
@@ -55,6 +106,16 @@ void book_merge(int argc, char * argv[]) {
    const char * in_file_1;
    const char * in_file_2;
    const char * out_file;
+   char *header1;
+   char *header2;
+   char *header;
+   char *variants;
+   char *comment;
+   char *variants1;
+   char *variants2;
+   char *raw_header;
+   int size;
+   char ret;
    int i1, i2;
    bool b1, b2;
    entry_t e1[1], e2[1];
@@ -104,6 +165,47 @@ void book_merge(int argc, char * argv[]) {
       }
    }
 
+
+   ret=pgheader_read(&header1,in_file_1);
+   if(ret){
+       switch(ret){
+       case PGHEADER_NO_HEADER:
+          pgheader_create(&header1,"normal","");
+          break;
+       case PGHEADER_OS_ERROR:
+          my_fatal("book_merge(): %s: %s\n",in_file_1,strerror(errno));
+       default:
+          my_fatal("book_merge(): Could not read header of %s\n",in_file_1);
+       }
+   }
+   ret=pgheader_read(&header2,in_file_2);
+   if(ret){
+       switch(ret){
+       case PGHEADER_NO_HEADER:
+          pgheader_create(&header2,"normal","");
+          break;
+       case PGHEADER_OS_ERROR:
+          my_fatal("book_merge(): %s: %s\n",in_file_2,strerror(errno));
+       default:
+          my_fatal("book_merge(): Could not read header of %s\n",in_file_2);
+       }
+   }
+   
+   pgheader_parse(header1,&variants1,&comment);
+   free(header1);
+   free(comment);
+   pgheader_parse(header2,&variants2,&comment);
+   free(header2);
+   free(comment);
+   variants_merge(&variants,variants1,variants2);
+   free(variants1);
+   free(variants2);
+
+   pgheader_create(&header,variants,"Created by Polyglot.");
+   free(variants);
+   pgheader_create_raw(&raw_header,header,&size);
+   free(header);
+
    book_clear(In1);
    book_clear(In2);
    book_clear(Out);
@@ -112,16 +214,30 @@ void book_merge(int argc, char * argv[]) {
    book_open(In2,in_file_2,"rb");
    book_open(Out,out_file,"wb");
 
+   // write header
+   
+   for(i=0;i<size;i++){
+       fputc(raw_header[i],Out->file);
+   }
+   free(raw_header);
+
    skip = 0;
 
    i1 = 0;
    i2 = 0;
 
-   while (TRUE) {
+   
 
-      b1 = read_entry(In1,e1,i1);
-      b2 = read_entry(In2,e2,i2);
+   while (TRUE) {
 
+      do{
+          b1 = read_entry(In1,e1,i1);
+      }while(b1 && e1->key==U64(0x0) && (++i1));
+       
+      do{
+         b2 = read_entry(In2,e2,i2);
+      }while(b2 && e2->key==U64(0x0) && (++i2));
+         
       if (FALSE) {
 
       } else if (!b1 && !b2) {
@@ -129,8 +245,7 @@ void book_merge(int argc, char * argv[]) {
          break;
 
       } else if (b1 && !b2) {
-
-         write_entry(Out,e1);
+        write_entry(Out,e1);
          i1++;
 
       } else if (b2 && !b1) {
@@ -246,6 +361,8 @@ static void write_entry(book_t * book, const entry_t * entry) {
    write_integer(book->file,2,entry->sum);
 }
 
+
+
 // read_integer()
 
 static uint64 read_integer(FILE * file, int size) {