* tsexp.c (back_and_forth): Very minimal test of the new functions.
authorWerner Koch <wk@gnupg.org>
Thu, 16 May 2002 17:11:21 +0000 (17:11 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 16 May 2002 17:11:21 +0000 (17:11 +0000)
* missing-string.c: New.

* gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
ones using an underscore.

* global.c (gcry_strerror): Add strings fro the new error codes.
* sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
old error codes.
(gcry_sexp_create,gcry_sexp_new): New.

src/ChangeLog
src/Makefile.am
src/g10lib.h
src/gcrypt.h
src/global.c
src/missing-string.c [new file with mode: 0644]
src/sexp.c
tests/ChangeLog
tests/tsexp.c

index b012286..e1419db 100644 (file)
@@ -1,3 +1,16 @@
+2002-05-16  Werner Koch  <wk@gnupg.org>
+
+       * missing-string.c: New.
+
+       * gcrypt.h: Add new error codes GCRYERR_SEXP_ and typedefs
+       GcryMPI, GcrySexp, GcryCipherHd, GcryMDHd as aliases for the old
+       ones using an underscore.
+
+       * global.c (gcry_strerror): Add strings fro the new error codes.
+       * sexp.c (gcry_sexp_canon_len): Use a macro to convert from new to
+       old error codes.
+       (gcry_sexp_create,gcry_sexp_new): New.
+
 2002-05-15  Werner Koch  <wk@gnupg.org>
 
        * mutex.h (DEFINE_LOCAL_MUTEX): Macro to define a mutex and
index 71b82d1..447da74 100644 (file)
@@ -50,7 +50,8 @@ libgcrypt_la_SOURCES =         g10lib.h \
                         secmem.c \
                         secmem.h \
                         mpi.h \
-                        mutex.h 
+                        mutex.h \
+                        missing-string.c 
 
 libgcrypt_la_DEPENDENCIES = libgcrypt.sym \
                            ../cipher/libcipher.la ../mpi/libmpi.la
index 125c782..bfbe7f8 100644 (file)
@@ -128,16 +128,22 @@ MPI _gcry_generate_elg_prime( int mode, unsigned pbits, unsigned qbits,
 
 
 
-/* replacements of missing functions */
-#ifndef HAVE_MEMICMP
-int memicmp( const char *a, const char *b, size_t n );
-#endif
+/* replacements of missing functions (missing-string.c)*/
 #ifndef HAVE_STPCPY
-char *stpcpy(char *a,const char *b);
+char *stpcpy (char *a, const char *b);
+#endif
+#ifndef HAVE_STRSEP
+char *strsep (char **stringp, const char *delim);
 #endif
 #ifndef HAVE_STRLWR
-char *strlwr(char *a);
+char *strlwr (char *a);
 #endif
+#ifndef HAVE_STRCASECMP
+int strcasecmp (const char *a, const char *b);
+#endif
+
+
+/* macros used to rename missing functions */
 #ifndef HAVE_STRTOUL
   #define strtoul(a,b,c)  ((unsigned long)strtol((a),(b),(c)))
 #endif
@@ -154,6 +160,7 @@ char *strlwr(char *a);
   #define raise(a) kill(getpid(), (a))
 #endif
 
+
 /* some handy macros */
 #ifndef STR
   #define STR(v) #v
@@ -164,3 +171,5 @@ char *strlwr(char *a);
 
 
 #endif /* G10LIB_H */
+
+
index c0b979f..aa382a3 100644 (file)
@@ -52,6 +52,7 @@ extern "C" {
 
 struct gcry_mpi;
 typedef struct gcry_mpi *GCRY_MPI;
+typedef struct gcry_mpi *GcryMPI;
 
 /*******************************************
  *                                        *
@@ -90,7 +91,23 @@ enum {
     GCRYERR_NO_OBJ = 68,     /* Missing item in an object */
     GCRYERR_NOT_IMPL = 69,   /* Not implemented */
     GCRYERR_CONFLICT = 70,
-    GCRYERR_INV_CIPHER_MODE = 71
+    GCRYERR_INV_CIPHER_MODE = 71,
+
+    /* error codes pertaining to S-expressions */
+    GCRYERR_SEXP_INV_LEN_SPEC    = 201,
+    GCRYERR_SEXP_STRING_TOO_LONG = 202,
+    GCRYERR_SEXP_UNMATCHED_PAREN = 203, 
+    GCRYERR_SEXP_NOT_CANONICAL   = 204, 
+    GCRYERR_SEXP_BAD_CHARACTER   = 205, 
+    GCRYERR_SEXP_BAD_QUOTATION   = 206,/* or invalid hex or octal value */
+    GCRYERR_SEXP_ZERO_PREFIX     = 207,/* first character of a length is 0 */
+    GCRYERR_SEXP_NESTED_DH       = 208,/* nested display hints */
+    GCRYERR_SEXP_UNMATCHED_DH    = 209,/* unmatched display hint */
+    GCRYERR_SEXP_UNEXPECTED_PUNC = 210,/* unexpected reserved punctuation */
+    GCRYERR_SEXP_BAD_HEX_CHAR    = 211,
+    GCRYERR_SEXP_ODD_HEX_NUMBERS = 212,
+    GCRYERR_SEXP_BAD_OCT_CHAR    = 213
+
 };
 
 const char *gcry_check_version( const char *req_version );
@@ -151,6 +168,7 @@ enum gcry_random_level {
 
 struct gcry_sexp;
 typedef struct gcry_sexp *GCRY_SEXP;
+typedef struct gcry_sexp *GcrySexp;  /* this type looks more pretty */
 
 enum gcry_sexp_format {
     GCRYSEXP_FMT_DEFAULT   = 0,
@@ -159,20 +177,29 @@ enum gcry_sexp_format {
     GCRYSEXP_FMT_ADVANCED  = 3
 };
 
-void     gcry_sexp_release( GCRY_SEXP sexp );
+int gcry_sexp_new (GCRY_SEXP *retsexp, const void *buffer, size_t length,
+                   int autodetect);
+int gcry_sexp_create (GCRY_SEXP *retsexp, void *buffer, size_t length,
+                       int autodetect, void (*freefnc)(void*) );
+int gcry_sexp_sscan (GCRY_SEXP *retsexp, size_t *erroff,
+                     const char *buffer, size_t length );
+int gcry_sexp_build (GCRY_SEXP *retsexp, size_t *erroff,
+                     const char *format, ... );
+void gcry_sexp_release (GCRY_SEXP sexp);
+
+size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
+                            size_t *erroff, int *errcode);
+
+size_t   gcry_sexp_sprint (GCRY_SEXP sexp, int mode, char *buffer,
+                            size_t maxlength );
+
 void     gcry_sexp_dump( const GCRY_SEXP a );
 GCRY_SEXP gcry_sexp_cons( const GCRY_SEXP a, const GCRY_SEXP b );
 GCRY_SEXP gcry_sexp_alist( const GCRY_SEXP *array );
 GCRY_SEXP gcry_sexp_vlist( const GCRY_SEXP a, ... );
 GCRY_SEXP gcry_sexp_append( const GCRY_SEXP a, const GCRY_SEXP n );
 GCRY_SEXP gcry_sexp_prepend( const GCRY_SEXP a, const GCRY_SEXP n );
-int      gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff,
-                          const char *buffer, size_t length );
-int      gcry_sexp_build( GCRY_SEXP *retsexp, size_t *erroff,
-                          const char *format, ... );
-size_t   gcry_sexp_sprint( GCRY_SEXP sexp, int mode, char *buffer,
-                                               size_t maxlength );
-GCRY_SEXP   gcry_sexp_find_token( GCRY_SEXP list,
+GCRY_SEXP gcry_sexp_find_token( GCRY_SEXP list,
                                  const char *tok, size_t toklen );
 int        gcry_sexp_length( const GCRY_SEXP list );
 GCRY_SEXP   gcry_sexp_nth( const GCRY_SEXP list, int number );
@@ -183,8 +210,6 @@ const char *gcry_sexp_nth_data( const GCRY_SEXP list, int number,
                                                      size_t *datalen );
 GCRY_MPI    gcry_sexp_nth_mpi( GCRY_SEXP list, int number, int mpifmt );
 
-size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
-                            size_t *erroff, int *errcode);
 
 
 /*******************************************
@@ -305,6 +330,7 @@ int      gcry_mpi_get_flag( GCRY_MPI a, enum gcry_mpi_flag flag );
 
 struct gcry_cipher_handle;
 typedef struct gcry_cipher_handle *GCRY_CIPHER_HD;
+typedef struct gcry_cipher_handle *GcryCipherHd;
 
 enum gcry_cipher_algos {
     GCRY_CIPHER_NONE       = 0,
@@ -436,6 +462,7 @@ struct gcry_md_handle {
     byte buf[1];
 };
 typedef struct gcry_md_handle *GCRY_MD_HD;
+typedef struct gcry_md_handle *GcryMDHd;
 
 
 GCRY_MD_HD gcry_md_open( int algo, unsigned flags );
index 7d922b7..192cf50 100644 (file)
@@ -280,6 +280,19 @@ gcry_strerror( int ec )
       X(CONFLICT,      N_("conflict"))
       X(INV_CIPHER_MODE,N_("invalid cipher mode"))
 
+        X(SEXP_INV_LEN_SPEC   ,N_("invalid length specification")) 
+        X(SEXP_STRING_TOO_LONG,N_("string too long")) 
+        X(SEXP_UNMATCHED_PAREN,N_("unmatched parenthesis")) 
+        X(SEXP_NOT_CANONICAL  ,N_("not a canonical S-expression")) 
+        X(SEXP_BAD_CHARACTER  ,N_("bad character")) 
+        X(SEXP_BAD_QUOTATION  ,N_("invalid hex/octal value or bad quotation")) 
+        X(SEXP_ZERO_PREFIX    ,N_("a length may not begin with zero")) 
+        X(SEXP_NESTED_DH      ,N_("nested display hints")) 
+        X(SEXP_UNMATCHED_DH   ,N_("unmatched display hint close")) 
+        X(SEXP_UNEXPECTED_PUNC,N_("unexpected reserved punctuation")) 
+        X(SEXP_BAD_HEX_CHAR,   N_("invalid hex character"))
+        X(SEXP_ODD_HEX_NUMBERS,N_("odd number of hex characters"))
+        X(SEXP_BAD_OCT_CHAR,   N_("invalid octal character"))
 
       default:
        sprintf( buf, "ec=%d", ec );
diff --git a/src/missing-string.c b/src/missing-string.c
new file mode 100644 (file)
index 0000000..f9c5df1
--- /dev/null
@@ -0,0 +1,209 @@
+/* missing-string.c - missing string utilities
+ * Copyright (C) 1994, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
+ *
+ * This file is part of Libgcrypt.
+ *
+ * Libgcrypt is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * Libgcrypt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <config.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+
+
+#ifndef HAVE_STPCPY
+char *
+stpcpy(char *a,const char *b)
+{
+    while( *b )
+       *a++ = *b++;
+    *a = 0;
+
+    return (char*)a;
+}
+#endif
+
+
+#ifndef HAVE_STRSEP
+/* code taken from glibc-2.2.1/sysdeps/generic/strsep.c */
+char *
+strsep (char **stringp, const char *delim)
+{
+  char *begin, *end;
+
+  begin = *stringp;
+  if (begin == NULL)
+    return NULL;
+
+  /* A frequent case is when the delimiter string contains only one
+     character.  Here we don't need to call the expensive `strpbrk'
+     function and instead work using `strchr'.  */
+  if (delim[0] == '\0' || delim[1] == '\0')
+    {
+      char ch = delim[0];
+
+      if (ch == '\0')
+        end = NULL;
+      else
+        {
+          if (*begin == ch)
+            end = begin;
+          else if (*begin == '\0')
+            end = NULL;
+          else
+            end = strchr (begin + 1, ch);
+        }
+    }
+  else
+    /* Find the end of the token.  */
+    end = strpbrk (begin, delim);
+
+  if (end)
+    {
+      /* Terminate the token and set *STRINGP past NUL character.  */
+      *end++ = '\0';
+      *stringp = end;
+    }
+  else
+    /* No more delimiters; this is the last token.  */
+    *stringp = NULL;
+
+  return begin;
+}
+#endif /*HAVE_STRSEP*/
+
+
+#ifndef HAVE_STRLWR
+char *
+strlwr(char *s)
+{
+    char *p;
+    for(p=s; *p; p++ )
+       *p = tolower(*p);
+    return s;
+}
+#endif
+
+#ifndef HAVE_STRCASECMP
+int
+strcasecmp( const char *a, const char *b )
+{
+    for( ; *a && *b; a++, b++ ) {
+       if( *a != *b && toupper(*a) != toupper(*b) )
+           break;
+    }
+    return *(const byte*)a - *(const byte*)b;
+}
+#endif
+
+
+#ifdef __MINGW32__
+/* 
+ * Like vsprintf but provides a pointer to malloc'd storage, which
+ * must be freed by the caller (m_free).  Taken from libiberty as
+ * found in gcc-2.95.2 and a little bit modernized.
+ * FIXME: Write a new CRT for W32.
+ */
+int
+vasprintf ( char **result, const char *format, va_list args)
+{
+  const char *p = format;
+  /* Add one to make sure that it is never zero, which might cause malloc
+     to return NULL.  */
+  int total_width = strlen (format) + 1;
+  va_list ap;
+
+  /* this is not really portable but works under Windows */
+  memcpy ( &ap, &args, sizeof (va_list));
+
+  while (*p != '\0')
+    {
+      if (*p++ == '%')
+       {
+         while (strchr ("-+ #0", *p))
+           ++p;
+         if (*p == '*')
+           {
+             ++p;
+             total_width += abs (va_arg (ap, int));
+           }
+         else
+            {
+              char *endp;  
+              total_width += strtoul (p, &endp, 10);
+              p = endp;
+            }
+         if (*p == '.')
+           {
+             ++p;
+             if (*p == '*')
+               {
+                 ++p;
+                 total_width += abs (va_arg (ap, int));
+               }
+             else
+                {
+                  char *endp;
+                  total_width += strtoul (p, &endp, 10);
+                  p = endp;
+                }
+           }
+         while (strchr ("hlL", *p))
+           ++p;
+         /* Should be big enough for any format specifier except %s
+             and floats.  */
+         total_width += 30;
+         switch (*p)
+           {
+           case 'd':
+           case 'i':
+           case 'o':
+           case 'u':
+           case 'x':
+           case 'X':
+           case 'c':
+             (void) va_arg (ap, int);
+             break;
+           case 'f':
+           case 'e':
+           case 'E':
+           case 'g':
+           case 'G':
+             (void) va_arg (ap, double);
+             /* Since an ieee double can have an exponent of 307, we'll
+                make the buffer wide enough to cover the gross case. */
+             total_width += 307;
+           
+           case 's':
+             total_width += strlen (va_arg (ap, char *));
+             break;
+           case 'p':
+           case 'n':
+             (void) va_arg (ap, char *);
+             break;
+           }
+       }
+    }
+  *result = m_alloc (total_width);
+  if (*result != NULL)
+    return vsprintf (*result, format, args);
+  else
+    return 0;
+}
+
+#endif /*__MINGW32__*/
+
index c1bf804..aea3a5f 100644 (file)
@@ -59,6 +59,13 @@ struct gcry_sexp {
 
 #define TOKEN_SPECIALS  "-./_:*+="
 
+#define OLDPARSECODE(a) (-((GCRYERR_SEXP_ ## a)-GCRYERR_SEXP_INV_LEN_SPEC+1))
+
+
+static int
+sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
+           const char *buffer, size_t length, va_list arg_ptr, int argflag);
+
 
 #if 0
 static void
@@ -174,6 +181,73 @@ normalize ( GCRY_SEXP list )
     return list;
 }
 
+/* Create a new S-expression object by reading LENGTH bytes from
+   BUFFER, assuming it is canonilized encoded or autodetected encoding
+   when AUTODETECT is set to 1.  With FREEFNC not NULL, ownership of
+   the buffer is transferred to tyhe newle created object.  FREEFNC
+   should be the freefnc used to release BUFFER; there is no guarantee
+   at which point this function is called; most likey you want to use
+   free() or gcry_free(). 
+   Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
+   BUFFER points to a valid canonical encoded S-expression.  A LENGTH
+   of 0 and AUTODETECT 1 indicates that buffer points to a
+   null-terminated string.
+  
+   This function returns 0 and and the pointer to the new object in
+   RETSEXP or an error code in which case RETSEXP is set to NULL.  */
+int 
+gcry_sexp_create (GCRY_SEXP *retsexp, void *buffer, size_t length,
+                  int autodetect, void (*freefnc)(void*) )
+{
+  int errcode;
+  GCRY_SEXP se;
+  volatile va_list dummy_arg_ptr;
+
+  if (!retsexp)
+    return GCRYERR_INV_ARG;
+  *retsexp = NULL;
+  if (autodetect < 0 || autodetect > 1 || !buffer)
+    return GCRYERR_INV_ARG;
+
+  if (!length && !autodetect)
+    { /* What a brave caller to assume that there is really a canonical
+         encoded S-expression in buffer */
+      length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+      if (!length)
+        return 200 - errcode;
+    }
+  else if (!length && autodetect)
+    { /* buffer is a string */
+      length = strlen ((char *)buffer);
+    }
+
+  errcode = sexp_sscan (&se, NULL, buffer, length, dummy_arg_ptr, 0);
+  if (errcode)
+    return 200 - errcode;
+
+  *retsexp = se;
+  if (freefnc)
+    {
+      /* For now we release the buffer immediately.  As soon as we
+         have changed the internal represenation of S-expression to
+         the canoncial format - which has the advantage of faster
+         parsing - we will use this function as a closure in our
+         GCRYSEXP object and use the BUFFER directly */
+      freefnc (buffer);
+    }
+  return 0;
+}
+
+/* Same as gcry_sexp_create but don't transfer ownership */
+int
+gcry_sexp_new (GCRY_SEXP *retsexp, const void *buffer, size_t length,
+               int autodetect)
+{
+  return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+}
+
+
 /****************
  * Release resource of the given SEXP object.
  */
@@ -890,7 +964,7 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
            else if( *p == '#' ) {
                if( (hexcount & 1) ) {
                    *erroff = p - buffer;
-                   return -12;  /* odd number of hex digits */
+                   return OLDPARSECODE (ODD_HEX_NUMBERS);
                }
 
                datalen = hexcount/2;
@@ -907,7 +981,7 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
            }
            else if( !isspace( *p ) ) {
                *erroff = p - buffer;
-               return -11;  /* invalid hex character */
+               return OLDPARSECODE (BAD_HEX_CHAR);
            }
        }
        else if( base64 ) {
@@ -1394,7 +1468,7 @@ gcry_sexp_sprint( const GCRY_SEXP list, int mode,
    return the actual length this S-expression uses.  For a valid S-Exp
    it should never return 0.  If LENGTH is not zero, the maximum
    length to scan is given - this can be used for syntax checks of
-   data passed from outside. erroce and erroff may both be passed as
+   data passed from outside. errorcode and erroff may both be passed as
    NULL
 
    Errorcodes (for historic reasons they are all negative):
@@ -1407,7 +1481,10 @@ gcry_sexp_sprint( const GCRY_SEXP list, int mode,
     -7 := a length may not begin with zero 
     -8 := nested display hints 
     -9 := unmatched display hint close
-   -10 := unexpected reserved punctuation 
+   -10 := unexpected reserved punctuation          
+
+   Use this formula to convert the errorcodes:
+   gcryerr = 200 - errcode;
  */
 size_t
 gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
@@ -1432,7 +1509,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
     return 0;
   if (*buffer != '(')
     {
-      *errcode = -4; /* not a canonical S-expression */
+      *errcode = OLDPARSECODE (NOT_CANONICAL);
       return 0;
     }
 
@@ -1441,7 +1518,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
       if (length && count >= length)
         {
           *erroff = count;
-          *errcode = -2; /* string too long */
+          *errcode = OLDPARSECODE (STRING_TOO_LONG); 
           return 0;
         }
       
@@ -1452,7 +1529,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
               if (length && (count+datalen) >= length)
                 {
                   *erroff = count;
-                  *errcode = -2; /* string too long */
+                  *errcode = OLDPARSECODE (STRING_TOO_LONG);
                   return 0;
                 }
               count += datalen;
@@ -1464,7 +1541,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           else 
             {
               *erroff = count;
-              *errcode = -1;
+              *errcode = OLDPARSECODE (INV_LEN_SPEC);
               return 0;
            }
        }
@@ -1473,7 +1550,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (disphint)
             {
               *erroff = count;
-              *errcode = -9; /* open display hint */
+              *errcode = OLDPARSECODE (UNMATCHED_DH);
               return 0;
            }
           level++;
@@ -1483,13 +1560,13 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (!level)
             {
               *erroff = count;
-              *errcode = -3; /* unmatched parenthesis */
+              *errcode = OLDPARSECODE (UNMATCHED_PAREN);
               return 0;
            }
           if (disphint)
             {
               *erroff = count;
-              *errcode = -9; /* open display hint */
+              *errcode = OLDPARSECODE (UNMATCHED_DH);
               return 0;
            }
           if (!--level)
@@ -1500,7 +1577,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (disphint) 
             {
               *erroff = count;
-              *errcode = -8; /* nested display hints */
+              *errcode = OLDPARSECODE (NESTED_DH);
               return 0;
             }
           disphint = p;
@@ -1510,7 +1587,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if( !disphint ) 
             {
               *erroff = count;
-              *errcode = -9; /* unmatched display hint close */
+              *errcode = OLDPARSECODE (UNMATCHED_DH);
               return 0;
            }
           disphint = NULL;
@@ -1520,7 +1597,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (*p == '0')
             { 
               *erroff = count;
-              *errcode = -7; /* a length may not begin with zero */
+              *errcode = OLDPARSECODE (ZERO_PREFIX);
               return 0;
            }
           datalen = atoi_1 (p);
@@ -1528,16 +1605,14 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
       else if (*p == '&' || *p == '\\')
         {
           *erroff = count;
-          *errcode = -10; /* unexpected reserved punctuation */
+          *errcode = OLDPARSECODE (UNEXPECTED_PUNC);
           return 0;
        }
       else
         { 
           *erroff = count;
-          *errcode = -5; /* bad character */
+          *errcode = OLDPARSECODE (BAD_CHARACTER);
           return 0;
        }
     }
 }
-
-
index ca1b5ef..e0c7331 100644 (file)
@@ -1,3 +1,7 @@
+2002-05-16  Werner Koch  <wk@gnupg.org>
+
+       * tsexp.c (back_and_forth): Very minimal test of the new functions.
+
 2002-05-14  Werner Koch  <wk@gnupg.org>
 
        Changed license of all files to the LGPL.
index 2615f42..dd852f9 100644 (file)
@@ -213,6 +213,64 @@ canon_len (void)
 }
 
 
+static void
+back_and_forth_one (int testno, const char *buffer, size_t length)
+{
+  int rc;
+  GcrySexp se, se1;
+  size_t n, n1;
+  char *p1;
+
+  rc = gcry_sexp_new (&se, buffer, length, 1);
+  if (rc)
+    {
+      fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gcry_strerror (rc));
+      return;
+    }
+  n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
+  if (!n1)
+    {
+      fail ("baf %d: get required length for canon failed\n", testno);
+      return;
+    }
+  p1 = gcry_xmalloc (n1);
+  n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
+  if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
+    {
+      fail ("baf %d: length mismatch for canon\n", testno);
+      return;
+    }
+  rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
+  if (rc)
+    {
+      fail ("baf %d: gcry_sexp_create failed: %s\n",
+            testno, gcry_strerror (rc));
+      return;
+    }
+  gcry_sexp_release (se1);
+  
+  /* FIXME: we need a lot more tests */
+
+  gcry_sexp_release (se);
+}
+
+
+
+static void
+back_and_forth (void)
+{
+  static struct { char *buf; int len; } tests[] = {
+    { "(7:g34:fgh1::2:())", 0 },
+    { "(7:g34:fgh1::2:())", 18 },
+    { NULL, 0 }
+  };
+  int idx;
+
+  for (idx=0; tests[idx].buf; idx++)
+    back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -221,8 +279,13 @@ main (int argc, char **argv)
 
   basic ();
   canon_len ();
+  back_and_forth ();
   
   return error_count? 1:0;
 }
 
 
+
+
+
+