Avoid ctype.h .
[yaz-moved-to-github.git] / client / client.c
index e77e35c..42a56f0 100644 (file)
@@ -1,16 +1,18 @@
 /* This file is part of the YAZ toolkit.
- * Copyright (C) 1995-2010 Index Data
+ * Copyright (C) 1995-2011 Index Data
  * See the file LICENSE for details.
  */
 /** \file client.c
  *  \brief yaz-client program
  */
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <time.h>
-#include <ctype.h>
 #ifndef WIN32
 #include <signal.h>
 #endif
@@ -145,6 +147,8 @@ static int scan_size = 20;
 static char cur_host[200];
 static Odr_int last_hit_count = 0;
 
+static int pretty_xml = 0;
+
 typedef enum {
     QueryType_Prefix,
     QueryType_CCL,
@@ -284,7 +288,7 @@ int send_apdu(Z_APDU *a)
     do_hex_dump(buf, len);
     if (cs_put(conn, buf, len) < 0)
     {
-        fprintf(stderr, "cs_put: %s", cs_errmsg(cs_errno(conn)));
+        fprintf(stderr, "cs_put: %s\n", cs_errmsg(cs_errno(conn)));
         close_session();
         return 0;
     }
@@ -846,6 +850,31 @@ static void print_record(const char *buf, size_t len)
         printf("\n");
 }
 
+static void print_xml_record(const char *buf, size_t len)
+{
+    int has_printed = 0;
+#if YAZ_HAVE_XML2
+    if (pretty_xml)
+    {
+        xmlDocPtr doc;
+        xmlKeepBlanksDefault(0); /* get get xmlDocFormatMemory to work! */
+        doc = xmlParseMemory(buf, len);
+        if (doc)
+        {
+            xmlChar *xml_mem;
+            int xml_size;
+            xmlDocDumpFormatMemory(doc, &xml_mem, &xml_size, 1);
+            fwrite(xml_mem, 1, xml_size, stdout);
+            xmlFree(xml_mem);
+            xmlFreeDoc(doc);
+            has_printed = 1;
+        }
+    }
+#endif
+    if (!has_printed)
+        fwrite(buf, 1, len, stdout);
+}
+
 static void display_record(Z_External *r)
 {
     const Odr_oid *oid = r->direct_reference;
@@ -905,7 +934,8 @@ static void display_record(Z_External *r)
             || !oid_oidcmp(oid, yaz_oid_recsyn_xml)
             || !oid_oidcmp(oid, yaz_oid_recsyn_html))
         {
-            fwrite(octet_buf, 1, octet_len, stdout);
+            print_xml_record(octet_buf, octet_len);
+
         }
         else if (yaz_oid_is_iso2709(oid))
         {
@@ -2280,6 +2310,22 @@ static int only_z3950(void)
     return 0;
 }
 
+static int is_SRW(void)
+{
+    if (!conn)
+    {
+        printf("Not connected yet\n");
+        return 1;
+    }
+    if (protocol == PROTO_HTTP && yaz_matchstr(sru_method, "solr"))
+    {
+        printf("Not supported by SRW\n");
+        return 1;
+    }
+    return 0;
+}
+
+
 static int cmd_update_common(const char *arg, int version);
 
 static int cmd_update(const char *arg)
@@ -2887,6 +2933,8 @@ static int cmd_find(const char *arg)
 
 static int cmd_facets(const char *arg)
 {
+    /* TODO Wrong odr. Loosing memory */
+    ODR odr = odr_createmem(ODR_ENCODE);
     int size = 0;
     if (!*arg)
     {
@@ -2895,15 +2943,9 @@ static int cmd_facets(const char *arg)
         return 0;
     }
     size = strlen(arg);
-/*
-    MOVE to non-usage of it?
-    if (only_z3950() && !yaz_matchstr(sru_method, "solr")) {
-        // We are not Z39.50 and not SOLR (I think)
-        printf("WARN: Currently supported for Z39.50 and SOLR.\n");
+    if (is_SRW()) {
+        printf("WARN: No supported for SRW/SRU.\n");
     }
-ยบ/
-    /* TODO Wrong odr. Loosing memory */
-    ODR odr = odr_createmem(ODR_ENCODE);
     facet_list = yaz_pqf_parse_facet_list(odr, arg);
 
     if (!facet_list)
@@ -2973,21 +3015,50 @@ static int cmd_setnames(const char *arg)
 
 /* PRESENT SERVICE ----------------------------- */
 
+size_t check_token(const char *haystack, const char *token)
+{
+    size_t len = strlen(token);
+    size_t extra;
+    if (strncmp(haystack, token, len))
+        return 0;
+    for (extra = 0; haystack[extra + len] != '\0'; extra++)
+        if (!strchr(" \r\n\t", haystack[extra + len]))
+        {
+            if (extra)
+                break;
+            else
+                return 0;  /* no whitespace after token */
+        }
+    return extra + len;
+}
+
 static int parse_show_args(const char *arg_c, char *setstring,
                            Odr_int *start, Odr_int *number)
 {
     char *end_ptr;
     Odr_int start_position;
+    size_t token_len;
 
     if (setnumber >= 0)
         sprintf(setstring, "%d", setnumber);
     else
         *setstring = '\0';
+    
+    token_len = check_token(arg_c, "format");
+    if (token_len)
+    {
+        pretty_xml = 1;
+        arg_c += token_len;
+    }
+    else
+        pretty_xml = 0;
 
-    if (!strcmp(arg_c, "all"))
+    token_len = check_token(arg_c, "all");
+    if (token_len)
     {
         *number = last_hit_count;
         *start = 1;
+        return 1;
     }
     start_position = odr_strtol(arg_c, &end_ptr, 10);
     if (end_ptr == arg_c)
@@ -2995,7 +3066,7 @@ static int parse_show_args(const char *arg_c, char *setstring,
     *start = start_position;
     if (*end_ptr == '\0')
         return 1;
-    while (isspace(*(unsigned char *)end_ptr))
+    while (yaz_isspace(*end_ptr))
         end_ptr++;
     if (*end_ptr != '+')
     {
@@ -3012,7 +3083,7 @@ static int parse_show_args(const char *arg_c, char *setstring,
     }
     if (*end_ptr == '\0')
         return 1;
-    while (isspace(*(unsigned char *)end_ptr))
+    while (yaz_isspace(*end_ptr))
         end_ptr++;
     if (*end_ptr != '+')
     {
@@ -4270,7 +4341,7 @@ static void handle_srw_record(Z_SRW_record *rec)
     printf("\n");
     if (rec->recordData_buf && rec->recordData_len)
     {
-        printf("%.*s", rec->recordData_len, rec->recordData_buf);
+        print_xml_record(rec->recordData_buf, rec->recordData_len);
         marc_file_write(rec->recordData_buf, rec->recordData_len);
     }
     else
@@ -4303,6 +4374,9 @@ static void handle_srw_response(Z_SRW_searchRetrieveResponse *res)
     }
     if (res->numberOfRecords)
         printf("Number of hits: " ODR_INT_PRINTF "\n", *res->numberOfRecords);
+    if (res->facetList) {
+        display_facets(res->facetList);
+    }
     for (i = 0; i<res->num_records; i++)
         handle_srw_record(res->records + i);
 }
@@ -5105,7 +5179,7 @@ static void process_cmd_line(char* line)
 
         for (; *p; ++p)
         {
-            if (!isspace(*(unsigned char *) p))
+            if (!yaz_isspace(*p))
                 lastnonspace = p;
         }
         if (lastnonspace)