libhpdftbl 1.5.0
Table construction library for Haru PDF library
Loading...
Searching...
No Matches
unit_test.inc.h
Go to the documentation of this file.
1
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12#include <execinfo.h>
13
14#if !(defined _WIN32 || defined __WIN32__)
15#include <unistd.h>
16#include <libgen.h>
17#include <sys/stat.h>
18#include <sys/utsname.h>
19#endif
20#include <hpdf.h>
21#include <math.h>
22#include <setjmp.h>
23#include <time.h>
24#include "../src/hpdftbl.h"
25
36
46
47#ifndef _MSC_VER
48// Silent gcc about unused "arg" in the callback and error functions
49#pragma GCC diagnostic push
50#pragma GCC diagnostic ignored "-Wunused-parameter"
51#pragma GCC diagnostic ignored "-Wunused-function"
52#endif
53
54#define TESTS_DIR "./tests_libharu/"
55
62static void
63error_handler(HPDF_STATUS error_no, HPDF_STATUS detail_no,
64 void *user_data) {
65 fprintf(stderr, "*** PDF ERROR: \"%s\", [0x%04X : %d]\n",
66 hpdftbl_hpdf_get_errstr(error_no), (unsigned int)error_no, (int)detail_no);
67 longjmp(_hpdftbl_jmp_env, 1);
68}
69
82static void
83table_error_handler(hpdftbl_t t, int r, int c, int err) {
84
85 int lineno;
86 char *filename;
87 char *extrainfo;
88
89 hpdftbl_get_last_err_file(&lineno, &filename, &extrainfo);
90 if (r > -1 && c > -1) {
91 fprintf(stderr, "*** Table Error: [%d] \"%s\" at cell (%d, %d)", err,
92 hpdftbl_get_errstr(err), r, c);
93 } else {
94 fprintf(stderr, "*** Table Error: [%d] \"%s\"", err,
96 }
97 if( filename != NULL ) {
98 fprintf(stderr," in %s:%d",filename, lineno);
99 }
100 if( extrainfo != NULL ) {
101 fprintf(stderr,". Info: \"%s\"\n",extrainfo);
102 }
103 else {
104 fprintf(stderr,"\n");
105 }
106
107 // Also print the available stacktrace
108 void* callstack[128];
109 int i, frames = backtrace(callstack, 128);
110 char** callstack_sym = backtrace_symbols(callstack, frames);
111 if( callstack_sym != NULL ) {
112 fprintf(stderr, "Stacktrace:\n");
113 for (i = 0; i < frames; ++i) {
114 fprintf(stderr, "%s\n", callstack_sym[i]);
115 }
116 free(callstack_sym);
117 }
118
119 longjmp(_hpdftbl_jmp_env, 1);
120}
121
122
123#ifndef _MSC_VER
124#pragma GCC diagnostic pop
125#endif
126
127// Setup a new PDF document with one page
150void
151setup_hpdf(HPDF_Doc* pdf_doc, HPDF_Page* pdf_page, _Bool addgrid) {
152 *pdf_doc = HPDF_New(error_handler, NULL);
153 *pdf_page = HPDF_AddPage(*pdf_doc);
154 HPDF_SetCompressionMode(*pdf_doc, HPDF_COMP_ALL);
155 HPDF_Page_SetSize(*pdf_page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
156 if (addgrid) {
157 hpdftbl_stroke_grid(*pdf_doc, *pdf_page);
158 }
159}
160
180char *
181setup_filename(int argc, char **argv) {
182 static char file[1024];
183 if ( 2==argc ) {
184 strncpy(file, argv[1], sizeof file);
185 file[sizeof(file)-1] = 0;
186 } else if ( 1==argc ) {
187 char fbuff[255];
188 strncpy(fbuff, argv[0], sizeof fbuff);
189 fbuff[sizeof(fbuff) - 1] = 0;
190 char *bname = basename(fbuff);
191 snprintf(file, sizeof file, "out/%s.pdf", bname);
192 } else {
193 return NULL;
194 }
195 return file;
196}
197
209int
210stroke_to_file(HPDF_Doc pdf_doc, int argc, char **argv) {
211 char *file;
212 if( NULL == (file=setup_filename(argc, argv)) ) {
213 fprintf(stderr,"ERROR: Unknown arguments!\n");
214 return -1;
215 }
216
217 printf("Sending to file \"%s\" ...\n", file);
218 if ( -1 == hpdftbl_stroke_pdfdoc(pdf_doc, file) ) {
219 fprintf(stderr,"ERROR: Cannot save to file. Does the full directory path exist?\n");
220 return -1;
221 }
222 printf("Done.\n");
223 return 0;
224}
225
226
230typedef char **content_t;
231
238void setup_dummy_content(content_t *content, size_t rows, size_t cols) {
239 char buff[255];
240 *content = calloc(rows*cols, sizeof(char*));
241 size_t cnt = 0;
242 for (size_t r = 0; r < rows; r++) {
243 for (size_t c = 0; c < cols; c++) {
244 snprintf(buff, sizeof(buff), "Content %zu", cnt);
245 (*content)[cnt] = strdup(buff);
246 cnt++;
247 }
248 }
249}
250
258void setup_dummy_content_label(content_t *content, content_t *labels, size_t rows, size_t cols) {
259 char buff[255];
260 *content = calloc(rows*cols, sizeof(char*));
261 *labels = calloc(rows*cols, sizeof(char*));
262 size_t cnt = 0;
263 for (size_t r = 0; r < rows; r++) {
264 for (size_t c = 0; c < cols; c++) {
265 snprintf(buff, sizeof(buff), "Content %zu", cnt);
266 (*content)[cnt] = strdup(buff);
267 snprintf(buff, sizeof(buff), "Label %zu:", cnt);
268 (*labels)[cnt] = strdup(buff);
269 cnt++;
270 }
271 }
272}
273
294char *
295mkfullpath(char *filename) {
296 const size_t len=strlen(filename)+strlen(TESTS_DIR)+1;
297 char *fullpath = calloc(len, sizeof(char));
298 if( NULL==fullpath ) {
299/*
300 * ISO C does not support ‘__FUNCTION__’ predefined identifier, so we need to relax the
301 * pedantic error checking for the fprintf() statement.
302 */
303#pragma GCC diagnostic push
304#pragma GCC diagnostic ignored "-Wpedantic"
305 fprintf(stderr,"Error: Failed to allocate dynamic buffer (%s:%d)\n", __FUNCTION__ , __LINE__);
306#pragma GCC diagnostic pop
307 exit(1);
308 }
309 xstrlcat(fullpath,TESTS_DIR,len);
310 xstrlcat(fullpath,filename,len);
311 return fullpath;
312}
313
314
322#define TUTEX_MAIN(_tbl_, _showgrid_) int \
323main(int argc, char **argv) { \
324 HPDF_Doc pdf_doc; \
325 HPDF_Page pdf_page; \
326 run_as_unit_test = 2==argc ; \
327 if (setjmp(_hpdftbl_jmp_env)) { \
328 return EXIT_FAILURE; \
329 } \
330 hpdftbl_set_errhandler(table_error_handler); \
331 setup_hpdf(&pdf_doc, &pdf_page, _showgrid_); \
332 _tbl_(pdf_doc, pdf_page); \
333 if( -1 == stroke_to_file(pdf_doc, argc, argv) ) \
334 return EXIT_FAILURE; \
335 else \
336 return EXIT_SUCCESS; \
337}
338
int hpdftbl_stroke_pdfdoc(HPDF_Doc pdf_doc, char *file)
Stroke PDF document to file with check that the directory in path exists.
Definition: hpdftbl.c:1883
void hpdftbl_get_last_err_file(int *lineno, char **file, char **extrainfo)
Get the filename and line number where the last error occurred.
Definition: hpdftbl_errstr.c:345
const char * hpdftbl_hpdf_get_errstr(HPDF_STATUS err_code)
Function to return a human readable error string for an error code from Core HPDF library.
Definition: hpdftbl_errstr.c:232
size_t xstrlcat(char *dst, const char *src, size_t siz)
Safe string concatenation.
Definition: xstr.c:68
#define FALSE
Boolean false value.
Definition: hpdftbl.h:52
const char * hpdftbl_get_errstr(int err)
Translate a table error code to a human readable string.
Definition: hpdftbl_errstr.c:256
void hpdftbl_stroke_grid(HPDF_Doc pdf, HPDF_Page page)
Definition: hpdftbl_grid.c:46
Core table handle.
Definition: hpdftbl.h:470
int stroke_to_file(HPDF_Doc pdf_doc, int argc, char **argv)
Stroke the created PDF page to a file.
Definition: unit_test.inc.h:210
void setup_dummy_content_label(content_t *content, content_t *labels, size_t rows, size_t cols)
Create both array of char pointers to simulate real table content as well as an array of simulated la...
Definition: unit_test.inc.h:258
jmp_buf _hpdftbl_jmp_env
For simulated exception handling.
Definition: unit_test.inc.h:45
void setup_dummy_content(content_t *content, size_t rows, size_t cols)
Create an array of char pointers to simulate real table data.
Definition: unit_test.inc.h:238
_Bool run_as_unit_test
For the case when we use this example as a unit/integration test we do not want data such as dates,...
Definition: unit_test.inc.h:35
char * setup_filename(int argc, char **argv)
Return a pointer to a static buffer that holds the filename to be used for the PDF page.
Definition: unit_test.inc.h:181
char * mkfullpath(char *filename)
Add the full path to the tests directory as prefix to the supplied filename as argument.
Definition: unit_test.inc.h:295
char ** content_t
An array of char pointers.
Definition: unit_test.inc.h:230
void setup_hpdf(HPDF_Doc *pdf_doc, HPDF_Page *pdf_page, _Bool addgrid)
Create a new PDF document with one page in A4 format.
Definition: unit_test.inc.h:151