pdf-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[pdf-devel] patch, mivael, 17Feb2011


From: Michael V. Antosha
Subject: [pdf-devel] patch, mivael, 17Feb2011
Date: Thu, 17 Feb 2011 03:33:29 +0200

Hello,

Here is another proposed patch bundle.
The list of my changes, in short:


* pdf-token-write.c

** Bug fix in unit test pdf_token_write_string_octal

** Bug fix in unit test pdf_token_write_string_null, improvements to
write_and_check


* gnupdf-hg.texi

** Practical example using gdb with failing unit tests.


Michael V. Antosha
http://identi.ca/mivael


# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: address@hidden
#   ir45zyqibmop9obp
# target_branch: bzr://bzr.savannah.gnu.org/pdf/libgnupdf/trunk/
# testament_sha1: 9271f0d0daa6ef8c82bbfb40af27216b718f6b47
# timestamp: 2011-02-17 03:10:04 +0200
# base_revision_id: address@hidden
# 
# Begin patch
=== modified file 'ChangeLog'
--- ChangeLog   2011-02-15 21:22:36 +0000
+++ ChangeLog   2011-02-17 01:06:36 +0000
@@ -1,3 +1,23 @@
+2011-02-17  Michael V. Antosha  <address@hidden>
+
+       * torture/unit/base/token/pdf-token-write.c (string_to_printable):
+       New function. Prints octal escape sequences for nonprintable
+       characters. Used for displaying detailed info about tests that
+       failed in write_and_check.
+       (write_and_check): Two more string buffers allocated, call to
+       string_to_printable arranged.
+       (write_and_check): Using memcmp instead of strncmp
+       now. Explanation added in comments. Needed for
+       pdf_token_write_string_null bug fix, in particular.
+       (pdf_token_write_string_null): False-pass fixed.
+
+2011-02-16  Michael V. Antosha  <address@hidden>
+
+       * torture/unit/base/token/pdf-token-write.c 
(pdf_token_write_string_octal): Bug fix in test.
+
+       * doc/gnupdf-hg.texi (Using gdb to debug check tests): Practical
+       example using gdb with failing unit tests.
+
 2011-02-15  Jose E. Marchesi  <address@hidden>
 
        manual: changes to the object API.

=== modified file 'doc/gnupdf-hg.texi'
--- doc/gnupdf-hg.texi  2011-01-22 22:08:09 +0000
+++ doc/gnupdf-hg.texi  2011-02-16 14:12:44 +0000
@@ -1289,15 +1289,75 @@
 and change it to something like:
 
 @example
-exec "gdb $progdir/$program"
+exec gdb --return-child-result --quiet --args "$progdir/$program" 
address@hidden"$@@"@}
 @end example
 
+Note that you need to repeat this change every time
address@hidden/unit/runtests} is rebuilt by @command{make}.
+
 The second alternative is to run gdb on the real binary using:
 
 @example
 $ LD_LIBRARY_PATH=/path/to/libgnupdf/src/.libs:$LD_LIBRARY_PATH gdb 
torture/unit/.libs/runtests
 @end example
 
+When debugging failing tests you may find it useful to set breakpoint
+to @code{_fail_unless} function:
+
address@hidden
+$ @strong{( export CK_FORK='no'; make check )}   # you can use 'make check 
FUNCTION=...' as well
+...
+(gdb) @strong{break _fail_unless}
+Breakpoint 1 at 0x804ac44
+(gdb) @strong{run}
+...
+Breakpoint 1, _fail_unless (result=1, file=0x80b2f94 "base/alloc/pdf-alloc.c",
+    line=47, expr=0x80aac30 "Failure 'data == NULL' occured") at check.c:237
+237       send_loc_info (file, line);
+...
+(gdb) @strong{list}
+232     void _fail_unless (int result, const char *file,
+233                        int line, const char *expr, ...)
+234     @{
+235       const char *msg;
+236
+237       send_loc_info (file, line);
address@hidden       if (!result) @{}
+239         va_list ap;
+240         char buf[BUFSIZ];
+241
+(gdb) @strong{break check.c:238 if (!result)}
+Breakpoint 2 at 0xb7ea4a7c: file check.c, line 238.
+(gdb) @strong{delete 1}
+(gdb) @strong{continue}
+Continuing.
+...
+Breakpoint 2, _fail_unless (result=0,
+    file=0x80a7ef8 "base/text/pdf-text-new-destroy.c", line=44,
+    expr=0x80a7f1c "Assertion 'pdf_text_new (&newtext) == PDF_EBADCONTEXT' 
failed")
+    at check.c:238
+238       if (!result) @{
+(gdb) @strong{finish}
+Run till exit from #0  _fail_unless (result=0,
+    file=0x80a7ef8 "base/text/pdf-text-new-destroy.c", line=44,
+    expr=0x80a7f1c "Assertion 'pdf_text_new (&newtext) == PDF_EBADCONTEXT' 
failed")
+    at check.c:238
+pdf_text_new_destroy_001 (_i=0) at base/text/pdf-text-new-destroy.c:46
+46      END_TEST
+(gdb) @strong{list}
+41      @{
+42        pdf_text_t newtext = NULL;
+43
+44        fail_unless(pdf_text_new (&newtext) == PDF_EBADCONTEXT);
+45      @}
+46      END_TEST
+47
+48      /*
+49       * Test: pdf_text_new_destroy_002
+50       * Description:
+(gdb) ...
address@hidden example
+
 @node Test Data Files
 @section Test Data Files
 

=== modified file 'torture/unit/base/token/pdf-token-write.c'
--- torture/unit/base/token/pdf-token-write.c   2011-02-11 11:21:22 +0000
+++ torture/unit/base/token/pdf-token-write.c   2011-02-17 01:06:36 +0000
@@ -1,4 +1,4 @@
-/* -*- mode: C -*- Time-stamp: "2011-02-11 12:54:59 EET mivael"
+/* -*- mode: C -*- Time-stamp: "2011-02-17 02:58:53 EET mivael"
  *
  *       File:         pdf-token-write.c
  *       Date:         Tue Sep 21 21:08:07 2010
@@ -32,6 +32,69 @@
 #include <pdf.h>
 
 
+/* Process src_len characters in src.  For every processed character
+   either copy it to dst (if printable except for backslash) or
+   translate the non-printable character to octal escape sequence \ddd
+   and write the sequence to dst.  Backslash is processed specially --
+   corresponding output sequence contains two backslashes.  The
+   resulting string in dst is always zero-terminated.  Not more than
+   dst_size characters are written to dst (including terminating
+   '\0').  If dst_size is not enough to process src_len characters
+   then trailing characters in src are ignored.  Returns dst. */
+static char*
+string_to_printable(char *dst,
+                    int dst_size,
+                    char *src,
+                    int src_len)
+{
+  int src_ind, dst_ind;
+
+  dst_size--; /* reserve one char in dst for '\0' */
+
+  for (src_ind = dst_ind = 0;
+       dst_ind < dst_size && src_ind < src_len;
+       src_ind++)
+    {
+      unsigned char ch = src[src_ind];
+
+      if ( ch == '\\' )
+        {
+          if ( dst_size - dst_ind >= 2 )
+            {
+              dst[dst_ind++] = '\\';
+              dst[dst_ind++] = '\\';
+            }
+          else
+              /* prevent processing the next character from src */
+              dst_size = dst_ind;
+        }
+      else if ( ch > 32 && ch < 127 ) /* if printable except for '\\' */
+        {
+          dst[dst_ind++] = ch;
+        }
+      else /* non-printable */
+        {
+          const int seq_len = 4;
+
+          if ( dst_size - dst_ind >= seq_len )
+            {
+              /* must write exactly seq_len characters (not counting
+                 the '\0' character) */
+              sprintf( dst + dst_ind, "\\%03hho", ch );
+
+              dst_ind += seq_len;
+            }
+          else
+              /* prevent processing the next character from src */
+              dst_size = dst_ind;
+        }
+    }
+
+  dst[dst_ind] = '\0';
+
+  return dst;
+}
+
 /* Write a token in an in-memory buffer and compare results.  */
 static void
 write_and_check (pdf_token_t token,
@@ -43,6 +106,12 @@
   pdf_stm_t stm;
   pdf_char_t *buffer;
   pdf_token_writer_t writer;
+  char *buffer_printable;
+  char *expected_printable;
+
+  /* Allocate memory for printable strings.  */
+  fail_if ((buffer_printable = pdf_alloc (max_size)) == NULL);
+  fail_if ((expected_printable = pdf_alloc (max_size)) == NULL);
 
   /* Create the in-memory stream.  */
   fail_if ((buffer = pdf_alloc (max_size)) == NULL);
@@ -60,15 +129,24 @@
   fail_if (pdf_stm_destroy (stm) != PDF_OK);
 
   /* Compare results.  */
-  fail_unless (strncmp (buffer, expected, expected_size) == 0,
-               "Assertion 'strncmp"
-                 " (\"%.*s\" /*buffer*/, \"%.*s\" /*expected*/, %d)"
+  fail_unless (memcmp (buffer, expected, expected_size) == 0,
+               "Assertion 'memcmp"
+                 " (\"%s\" /*buffer*/, \"%s\" /*expected*/, %d)"
                  " == 0' failed",
-               (int) expected_size,
-               (char*) buffer,
-               (int) expected_size,
-               (char*) expected,
+               string_to_printable(buffer_printable,
+                                   max_size,
+                                   buffer,
+                                   expected_size),
+               string_to_printable(expected_printable,
+                                   max_size,
+                                   expected,
+                                   expected_size),
                (int) expected_size);
+  /* Note that memcmp is used here instead of strncmp. It is necessary
+     for tests of "nonreadable" PDF literal strings, when there is
+     '\0' char inside pdf string.  Thus, pdf_token_write_string_null
+     test may result in false-pass when using strncmp here. See also
+     7.3.4.2 Literal Strings in the PDF spec. */
 }
 
 /*
@@ -553,13 +631,13 @@
   pdf_init ();
 
   /* Create the token.  */
-  fail_if (pdf_token_string_new ("a\0007c", 3, &token)
+  fail_if (pdf_token_string_new ("a\007c", 3, &token)
            != PDF_OK);
 
   /* Check.  */
   write_and_check (token,
                    0,  /* Flags.  */
-                   "(a\0007c)", 5, 100);
+                   "(a\007c)", 5, 100);
 }
 END_TEST
 
@@ -604,13 +682,13 @@
   pdf_init ();
 
   /* Create the token.  */
-  fail_if (pdf_token_string_new ("a\0000c", 3, &token)
+  fail_if (pdf_token_string_new ("a\000c", 3, &token)
            != PDF_OK);
 
   /* Check.  */
   write_and_check (token,
                    0,  /* Flags.  */
-                   "(a\00000c)", 9, 100);
+                   "(a\000c)", 5, 100);
 }
 END_TEST
 

# Begin bundle
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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]