Disable shared objects by default
[idzebra-moved-to-github.git] / util / charmap.c
index 4d331d4..96a390a 100644 (file)
@@ -1,5 +1,5 @@
-/* $Id: charmap.c,v 1.26 2002-08-28 19:52:29 adam Exp $
-   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002
+/* $Id: charmap.c,v 1.29 2004-07-28 09:47:42 adam Exp $
+   Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004
    Index Data Aps
 
 This file is part of the Zebra server.
@@ -42,7 +42,8 @@ typedef unsigned ucs4_t;
 
 const char *CHR_UNKNOWN = "\001";
 const char *CHR_SPACE   = "\002";
-const char *CHR_BASE    = "\003";
+const char *CHR_CUT     = "\003";
+const char *CHR_BASE    = "\005";
 
 struct chrmaptab_info
 {
@@ -244,6 +245,14 @@ unsigned char zebra_prim(char **s)
     return c;
 }
 
+static int zebra_ucs4_strlen(ucs4_t *s)
+{
+    int i = 0;
+    while (*s++)
+       i++;
+    return i;
+}
+
 ucs4_t zebra_prim_w(ucs4_t **s)
 {
     ucs4_t c;
@@ -263,13 +272,16 @@ ucs4_t zebra_prim_w(ucs4_t **s)
        case 't': c = '\t'; (*s)++; break;
        case 's': c = ' '; (*s)++; break;
        case 'x': 
-            fmtstr[0] = (*s)[0];
-            fmtstr[1] = (*s)[1];
-            fmtstr[2] = (*s)[2];
-            fmtstr[3] = 0;
-            sscanf(fmtstr, "x%2x", &i);
-            c = i;
-            *s += 3; break;
+           if (zebra_ucs4_strlen(*s) >= 3)
+           {
+               fmtstr[0] = (*s)[1];
+               fmtstr[1] = (*s)[2];
+               fmtstr[2] = 0;
+               sscanf(fmtstr, "%x", &i);
+               c = i;
+               *s += 3;
+           }
+           break;
         case '0':
         case '1':
         case '2':
@@ -280,14 +292,30 @@ ucs4_t zebra_prim_w(ucs4_t **s)
         case '7':
         case '8':
         case '9':
-            fmtstr[0] = (*s)[0];
-            fmtstr[1] = (*s)[1];
-            fmtstr[2] = (*s)[2];
-            fmtstr[3] = 0;
-           sscanf(fmtstr, "%3o", &i);
-            c = i;
-            *s += 3;
+           if (zebra_ucs4_strlen(*s) >= 3)
+           {
+               fmtstr[0] = (*s)[0];
+               fmtstr[1] = (*s)[1];
+               fmtstr[2] = (*s)[2];
+               fmtstr[3] = 0;
+               sscanf(fmtstr, "%o", &i);
+               c = i;
+               *s += 3;
+           }
             break;
+       case 'L':
+           if (zebra_ucs4_strlen(*s) >= 5)
+           {
+               fmtstr[0] = (*s)[1];
+               fmtstr[1] = (*s)[2];
+               fmtstr[2] = (*s)[3];
+               fmtstr[3] = (*s)[4];
+               fmtstr[4] = 0;
+               sscanf(fmtstr, "%x", &i);
+               c = i;
+               *s += 5;
+           }
+           break;
         default:
             (*s)++;
        }
@@ -327,6 +355,17 @@ static void fun_addspace(const char *s, void *data, int num)
                                (char*) CHR_SPACE, 0);
 }
 
+/* 
+ * Callback function.
+ * Add a space-entry to the value space.
+ */
+static void fun_addcut(const char *s, void *data, int num)
+{
+    chrmaptab tab = (chrmaptab) data;
+    tab->input = set_map_string(tab->input, tab->nmem, s, strlen(s),
+                               (char*) CHR_CUT, 0);
+}
+
 /*
  * Create a string containing the mapped characters provided.
  */
@@ -386,6 +425,8 @@ static int scan_to_utf8 (yaz_iconv_t t, ucs4_t *from, size_t inlen,
         ret = yaz_iconv (t, &inbuf, &inbytesleft, &outbuf, &outbytesleft);
         if (ret == (size_t) (-1))
         {
+           yaz_log(LOG_LOG, "from: %2X %2X %2X %2X",
+                   from[0], from[1], from[2], from[3]);
             yaz_log (LOG_WARN|LOG_ERRNO, "bad unicode sequence");
             return -1;
         }
@@ -412,8 +453,8 @@ static int scan_string(char *s_native,
         char *inbuf = s_native;
         size_t outbytesleft = sizeof(arg)-4;
         size_t inbytesleft = strlen(s_native);
-        size_t ret;
-        ret = yaz_iconv(t_unicode, &inbuf, &inbytesleft,
+        size_t ret;            
+       ret = yaz_iconv(t_unicode, &inbuf, &inbytesleft,
                         &outbuf, &outbytesleft);
         if (ret == (size_t)(-1))
             return -1;
@@ -495,6 +536,7 @@ chrmaptab chrmaptab_create(const char *tabpath, const char *name, int map_only,
         ucs4_native = "UCS-4LE";
 
     t_utf8 = yaz_iconv_open ("UTF-8", ucs4_native);
+
     logf (LOG_DEBUG, "maptab %s open", name);
     if (!(f = yaz_fopen(tabpath, name, "r", tabroot)))
     {
@@ -582,7 +624,7 @@ chrmaptab chrmaptab_create(const char *tabpath, const char *name, int map_only,
        {
            if (argc != 2)
            {
-               logf(LOG_FATAL, "Syntax error in charmap");
+               logf(LOG_FATAL, "Syntax error in charmap for space");
                ++errors;
            }
            if (scan_string(argv[1], t_unicode, t_utf8,
@@ -592,6 +634,20 @@ chrmaptab chrmaptab_create(const char *tabpath, const char *name, int map_only,
                ++errors;
            }
        }
+       else if (!map_only && !yaz_matchstr(argv[0], "cut"))
+       {
+           if (argc != 2)
+           {
+               logf(LOG_FATAL, "Syntax error in charmap for cut");
+               ++errors;
+           }
+           if (scan_string(argv[1], t_unicode, t_utf8,
+                            fun_addcut, res, 0) < 0)
+           {
+               logf(LOG_FATAL, "Bad cut specification");
+               ++errors;
+           }
+       }
        else if (!yaz_matchstr(argv[0], "map"))
        {
            chrwork buf;
@@ -642,9 +698,28 @@ chrmaptab chrmaptab_create(const char *tabpath, const char *name, int map_only,
        }
         else if (!yaz_matchstr(argv[0], "encoding"))
         {
+           /*
+            * Fix me. When t_unicode==0 and use encoding directive in *.chr file the beheviour of the
+            * zebra need to comment next part of code.
+            */
+
+           /* Original code */
+#if 1
             if (t_unicode != 0)
                 yaz_iconv_close (t_unicode);
             t_unicode = yaz_iconv_open (ucs4_native, argv[1]);
+#endif
+           /*
+            * Fix me. It is additional staff for conversion of characters from local encoding
+            * of *.chr file to UTF-8 (internal encoding).
+            * NOTE: The derective encoding must be first directive in *.chr file.
+            */
+           /* For whatever reason Oleg enabled this.. */
+#if 0
+           if (t_utf8 != 0)
+               yaz_iconv_close(t_utf8);
+           t_utf8 = yaz_iconv_open ("UTF-8", argv[1]);
+#endif
         }
        else
        {