Browse Source

Provide data debugging API

Suren A. Chilingaryan 9 years ago
parent
commit
92b8fe6e94
4 changed files with 97 additions and 9 deletions
  1. 4 3
      CMakeLists.txt
  2. 1 0
      pcilib/config.h.in
  3. 72 0
      pcilib/debug.c
  4. 20 6
      pcilib/debug.h

+ 4 - 3
CMakeLists.txt

@@ -57,9 +57,10 @@ if(NOT DEFINED LOCALE_INSTALL_DIR)
     set(LOCALE_INSTALL_DIR "${DATA_INSTALL_DIR}/locale")
 endif(NOT DEFINED LOCALE_INSTALL_DIR)
 
-set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib")
-set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib")
-set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models")
+set(PCILIB_PLUGIN_DIR "${LIB_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install plugins")
+set(PCILIB_DATA_DIR "${DATA_INSTALL_DIR}/pcilib" CACHE PATH "Directory to install data files")
+set(PCILIB_MODEL_DIR "${PCILIB_DATA_DIR}/models" CACHE PATH "Directory to install XML models")
+set(PCILIB_DEBUG_DIR "." CACHE PATH "Directory to write debug information")
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcitool.pc.in ${CMAKE_CURRENT_BINARY_DIR}/pcitool.pc)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/pcilib/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pcilib/config.h)

+ 1 - 0
pcilib/config.h.in

@@ -1,3 +1,4 @@
 #cmakedefine PCILIB_PLUGIN_DIR "${PCILIB_PLUGIN_DIR}"
 #cmakedefine PCILIB_DATA_DIR "${PCILIB_DATA_DIR}"
 #cmakedefine PCILIB_MODEL_DIR "${PCILIB_MODEL_DIR}"
+#cmakedefine PCILIB_DEBUG_DIR "${PCILIB_DEBUG_DIR}"

+ 72 - 0
pcilib/debug.c

@@ -1,8 +1,15 @@
+#define _ISOC99_SOURCE 
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
+#include <string.h>
+#include <sys/stat.h>
 
+#include "config.h"
 #include "error.h"
+#include "debug.h"
+
+#define PCILIB_MAX_DEBUG_FILENAME_LENGTH 1023
 
 void pcilib_debug_message(const char *function, const char *file, int line, const char *format, ...) {
     va_list va;
@@ -14,3 +21,68 @@ void pcilib_debug_message(const char *function, const char *file, int line, cons
     va_end(va);
 }
 
+
+void pcilib_debug_data_buffer(const char *function, size_t size, void *buffer, pcilib_debug_buffer_flags_t flags, const char *file, ...) {
+    va_list va;
+
+    FILE *f;
+    size_t prefix_len;
+    const char *prefix;
+    char fname[PCILIB_MAX_DEBUG_FILENAME_LENGTH + 1];
+
+
+    prefix = getenv(function);
+    if (!prefix) return;
+
+    if ((!prefix[0])||(prefix[0] == '1'))
+	prefix = PCILIB_DEBUG_DIR;
+
+    prefix_len = strlen(prefix);
+    if (prefix_len >= PCILIB_MAX_DEBUG_FILENAME_LENGTH)
+	return;
+
+    if (prefix_len) {
+	strncpy(fname, prefix, PCILIB_MAX_DEBUG_FILENAME_LENGTH + 1);
+	fname[prefix_len++] = '/';
+    }
+    
+    fname[PCILIB_MAX_DEBUG_FILENAME_LENGTH] = -1;
+    va_start(va, file);
+    vsnprintf(fname + prefix_len, PCILIB_MAX_DEBUG_FILENAME_LENGTH + 1 - prefix_len, file, va);
+    va_end(va);
+
+	// file name is too long, skipping...
+    if (!fname[PCILIB_MAX_DEBUG_FILENAME_LENGTH])
+	return;
+
+
+    if (flags&PCILIB_DEBUG_BUFFER_MKDIR) {
+	char *slash;
+	if (prefix_len) slash = fname + prefix_len - 1;
+	else slash = strchr(fname, '/');
+
+	while (slash) {
+	    size_t len;
+
+	    *slash = 0;
+	    mkdir(fname, 0755);
+	    len = strlen(fname);
+	    *slash = '/';
+
+	    slash = strchr(fname + len + 1, '/');
+	}	    
+    }
+
+    if (flags&PCILIB_DEBUG_BUFFER_APPEND)
+	f = fopen(fname, "a+");
+    else 
+	f = fopen(fname, "w");
+
+    if (!f)
+	return;
+    
+    if (size&&buffer)
+	fwrite(buffer, 1, size, f);
+
+    fclose(f);
+}

+ 20 - 6
pcilib/debug.h

@@ -1,6 +1,8 @@
 #ifndef _PCILIB_DEBUG_H
 #define _PCILIB_DEBUG_H
 
+#include <stdarg.h>
+
 #define PCILIB_DEBUG
 
 #ifdef PCILIB_DEBUG
@@ -10,22 +12,34 @@
 
 
 #ifdef PCILIB_DEBUG_DMA
-# define PCILIB_DEBUG_DMA_CALL(function, ...) pcilib_debug_message (#function, __FILE__, __LINE__, __VA_ARGS__) 
+# define PCILIB_DEBUG_DMA_MESSAGE(function, ...) pcilib_debug_message (#function, __FILE__, __LINE__, __VA_ARGS__) 
+# define PCILIB_DEBUG_DMA_BUFFER(function, ...) pcilib_debug_data_buffer (#function, __VA_ARGS__) 
 #else /* PCILIB_DEBUG_DMA */
-# define PCILIB_DEBUG_DMA_CALL(function, ...)
+# define PCILIB_DEBUG_DMA_MESSAGE(function, ...)
+# define PCILIB_DEBUG_DMA_BUFFER(function, ...)
 #endif /* PCILIB_DEBUG_DMA */
 
 #ifdef PCILIB_DEBUG_MISSING_EVENTS
-# define PCILIB_DEBUG_MISSING_EVENTS_CALL(function, ...) pcilib_debug_message (#function, __FILE__, __LINE__, __VA_ARGS__) 
+# define PCILIB_DEBUG_MISSING_EVENTS_MESSAGE(function, ...) pcilib_debug_message (#function, __FILE__, __LINE__, __VA_ARGS__) 
+# define PCILIB_DEBUG_MISSING_EVENTS_BUFFER(function, ...) pcilib_debug_data_buffer (#function, __VA_ARGS__) 
 #else /* PCILIB_DEBUG_MISSING_EVENTS */
-# define PCILIB_DEBUG_MISSING_EVENTS_CALL(function, ...)
+# define PCILIB_DEBUG_MISSING_EVENTS_MESSAGE(function, ...)
+# define PCILIB_DEBUG_MISSING_EVENTS_BUFFER(function, ...)
 #endif /* PCILIB_DEBUG_MISSING_EVENTS */
 
-
 #define pcilib_debug(function, ...) \
-    PCILIB_DEBUG_##function##_CALL(PCILIB_DEBUG_##function, __VA_ARGS__)
+    PCILIB_DEBUG_##function##_MESSAGE(PCILIB_DEBUG_##function, __VA_ARGS__)
+
+#define pcilib_debug_buffer(function, ...) \
+    PCILIB_DEBUG_##function##_BUFFER(PCILIB_DEBUG_##function, __VA_ARGS__)
+
+typedef enum {
+    PCILIB_DEBUG_BUFFER_APPEND = 1,
+    PCILIB_DEBUG_BUFFER_MKDIR = 2
+} pcilib_debug_buffer_flags_t; 
 
 void pcilib_debug_message(const char *function, const char *file, int line, const char *format, ...);
+void pcilib_debug_data_buffer(const char *function, size_t size, void *buffer, pcilib_debug_buffer_flags_t flags, const char *file, ...);
 
 
 #endif /* _PCILIB_DEBUG_H */