Drop PCRE dependency.
The config file is now manually parsed instead of using regex. While this is less beautifull, it allows us to drop PCRE as a dependency on Windows.
This commit is contained in:
parent
6be73720fa
commit
17ed36a7a5
7 changed files with 122 additions and 101 deletions
|
@ -112,15 +112,6 @@ IF(NOT WIN32)
|
||||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libnfc.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig)
|
||||||
ENDIF(NOT WIN32)
|
ENDIF(NOT WIN32)
|
||||||
|
|
||||||
# Require PCRE for Win32
|
|
||||||
IF (WIN32)
|
|
||||||
FIND_PACKAGE(PCRE REQUIRED)
|
|
||||||
IF(PCRE_INCLUDE_DIRS)
|
|
||||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${PCRE_LIBRARY_DIRS})
|
|
||||||
ENDIF(PCRE_INCLUDE_DIRS)
|
|
||||||
ENDIF(WIN32)
|
|
||||||
|
|
||||||
INCLUDE(LibnfcDrivers)
|
INCLUDE(LibnfcDrivers)
|
||||||
|
|
||||||
IF(PCSC_INCLUDE_DIRS)
|
IF(PCSC_INCLUDE_DIRS)
|
||||||
|
|
|
@ -18,7 +18,6 @@ Requirements
|
||||||
- MinGW-w64 compiler toolchain [1]
|
- MinGW-w64 compiler toolchain [1]
|
||||||
- LibUsb-Win32 1.2.5.0 (or greater) [2]
|
- LibUsb-Win32 1.2.5.0 (or greater) [2]
|
||||||
- CMake 2.8 [3]
|
- CMake 2.8 [3]
|
||||||
- PCRE for Windows [4]
|
|
||||||
|
|
||||||
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
||||||
Windows XP and 32 bit as well.
|
Windows XP and 32 bit as well.
|
||||||
|
@ -65,4 +64,3 @@ References
|
||||||
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm64-gcc-4.5.1.exe/download
|
http://sourceforge.net/projects/tdm-gcc/files/TDM-GCC%20Installer/tdm64-gcc-4.5.1.exe/download
|
||||||
[2] http://sourceforge.net/projects/libusb-win32/files/
|
[2] http://sourceforge.net/projects/libusb-win32/files/
|
||||||
[3] http://www.cmake.org
|
[3] http://www.cmake.org
|
||||||
[4] http://gnuwin32.sourceforge.net/packages/pcre.htm
|
|
|
@ -6,6 +6,6 @@ SET(bundle "${CMAKE_INSTALL_PREFIX}/bin/nfc-list@CMAKE_EXECUTABLE_SUFFIX@")
|
||||||
# set other_libs to a list of additional libs that cannot be reached by dependency analysis
|
# set other_libs to a list of additional libs that cannot be reached by dependency analysis
|
||||||
SET(other_libs "")
|
SET(other_libs "")
|
||||||
|
|
||||||
SET(dirs "@LIBUSB_LIBRARY_DIR@" "@PCRE_BIN_DIRS@")
|
SET(dirs "@LIBUSB_LIBRARY_DIR@")
|
||||||
|
|
||||||
fixup_bundle("${bundle}" "${other_libs}" "${dirs}")
|
fixup_bundle("${bundle}" "${other_libs}" "${dirs}")
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
# This CMake script wants to use pcre functionality needed for windows
|
|
||||||
# compilation. However, since PCRE isn't really a default install location
|
|
||||||
# there isn't much to search.
|
|
||||||
#
|
|
||||||
# Operating Systems Supported:
|
|
||||||
# - Windows (requires MinGW)
|
|
||||||
# Tested with Windows XP/Windows 7
|
|
||||||
#
|
|
||||||
# This should work for both 32 bit and 64 bit systems.
|
|
||||||
#
|
|
||||||
# Author: A. Lian <alex.lian@gmail.com>
|
|
||||||
#
|
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
IF(NOT PCRE_FOUND)
|
|
||||||
FIND_PATH(PCRE_INCLUDE_DIRS regex.h)
|
|
||||||
FIND_LIBRARY(PCRE_LIBRARIES NAMES PCRE pcre)
|
|
||||||
FIND_PATH(PCRE_BIN_DIRS pcre3.dll)
|
|
||||||
|
|
||||||
IF(PCRE_INCLUDE_DIRS AND PCRE_LIBRARIES AND PCRE_BIN_DIRS)
|
|
||||||
SET(PCRE_FOUND TRUE)
|
|
||||||
ENDIF(PCRE_INCLUDE_DIRS AND PCRE_LIBRARIES AND PCRE_BIN_DIRS)
|
|
||||||
ENDIF(NOT PCRE_FOUND)
|
|
||||||
|
|
||||||
IF(PCRE_FOUND)
|
|
||||||
IF(NOT PCRE_FIND_QUIETLY)
|
|
||||||
MESSAGE(STATUS "Found PCRE: ${PCRE_LIBRARIES} ${PCRE_INCLUDE_DIRS} ${PCRE_BIN_DIRS}")
|
|
||||||
ENDIF (NOT PCRE_FIND_QUIETLY)
|
|
||||||
ELSE(PCRE_FOUND)
|
|
||||||
IF(PCRE_FIND_REQUIRED)
|
|
||||||
MESSAGE(FATAL_ERROR "Could not find PCRE")
|
|
||||||
ENDIF(PCRE_FIND_REQUIRED)
|
|
||||||
ENDIF(PCRE_FOUND)
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(PCRE DEFAULT_MSG
|
|
||||||
PCRE_LIBRARIES
|
|
||||||
PCRE_INCLUDE_DIRS
|
|
||||||
PCRE_BIN_DIRS
|
|
||||||
)
|
|
||||||
|
|
||||||
ENDIF(WIN32)
|
|
|
@ -2,6 +2,5 @@ EXTRA_DIST = \
|
||||||
COPYING-CMAKE-SCRIPTS \
|
COPYING-CMAKE-SCRIPTS \
|
||||||
FindLIBUSB.cmake \
|
FindLIBUSB.cmake \
|
||||||
FindPCSC.cmake \
|
FindPCSC.cmake \
|
||||||
FindPCRE.cmake \
|
|
||||||
UseDoxygen.cmake \
|
UseDoxygen.cmake \
|
||||||
LibnfcDrivers.cmake
|
LibnfcDrivers.cmake
|
||||||
|
|
|
@ -47,16 +47,6 @@ ENDIF(SPI_REQUIRED)
|
||||||
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
|
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/buses)
|
||||||
|
|
||||||
IF(WIN32)
|
|
||||||
# Windows now requires regex, so we utilize PCRE
|
|
||||||
# since Windows doesn't get the benefit of finding in CMake
|
|
||||||
# it has to be added manually
|
|
||||||
IF(PCRE_FOUND)
|
|
||||||
INCLUDE_DIRECTORIES(${PCRE_INCLUDE_DIRS})
|
|
||||||
LINK_DIRECTORIES(${PCRE_LIBRARY_DIRS})
|
|
||||||
ENDIF(PCRE_FOUND)
|
|
||||||
ENDIF(WIN32)
|
|
||||||
|
|
||||||
IF(PCSC_FOUND)
|
IF(PCSC_FOUND)
|
||||||
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
|
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
|
||||||
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
|
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
|
||||||
|
@ -94,9 +84,6 @@ SET_TARGET_PROPERTIES(nfc PROPERTIES SOVERSION 5 VERSION 5.0.1)
|
||||||
IF(WIN32)
|
IF(WIN32)
|
||||||
# Libraries that are windows specific
|
# Libraries that are windows specific
|
||||||
TARGET_LINK_LIBRARIES(nfc wsock32)
|
TARGET_LINK_LIBRARIES(nfc wsock32)
|
||||||
IF(PCRE_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(nfc ${PCRE_LIBRARIES})
|
|
||||||
ENDIF(PCRE_FOUND)
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
OUTPUT libnfc.lib
|
OUTPUT libnfc.lib
|
||||||
|
|
154
libnfc/conf.c
154
libnfc/conf.c
|
@ -33,9 +33,9 @@
|
||||||
#ifdef CONFFILES
|
#ifdef CONFFILES
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <regex.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
#include <nfc/nfc.h>
|
#include <nfc/nfc.h>
|
||||||
|
@ -56,8 +56,122 @@
|
||||||
#define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
|
#define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
|
||||||
#define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
|
#define LIBNFC_DEVICECONFDIR LIBNFC_SYSCONFDIR"/devices.d"
|
||||||
|
|
||||||
|
static int
|
||||||
|
escaped_value(const char line[BUFSIZ], int i, char **value)
|
||||||
|
{
|
||||||
|
if (line[i] != '"')
|
||||||
|
goto FAIL;
|
||||||
|
i++;
|
||||||
|
if (line[i] == 0 || line[i] == '\n')
|
||||||
|
goto FAIL;
|
||||||
|
int c = 0;
|
||||||
|
while (line[i] && line[i] != '"') {
|
||||||
|
i++;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
if (line[i] != '"')
|
||||||
|
goto FAIL;
|
||||||
|
*value = malloc(c + 1);
|
||||||
|
if (!*value)
|
||||||
|
goto FAIL;
|
||||||
|
memset(*value, 0, c + 1);
|
||||||
|
memcpy(*value, &line[i - c], c);
|
||||||
|
i++;
|
||||||
|
while (line[i] && isspace(line[i]))
|
||||||
|
i++;
|
||||||
|
if (line[i] != 0 && line[i] != '\n')
|
||||||
|
goto FAIL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FAIL:
|
||||||
|
free(*value);
|
||||||
|
*value = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
non_escaped_value(const char line[BUFSIZ], int i, char **value)
|
||||||
|
{
|
||||||
|
int c = 0;
|
||||||
|
while (line[i] && !isspace(line[i])) {
|
||||||
|
i++;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
*value = malloc(c + 1);
|
||||||
|
if (!*value)
|
||||||
|
goto FAIL;
|
||||||
|
memset(*value, 0, c + 1);
|
||||||
|
memcpy(*value, &line[i - c], c);
|
||||||
|
i++;
|
||||||
|
while (line[i] && isspace(line[i]))
|
||||||
|
i++;
|
||||||
|
if (line[i] != 0)
|
||||||
|
goto FAIL;
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
FAIL:
|
||||||
|
free(*value);
|
||||||
|
*value = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
parse_line(const char line[BUFSIZ], char **key, char **value)
|
||||||
|
{
|
||||||
|
*key = NULL;
|
||||||
|
*value = NULL;
|
||||||
|
int i = 0;
|
||||||
|
int c = 0;
|
||||||
|
|
||||||
|
// optional initial spaces
|
||||||
|
while (isspace(line[i]))
|
||||||
|
i++;
|
||||||
|
if (line[i] == 0 || line[i] == '\n')
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// key
|
||||||
|
while (isalnum(line[i]) || line[i] == '_' || line[i] == '.') {
|
||||||
|
i++;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
if (c == 0 || line[i] == 0 || line[i] == '\n') // key is empty
|
||||||
|
return -1;
|
||||||
|
*key = malloc(c + 1);
|
||||||
|
if (!*key)
|
||||||
|
return -1;
|
||||||
|
memset(*key, 0, c + 1);
|
||||||
|
memcpy(*key, &line[i - c], c);
|
||||||
|
|
||||||
|
// space before '='
|
||||||
|
while (isspace(line[i]))
|
||||||
|
i++;
|
||||||
|
if (line[i] != '=')
|
||||||
|
return -1;
|
||||||
|
i++;
|
||||||
|
if (line[i] == 0 || line[i] == '\n')
|
||||||
|
return -1;
|
||||||
|
// space after '='
|
||||||
|
while (isspace(line[i]))
|
||||||
|
i++;
|
||||||
|
if (line[i] == 0 || line[i] == '\n')
|
||||||
|
return -1;
|
||||||
|
if (escaped_value(line, i, value) == 0)
|
||||||
|
return 0;
|
||||||
|
else if (non_escaped_value(line, i, value) == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Extracting key or value failed
|
||||||
|
free(*key);
|
||||||
|
*key = NULL;
|
||||||
|
free(*value);
|
||||||
|
*value = NULL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const char *key, const char *value), void *data)
|
conf_parse_file(const char *filename,
|
||||||
|
void (*conf_keyvalue)(void *data, const char *key, const char *value),
|
||||||
|
void *data)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(filename, "r");
|
FILE *f = fopen(filename, "r");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
|
@ -65,21 +179,6 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
char line[BUFSIZ];
|
char line[BUFSIZ];
|
||||||
const char *str_regex = "^[[:space:]]*([[:alnum:]_.]+)[[:space:]]*=[[:space:]]*(\"(.+)\"|([^[:space:]]+))[[:space:]]*$";
|
|
||||||
regex_t preg;
|
|
||||||
if (regcomp(&preg, str_regex, REG_EXTENDED | REG_NOTEOL) != 0) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Regular expression used for configuration file parsing is not valid.");
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
size_t nmatch = preg.re_nsub + 1;
|
|
||||||
regmatch_t *pmatch = malloc(sizeof(*pmatch) * nmatch);
|
|
||||||
if (!pmatch) {
|
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_ERROR, "%s", "Not enough memory: malloc failed.");
|
|
||||||
regfree(&preg);
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
while (fgets(line, BUFSIZ, f) != NULL) {
|
while (fgets(line, BUFSIZ, f) != NULL) {
|
||||||
|
@ -89,29 +188,18 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
||||||
case '\n':
|
case '\n':
|
||||||
break;
|
break;
|
||||||
default: {
|
default: {
|
||||||
int match;
|
char *key;
|
||||||
if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) {
|
char *value;
|
||||||
const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
|
if (parse_line(line, &key, &value) == 0) {
|
||||||
const off_t value_pmatch = pmatch[3].rm_eo != -1 ? 3 : 4;
|
|
||||||
const size_t value_size = pmatch[value_pmatch].rm_eo - pmatch[value_pmatch].rm_so;
|
|
||||||
char key[key_size + 1];
|
|
||||||
char value[value_size + 1];
|
|
||||||
strncpy(key, line + (pmatch[1].rm_so), key_size);
|
|
||||||
key[key_size] = '\0';
|
|
||||||
strncpy(value, line + (pmatch[value_pmatch].rm_so), value_size);
|
|
||||||
value[value_size] = '\0';
|
|
||||||
conf_keyvalue(data, key, value);
|
conf_keyvalue(data, key, value);
|
||||||
|
free(key);
|
||||||
|
free(value);
|
||||||
} else {
|
} else {
|
||||||
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line);
|
log_put(LOG_GROUP, LOG_CATEGORY, NFC_LOG_PRIORITY_DEBUG, "Parse error on line #%d: %s", lineno, line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(pmatch);
|
|
||||||
regfree(&preg);
|
|
||||||
fclose(f);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue