Fixed problem with unset variable (compose_char) in yaz_iconv system
[yaz-moved-to-github.git] / src / siconv.c
index 0034006..7e9d0fd 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 1995-2006, Index Data ApS
  * See the file LICENSE for details.
  *
- * $Id: siconv.c,v 1.25 2006-08-24 10:01:03 adam Exp $
+ * $Id: siconv.c,v 1.29 2006-08-31 18:19:53 adam Exp $
  */
 /**
  * \file siconv.c
  * is used by YAZ to interface with iconv (if present).
  * For systems where iconv is not present, this layer
  * provides a few important conversions: UTF-8, MARC-8, Latin-1.
+ *
+ * MARC-8 reference:
+ *  http://www.loc.gov/marc/specifications/speccharmarc8.html
  */
 
 #if HAVE_CONFIG_H
 #include <config.h>
 #endif
 
+#include <assert.h>
 #include <errno.h>
 #include <string.h>
 #include <ctype.h>
@@ -29,6 +33,7 @@
 #include <iconv.h>
 #endif
 
+
 #include <yaz/yaz-util.h>
 
 unsigned long yaz_marc8_1_conv(unsigned char *inp, size_t inbytesleft,
@@ -178,6 +183,7 @@ static unsigned long yaz_read_ISO8859_1 (yaz_iconv_t cd, unsigned char *inp,
     return x;
 }
 
+
 static size_t yaz_init_UTF8 (yaz_iconv_t cd, unsigned char *inp,
                              size_t inbytesleft, size_t *no_read)
 {
@@ -738,7 +744,7 @@ static unsigned long lookup_marc8(yaz_iconv_t cd,
         x = yaz_marc8r_9_conv(inp, inbytesleft, &no_read_sub, comb);
         if (x)
         {
-            *page_chr = "\033(1";
+            *page_chr = "\033$1";
             return x;
         }
         cd->my_errno = YAZ_ICONV_EILSEQ;
@@ -818,21 +824,42 @@ static size_t yaz_write_marc8_2(yaz_iconv_t cd, unsigned long x,
     else
     {
         size_t r = flush_combos(cd, outbuf, outbytesleft);
+        const char *old_page_chr = cd->write_marc8_page_chr;
         if (r)
             return r;
-        if (strcmp(page_chr, cd->write_marc8_page_chr))
+        if (strcmp(page_chr, old_page_chr))
         {
-            size_t plen = strlen(page_chr);
+            size_t plen = 0;
+            const char *page_out = page_chr;
 
-            if (*outbytesleft < plen)
+            if (*outbytesleft < 8)
             {
                 cd->my_errno = YAZ_ICONV_E2BIG;
+                
                 return (size_t) (-1);
             }
-            memcpy(*outbuf, page_chr, plen);
+            cd->write_marc8_page_chr = page_chr;
+
+            if (!strcmp(old_page_chr, "\033p") 
+                || !strcmp(old_page_chr, "\033g")
+                || !strcmp(old_page_chr, "\033b"))
+            {
+                /* Technique 1 leave */
+                page_out = "\033s";
+                if (strcmp(page_chr, "\033(B")) /* Not going ASCII page? */
+                {
+                    /* Must leave script + enter new page */
+                    plen = strlen(page_out);
+                    memcpy(*outbuf, page_out, plen);
+                    (*outbuf) += plen;
+                    (*outbytesleft) -= plen;
+                    page_out = page_chr;
+                }
+            }
+            plen = strlen(page_out);
+            memcpy(*outbuf, page_out, plen);
             (*outbuf) += plen;
             (*outbytesleft) -= plen;
-            cd->write_marc8_page_chr = page_chr;            
         }
         cd->write_marc8_last = y;
     }
@@ -923,13 +950,6 @@ yaz_iconv_t yaz_iconv_open (const char *tocode, const char *fromcode)
     cd->read_handle = 0;
     cd->init_handle = 0;
     cd->my_errno = YAZ_ICONV_UNKNOWN;
-    cd->marc8_esc_mode = 'B';
-    cd->comb_offset = cd->comb_size = 0;
-    cd->compose_char = 0;
-
-    cd->write_marc8_comb_no = 0;
-    cd->write_marc8_last = 0;
-    cd->write_marc8_page_chr = "\033(B";
 
     /* a useful hack: if fromcode has leading @,
        the library not use YAZ's own conversions .. */
@@ -1039,7 +1059,7 @@ size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft,
     {
         if (cd->init_handle)
         {
-            size_t no_read;
+            size_t no_read = 0;
             size_t r = (cd->init_handle)(cd, (unsigned char *) *inbuf,
                                          *inbytesleft, &no_read);
             if (r)
@@ -1052,6 +1072,15 @@ size_t yaz_iconv(yaz_iconv_t cd, char **inbuf, size_t *inbytesleft,
             *inbytesleft -= no_read;
             *inbuf += no_read;
         }
+        cd->marc8_esc_mode = 'B';
+        
+        cd->comb_offset = cd->comb_size = 0;
+        cd->compose_char = 0;
+        
+        cd->write_marc8_comb_no = 0;
+        cd->write_marc8_last = 0;
+        cd->write_marc8_page_chr = "\033(B";
+        
         cd->init_flag = 0;
         cd->unget_x = 0;
         cd->no_read_x = 0;