Archive for the 'Programming' Category

Dealing with errors in the GNU PDF Library

3 Comments

The most effective debugging tool is still careful thought, coupled with judiciously placed print statements (Brian Kernighan)

The GNU PDF project takes testing very seriously. Despite this, while programming functionalities that rely on uderlying modules, a returning value reporting if something went wrong in a call has a very high value. So, in this post I am going to explain how to output typical errors in the stderr stream when we are calling almost any functionality in the pdf.h interface.

The key data type here is pdf_status_t. As you can see in the reference manual, almost any function returns a pdf_status_t. For instance, supose that we are creating a new token reader (or tokeniser) for a given stream; the header is

pdf_status_t pdf_token_reader_new (pdf_stm_t stm, pdf_token_reader_t *reader)

The return value can be compared typically with a PDF status value like PDF_OK or PDF_ERROR this way

  1. if (pdf_token_reader_new (stream, &reader) != PDF_OK)

in order to treat error flows. But sometimes we want to know what kind of error happened, instead of knowing if some did occur. To achieve this, we need a function that outputs the corresponding error message to stderr:

void pdf_perror (const pdf_status_t status, const char *str)

Calling it, we get a description of the status contents for a given pdf_status_t data type. So, in our example, this code

  1. pdf_status_t token_stat;
  2. pdf_token_reader_t reader;
  3.  
  4. token_stat = pdf_token_reader_new (stream, &reader);
  5.  
  6. if (token_stat != PDF_OK)
  7.   {
  8.     printf("ERROR creating tokeniser\n");
  9.     pdf_perror(token_stat, NULL);
  10.   }

easily helps us to know what happened if something went wrong. Note that the pdf_perror function gets a desired string to concatenate to the error message as the second parameter.

IMPORTANT UPDATE: Please read Aleksander’s comments here, containing very useful and updated information about new error reporting / printing procedures.

First hacking session with GNU PDF library

4 Comments

In this short session we’ll get running a minimal piece of C code which uses types and functions of the types module, in the base layer of the GNU PDF library. For more information about the GNU PDF library architecture, please go here.

First of all, create a directory to store these little hacking things:

  1. mkdir gnupdfhack
  2. cd gnupdfhack/

Then, create a C test file, and open it with your favorite editor:

  1. touch test.c
  2. emacs test.c

This is a very first approximation to a trivial test unit, which simply:

  • checks the types declared in the library specification, and
  • tries to call some functionalities of the library implementation

The test.c file goes like this:

  1. #include <stdio.h>
  2. #include “../trunk/src/pdf.h”
  3.  
  4. int main ()
  5. {
  6.   printf (“GNU PDF hack test\n”);
  7.  
  8.   pdf_size_t size = 128;
  9.   pdf_error_t *error = NULL;
  10.   pdf_buffer_t *buf = pdf_buffer_new(size, &error);
  11.  
  12.   if (buf == NULL)
  13.     {
  14.       printf(“PDF buffer creation failed\n”);
  15.       /* do some more **error analysis here … */
  16.  
  17.       return 1;
  18.     }
  19.   else
  20.     {
  21.       pdf_buffer_destroy(buf);
  22.       printf(“PDF buffer created and destroyed successfully\n”);
  23.     }
  24.  
  25.   return 0;
  26. }

The type check tries to use the declaration of GNU PDF boolean types, while the library calls essentially allocate space for a buffer, and then they destroy it.

To get it working:

  1. gcc -Wall /usr/local/lib/libgnupdf.so test.c -o test
  2. ./text

This works under the assumption that the GNU PDF library is installed under /usr/local/lib. Please go to this previous post here for a guide on how to install the GNU PDF library in your system. If everything goes well, you’ll get this output:

  1. GNU PDF hack test
  2. —————–
  3. I have the types!
  4. PDF buffer created and destroyed successfully

On further sessions we’ll get more from the actual implementation to make some improvements required on the actual types module. Please feel free to read the base layer interfaces, and happy hacking! Hope this helps!