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)
|
||||
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)
|
||||
|
||||
IF(PCSC_INCLUDE_DIRS)
|
||||
|
|
|
@ -18,7 +18,6 @@ Requirements
|
|||
- MinGW-w64 compiler toolchain [1]
|
||||
- LibUsb-Win32 1.2.5.0 (or greater) [2]
|
||||
- CMake 2.8 [3]
|
||||
- PCRE for Windows [4]
|
||||
|
||||
This was tested on Windows 7 64 bit, but should work on Windows Vista and
|
||||
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
|
||||
[2] http://sourceforge.net/projects/libusb-win32/files/
|
||||
[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 "")
|
||||
|
||||
SET(dirs "@LIBUSB_LIBRARY_DIR@" "@PCRE_BIN_DIRS@")
|
||||
SET(dirs "@LIBUSB_LIBRARY_DIR@")
|
||||
|
||||
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 \
|
||||
FindLIBUSB.cmake \
|
||||
FindPCSC.cmake \
|
||||
FindPCRE.cmake \
|
||||
UseDoxygen.cmake \
|
||||
LibnfcDrivers.cmake
|
||||
|
|
|
@ -47,16 +47,6 @@ ENDIF(SPI_REQUIRED)
|
|||
|
||||
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)
|
||||
INCLUDE_DIRECTORIES(${PCSC_INCLUDE_DIRS})
|
||||
LINK_DIRECTORIES(${PCSC_LIBRARY_DIRS})
|
||||
|
@ -94,9 +84,6 @@ SET_TARGET_PROPERTIES(nfc PROPERTIES SOVERSION 5 VERSION 5.0.1)
|
|||
IF(WIN32)
|
||||
# Libraries that are windows specific
|
||||
TARGET_LINK_LIBRARIES(nfc wsock32)
|
||||
IF(PCRE_FOUND)
|
||||
TARGET_LINK_LIBRARIES(nfc ${PCRE_LIBRARIES})
|
||||
ENDIF(PCRE_FOUND)
|
||||
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT libnfc.lib
|
||||
|
|
154
libnfc/conf.c
154
libnfc/conf.c
|
@ -33,9 +33,9 @@
|
|||
#ifdef CONFFILES
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <regex.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <nfc/nfc.h>
|
||||
|
@ -56,8 +56,122 @@
|
|||
#define LIBNFC_CONFFILE LIBNFC_SYSCONFDIR"/libnfc.conf"
|
||||
#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
|
||||
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");
|
||||
if (!f) {
|
||||
|
@ -65,21 +179,6 @@ conf_parse_file(const char *filename, void (*conf_keyvalue)(void *data, const ch
|
|||
return false;
|
||||
}
|
||||
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;
|
||||
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':
|
||||
break;
|
||||
default: {
|
||||
int match;
|
||||
if ((match = regexec(&preg, line, nmatch, pmatch, 0)) == 0) {
|
||||
const size_t key_size = pmatch[1].rm_eo - pmatch[1].rm_so;
|
||||
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';
|
||||
char *key;
|
||||
char *value;
|
||||
if (parse_line(line, &key, &value) == 0) {
|
||||
conf_keyvalue(data, key, value);
|
||||
free(key);
|
||||
free(value);
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue