added qse_substbasenamedup()/qse_substwcsbasenamedup()/qse_substmbsbasenamedup().

enhanced $INCLUDE handling in raddic
This commit is contained in:
hyung-hwan 2017-12-14 04:08:10 +00:00
parent 61483e294a
commit 1f56b6cf93
5 changed files with 269 additions and 184 deletions

View File

@ -132,8 +132,14 @@ QSE_EXPORT const qse_mchar_t* qse_mbsbasename (
const qse_mchar_t* path const qse_mchar_t* path
); );
QSE_EXPORT qse_mchar_t* qse_substmbsbasenamedup (
const qse_mchar_t* path,
const qse_mchar_t* file,
qse_mmgr_t* mmgr
);
/** /**
* The qse_mbspathroot() function returns the core part of \a path * The qse_mbspathcore() function returns the core part of \a path
* excluding a special prefix. * excluding a special prefix.
*/ */
QSE_EXPORT qse_mchar_t* qse_mbspathcore ( QSE_EXPORT qse_mchar_t* qse_mbspathcore (
@ -230,8 +236,14 @@ QSE_EXPORT const qse_wchar_t* qse_wcsbasename (
const qse_wchar_t* path const qse_wchar_t* path
); );
QSE_EXPORT qse_wchar_t* qse_substwcsbasenamedup (
const qse_wchar_t* path,
const qse_wchar_t* file,
qse_mmgr_t* mmgr
);
/** /**
* The qse_wcspathroot() function returns the core part of \a path * The qse_wcspathcore() function returns the core part of \a path
* excluding a special prefix. * excluding a special prefix.
*/ */
QSE_EXPORT qse_wchar_t* qse_wcspathcore ( QSE_EXPORT qse_wchar_t* qse_wcspathcore (
@ -294,15 +306,17 @@ QSE_EXPORT qse_wchar_t* qse_mergewcspathdup (
# define qse_pathcore(p) qse_mbspathcore(p) # define qse_pathcore(p) qse_mbspathcore(p)
# define qse_canonpath(p,c,f) qse_canonmbspath(p,c,f) # define qse_canonpath(p,c,f) qse_canonmbspath(p,c,f)
# define qse_mergepathdup(d,f,m) qse_mergembspathdup(d,f,m) # define qse_mergepathdup(d,f,m) qse_mergembspathdup(d,f,m)
# define qse_substbasenamedup(d,f,m) qse_substmbsbasenamedup(d,f,m)
#else #else
# define qse_isabspath(p) qse_iswcsabspath(p) # define qse_isabspath(p) qse_iswcsabspath(p)
# define qse_isdrivepath(p) qse_iswcsdrivepath(p) # define qse_isdrivepath(p) qse_iswcsdrivepath(p)
# define qse_isdriveabspath(p) qse_iswcsdriveabspath(p) # define qse_isdriveabspath(p) qse_iswcsdriveabspath(p)
# define qse_isdrivecurpath(p) qse_iswcsdrivecurpath(p) # define qse_isdrivecurpath(p) qse_iswcsdrivecurpath(p)
# define qse_basename(path) qse_wcsbasename(path) # define qse_basename(path) qse_wcsbasename(path)
# define qse_pathcore(p) qse_getpathcore(p) # define qse_pathcore(p) qse_wcspathcore(p)
# define qse_canonpath(p,c,f) qse_canonwcspath(p,c,f) # define qse_canonpath(p,c,f) qse_canonwcspath(p,c,f)
# define qse_mergepathdup(d,f,m) qse_mergewcspathdup(d,f,m) # define qse_mergepathdup(d,f,m) qse_mergewcspathdup(d,f,m)
# define qse_substbasenamedup(d,f,m) qse_substwcsbasenamedup(d,f,m)
#endif #endif
#if defined(__cplusplus) #if defined(__cplusplus)

View File

@ -38,7 +38,8 @@ typedef enum qse_raddic_opt_t qse_raddic_opt_t;
enum qse_raddic_trait_t enum qse_raddic_trait_t
{ {
QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR = (1 << 0) QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR = (1 << 0),
QSE_RADDIC_ALLOW_DUPLICATE_CONST = (1 << 1)
}; };
typedef enum qse_raddic_trait_t qse_raddic_trait_t; typedef enum qse_raddic_trait_t qse_raddic_trait_t;
@ -57,6 +58,8 @@ enum qse_raddic_errnum_t
}; };
typedef enum qse_raddic_errnum_t qse_raddic_errnum_t; typedef enum qse_raddic_errnum_t qse_raddic_errnum_t;
#if 0
#define QSE_RADDIC_ATTR_TYPE_STRING 0 #define QSE_RADDIC_ATTR_TYPE_STRING 0
#define QSE_RADDIC_ATTR_TYPE_INTEGER 1 #define QSE_RADDIC_ATTR_TYPE_INTEGER 1
#define QSE_RADDIC_ATTR_TYPE_IPADDR 2 #define QSE_RADDIC_ATTR_TYPE_IPADDR 2
@ -72,6 +75,60 @@ typedef enum qse_raddic_errnum_t qse_raddic_errnum_t;
#define QSE_RADDIC_ATTR_TYPE_SIGNED 12 #define QSE_RADDIC_ATTR_TYPE_SIGNED 12
#define QSE_RADDIC_ATTR_TYPE_COMBO_IP 13 #define QSE_RADDIC_ATTR_TYPE_COMBO_IP 13
#define QSE_RADDIC_ATTR_TYPE_TLV 14 #define QSE_RADDIC_ATTR_TYPE_TLV 14
#endif
enum qse_raddic_attr_type_t
{
QSE_RADDIC_ATTR_TYPE_INVALID = 0,
QSE_RADDIC_ATTR_TYPE_STRING,
QSE_RADDIC_ATTR_TYPE_OCTETS,
QSE_RADDIC_ATTR_TYPE_IPV4_ADDR,
QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX,
QSE_RADDIC_ATTR_TYPE_IPV6_ADDR,
QSE_RADDIC_ATTR_TYPE_IPV6_PREFIX,
QSE_RADDIC_ATTR_TYPE_IFID,
QSE_RADDIC_ATTR_TYPE_COMBO_IP_ADDR,
QSE_RADDIC_ATTR_TYPE_COMBO_IP_PREFIX,
QSE_RADDIC_ATTR_TYPE_ETHERNET,
QSE_RADDIC_ATTR_TYPE_BOOL,
QSE_RADDIC_ATTR_TYPE_UINT8,
QSE_RADDIC_ATTR_TYPE_UINT16,
QSE_RADDIC_ATTR_TYPE_UINT32,
QSE_RADDIC_ATTR_TYPE_UINT64,
QSE_RADDIC_ATTR_TYPE_INT8,
QSE_RADDIC_ATTR_TYPE_INT16,
QSE_RADDIC_ATTR_TYPE_INT32,
QSE_RADDIC_ATTR_TYPE_INT64,
QSE_RADDIC_ATTR_TYPE_FLOAT32,
QSE_RADDIC_ATTR_TYPE_FLOAT64,
QSE_RADDIC_ATTR_TYPE_TIMEVAL,
QSE_RADDIC_ATTR_TYPE_DATE,
QSE_RADDIC_ATTR_TYPE_DATE_MILLISECONDS,
QSE_RADDIC_ATTR_TYPE_DATE_MICROSECONDS,
QSE_RADDIC_ATTR_TYPE_DATE_NANOSECONDS,
QSE_RADDIC_ATTR_TYPE_ABINARY,
QSE_RADDIC_ATTR_TYPE_SIZE,
QSE_RADDIC_ATTR_TYPE_TLV,
QSE_RADDIC_ATTR_TYPE_STRUCT,
QSE_RADDIC_ATTR_TYPE_EXTENDED,
QSE_RADDIC_ATTR_TYPE_LONG_EXTENDED,
QSE_RADDIC_ATTR_TYPE_VSA,
QSE_RADDIC_ATTR_TYPE_EVS,
QSE_RADDIC_ATTR_TYPE_VENDOR
};
typedef enum qse_raddic_attr_type_t qse_raddic_attr_type_t;
struct qse_raddic_attr_flags_t struct qse_raddic_attr_flags_t
{ {

View File

@ -25,6 +25,7 @@
*/ */
#include <qse/cmn/path.h> #include <qse/cmn/path.h>
#include <qse/cmn/str.h>
#define IS_MSEP(c) QSE_ISPATHMBSEP(c) #define IS_MSEP(c) QSE_ISPATHMBSEP(c)
#define IS_WSEP(c) QSE_ISPATHWCSEP(c) #define IS_WSEP(c) QSE_ISPATHWCSEP(c)
@ -52,3 +53,52 @@ const qse_wchar_t* qse_wcsbasename (const qse_wchar_t* path)
return (last == QSE_NULL)? path: (last + 1); return (last == QSE_NULL)? path: (last + 1);
} }
qse_mchar_t* qse_substmbsbasenamedup (const qse_mchar_t* path, const qse_mchar_t* file, qse_mmgr_t* mmgr)
{
const qse_mchar_t* b;
qse_mcstr_t seg[3];
qse_size_t idx = 0;
b = qse_mbsbasename(path);
if (b)
{
seg[idx].ptr = (qse_mchar_t*)path;
seg[idx].len = b - path;
idx++;
}
seg[idx].ptr = (qse_mchar_t*)file;
seg[idx].len = qse_mbslen(file);
idx++;
seg[idx].ptr = QSE_NULL;
seg[idx].len = 0;
return qse_mcstradup (seg, QSE_NULL, mmgr);
}
qse_wchar_t* qse_substwcsbasenamedup (const qse_wchar_t* path, const qse_wchar_t* file, qse_mmgr_t* mmgr)
{
const qse_wchar_t* b;
qse_wcstr_t seg[3];
qse_size_t idx = 0;
b = qse_wcsbasename(path);
if (b)
{
seg[idx].ptr = (qse_wchar_t*)path;
seg[idx].len = b - path;
idx++;
}
seg[idx].ptr = (qse_wchar_t*)file;
seg[idx].len = qse_wcslen(file);
idx++;
seg[idx].ptr = QSE_NULL;
seg[idx].len = 0;
return qse_wcstradup (seg, QSE_NULL, mmgr);
}

View File

@ -51,6 +51,7 @@
#include <qse/cmn/htl.h> #include <qse/cmn/htl.h>
#include <qse/cmn/str.h> #include <qse/cmn/str.h>
#include <qse/cmn/chr.h> #include <qse/cmn/chr.h>
#include <qse/cmn/path.h>
#include "../cmn/mem-prv.h" #include "../cmn/mem-prv.h"
#include <qse/si/sio.h> #include <qse/si/sio.h>
#include <stdarg.h> #include <stdarg.h>
@ -101,6 +102,65 @@ struct name_id_t
static const name_id_t type_table[] = static const name_id_t type_table[] =
{ {
{ QSE_T("string"), QSE_RADDIC_ATTR_TYPE_STRING },
{ QSE_T("octets"), QSE_RADDIC_ATTR_TYPE_OCTETS },
{ QSE_T("ipaddr"), QSE_RADDIC_ATTR_TYPE_IPV4_ADDR },
{ QSE_T("ipv4prefix"), QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX },
{ QSE_T("ipv6addr"), QSE_RADDIC_ATTR_TYPE_IPV6_ADDR },
{ QSE_T("ipv6prefix"), QSE_RADDIC_ATTR_TYPE_IPV6_PREFIX },
{ QSE_T("ifid"), QSE_RADDIC_ATTR_TYPE_IFID },
{ QSE_T("combo-ip"), QSE_RADDIC_ATTR_TYPE_COMBO_IP_ADDR },
{ QSE_T("combo-prefix"), QSE_RADDIC_ATTR_TYPE_COMBO_IP_PREFIX },
{ QSE_T("ether"), QSE_RADDIC_ATTR_TYPE_ETHERNET },
{ QSE_T("bool"), QSE_RADDIC_ATTR_TYPE_BOOL },
{ QSE_T("uint8"), QSE_RADDIC_ATTR_TYPE_UINT8 },
{ QSE_T("uint16"), QSE_RADDIC_ATTR_TYPE_UINT16 },
{ QSE_T("uint32"), QSE_RADDIC_ATTR_TYPE_UINT32 },
{ QSE_T("uint64"), QSE_RADDIC_ATTR_TYPE_UINT64 },
{ QSE_T("int8"), QSE_RADDIC_ATTR_TYPE_INT8 },
{ QSE_T("int16"), QSE_RADDIC_ATTR_TYPE_INT16 },
{ QSE_T("int32"), QSE_RADDIC_ATTR_TYPE_INT32 },
{ QSE_T("int64"), QSE_RADDIC_ATTR_TYPE_INT64 },
{ QSE_T("float32"), QSE_RADDIC_ATTR_TYPE_FLOAT32 },
{ QSE_T("float64"), QSE_RADDIC_ATTR_TYPE_FLOAT64 },
{ QSE_T("timeval"), QSE_RADDIC_ATTR_TYPE_TIMEVAL },
{ QSE_T("date"), QSE_RADDIC_ATTR_TYPE_DATE },
{ QSE_T("date_milliseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MILLISECONDS },
{ QSE_T("date_microseconds"), QSE_RADDIC_ATTR_TYPE_DATE_MICROSECONDS },
{ QSE_T("date_nanoseconds"), QSE_RADDIC_ATTR_TYPE_DATE_NANOSECONDS },
{ QSE_T("abinary"), QSE_RADDIC_ATTR_TYPE_ABINARY },
{ QSE_T("size"), QSE_RADDIC_ATTR_TYPE_SIZE },
{ QSE_T("tlv"), QSE_RADDIC_ATTR_TYPE_TLV },
{ QSE_T("struct"), QSE_RADDIC_ATTR_TYPE_STRUCT },
{ QSE_T("extended"), QSE_RADDIC_ATTR_TYPE_EXTENDED },
{ QSE_T("long-extended"), QSE_RADDIC_ATTR_TYPE_LONG_EXTENDED },
{ QSE_T("vsa"), QSE_RADDIC_ATTR_TYPE_VSA },
{ QSE_T("evs"), QSE_RADDIC_ATTR_TYPE_EVS },
{ QSE_T("vendor"), QSE_RADDIC_ATTR_TYPE_VENDOR },
/*
* Alternative names
*/
{ QSE_T("cidr"), QSE_RADDIC_ATTR_TYPE_IPV4_PREFIX },
{ QSE_T("byte"), QSE_RADDIC_ATTR_TYPE_UINT8 },
{ QSE_T("short"), QSE_RADDIC_ATTR_TYPE_UINT16 },
{ QSE_T("integer"), QSE_RADDIC_ATTR_TYPE_UINT32 },
{ QSE_T("integer64"), QSE_RADDIC_ATTR_TYPE_UINT64 },
{ QSE_T("decimal"), QSE_RADDIC_ATTR_TYPE_FLOAT64 },
{ QSE_T("signed"), QSE_RADDIC_ATTR_TYPE_INT32 },
#if 0
{ QSE_T("integer"), QSE_RADDIC_ATTR_TYPE_INTEGER }, { QSE_T("integer"), QSE_RADDIC_ATTR_TYPE_INTEGER },
{ QSE_T("string"), QSE_RADDIC_ATTR_TYPE_STRING }, { QSE_T("string"), QSE_RADDIC_ATTR_TYPE_STRING },
{ QSE_T("ipaddr"), QSE_RADDIC_ATTR_TYPE_IPADDR }, { QSE_T("ipaddr"), QSE_RADDIC_ATTR_TYPE_IPADDR },
@ -116,6 +176,7 @@ static const name_id_t type_table[] =
{ QSE_T("combo-ip"), QSE_RADDIC_ATTR_TYPE_COMBO_IP }, { QSE_T("combo-ip"), QSE_RADDIC_ATTR_TYPE_COMBO_IP },
{ QSE_T("tlv"), QSE_RADDIC_ATTR_TYPE_TLV }, { QSE_T("tlv"), QSE_RADDIC_ATTR_TYPE_TLV },
{ QSE_T("signed"), QSE_RADDIC_ATTR_TYPE_SIGNED }, { QSE_T("signed"), QSE_RADDIC_ATTR_TYPE_SIGNED },
#endif
}; };
/* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */
@ -245,10 +306,9 @@ static int dict_const_name_cmp (qse_htl_t* htl, const void* one, const void* two
{ {
const qse_raddic_const_t* a = one; const qse_raddic_const_t* a = one;
const qse_raddic_const_t* b = two; const qse_raddic_const_t* b = two;
int x;
x = a->attr - b->attr; if (a->attr < b->attr) return -1;
if (x != 0) return x; if (a->attr > b->attr) return 1;
return qse_strcasecmp(a->name, b->name); return qse_strcasecmp(a->name, b->name);
} }
@ -271,10 +331,9 @@ static int dict_const_name_hetero_cmp (qse_htl_t* htl, const void* one, const vo
{ {
const const_hsd_t* hsd = (const const_hsd_t*)one; const const_hsd_t* hsd = (const const_hsd_t*)one;
const qse_raddic_const_t* b = (const qse_raddic_const_t*)two; const qse_raddic_const_t* b = (const qse_raddic_const_t*)two;
int x;
x = hsd->attr - b->attr; if (hsd->attr < b->attr) return -1;
if (x != 0) return x; if (hsd->attr > b->attr) return 1;
return qse_strcasecmp(hsd->name, b->name); return qse_strcasecmp(hsd->name, b->name);
} }
@ -290,12 +349,11 @@ static qse_uint32_t dict_const_value_hash (qse_htl_t* htl, const void* data)
static int dict_const_value_cmp (qse_htl_t* htl, const void* one, const void* two) static int dict_const_value_cmp (qse_htl_t* htl, const void* one, const void* two)
{ {
const qse_raddic_const_t *a = one; const qse_raddic_const_t* a = one;
const qse_raddic_const_t *b = two; const qse_raddic_const_t* b = two;
int x;
x = a->attr - b->attr; if (a->attr < b->attr) return -1;
if (x != 0) return x; if (a->attr > b->attr) return 1;
return a->value - b->value; return a->value - b->value;
} }
@ -982,8 +1040,19 @@ qse_raddic_const_t* qse_raddic_addconst (qse_raddic_t* dic, const qse_char_t* na
if (!np || np->data != dval) if (!np || np->data != dval)
{ {
/* insertion failure or existing item found */ /* insertion failure or existing item found */
if (!np) qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM); if (!np)
else qse_raddic_seterrfmt (dic, QSE_RADDIC_EEXIST, QSE_T("existing constant %s"), name); {
qse_raddic_seterrnum (dic, QSE_RADDIC_ENOMEM);
}
else
{
if ((dic->opt.trait & QSE_RADDIC_ALLOW_DUPLICATE_CONST) && ((qse_raddic_const_t*)np->data)->value == dval->value)
{
QSE_MMGR_FREE (dic->mmgr, dval);
return np->data;
}
qse_raddic_seterrfmt (dic, QSE_RADDIC_EEXIST, QSE_T("existing constant %s"), name);
}
QSE_MMGR_FREE (dic->mmgr, dval); QSE_MMGR_FREE (dic->mmgr, dval);
return QSE_NULL; return QSE_NULL;
@ -1198,12 +1267,13 @@ static int process_attribute (
{ {
flags.array = 1; flags.array = 1;
/* TODO: ... */
switch (type) switch (type)
{ {
case QSE_RADDIC_ATTR_TYPE_IPADDR: case QSE_RADDIC_ATTR_TYPE_IPV4_ADDR:
case QSE_RADDIC_ATTR_TYPE_BYTE: case QSE_RADDIC_ATTR_TYPE_UINT8:
case QSE_RADDIC_ATTR_TYPE_SHORT: case QSE_RADDIC_ATTR_TYPE_UINT16:
case QSE_RADDIC_ATTR_TYPE_INTEGER: case QSE_RADDIC_ATTR_TYPE_UINT32:
case QSE_RADDIC_ATTR_TYPE_DATE: case QSE_RADDIC_ATTR_TYPE_DATE:
break; break;
@ -1237,7 +1307,7 @@ static int process_attribute (
switch (type) switch (type)
{ {
case QSE_RADDIC_ATTR_TYPE_STRING: case QSE_RADDIC_ATTR_TYPE_STRING:
case QSE_RADDIC_ATTR_TYPE_INTEGER: case QSE_RADDIC_ATTR_TYPE_UINT32:
break; break;
default: default:
@ -1324,93 +1394,6 @@ static int process_constant(qse_raddic_t* dic, const qse_char_t* fn, const qse_s
return 0; return 0;
} }
#if 0
/*
* Process the VALUE-ALIAS command
*
* This allows VALUE mappings to be shared among multiple
* attributes.
*/
static int process_constant_alias(qse_raddic_t* dic, const qse_char_t* fn, const qse_size_t line, qse_char_t** argv, int argc)
{
qse_raddic_attr_t* my_da, * da;
qse_raddic_const_t* dval;
if (argc != 2)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: invalid VALUE-ALIAS line", fn, line);
return -1;
}
my_da = qse_raddic_findattrbyname(argv[0]);
if (!my_da)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: ATTRIBUTE \"%s\" does not exist",
// fn, line, argv[1]);
return -1;
}
if (my_da->flags.has_value)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE",
// fn, line, argv[0]);
return -1;
}
if (my_da->flags.has_value_alias)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" with pre-existing VALUE-ALIAS",
// fn, line, argv[0]);
return -1;
}
da = qse_raddic_findattrbyname(argv[1]);
if (!da)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Cannot find ATTRIBUTE \"%s\" for alias", fn, line, argv[1]);
return -1;
}
if (!da->flags.has_value)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: VALUE-ALIAS cannot refer to ATTRIBUTE %s: It has no values", fn, line, argv[1]);
return -1;
}
if (da->flags.has_value_alias)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Cannot add VALUE-ALIAS to ATTRIBUTE \"%s\" which itself has a VALUE-ALIAS", fn, line, argv[1]);
return -1;
}
if (my_da->type != da->type)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Cannot add VALUE-ALIAS between attributes of differing type",
fn, line);
return -1;
}
if ((dval = fr_pool_alloc(QSE_SIZEOF(*dval))) == QSE_NULL) {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, "dict_addvalue: out of memory");
return -1;
}
dval->name[0] = '\0'; /* empty name */
dval->attr = my_da->attr;
dval->value = da->attr;
if (!fr_hash_table_insert(values_byname, dval)) {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: Error create alias"), fn, line);
fr_pool_free(dval);
return -1;
}
return 0;
}
#endif
/* /*
* Process the VENDOR command * Process the VENDOR command
*/ */
@ -1455,7 +1438,6 @@ static int process_vendor (qse_raddic_t* dic, const qse_char_t* fn, const qse_si
else if (value == VENDORPEC_USR) else if (value == VENDORPEC_USR)
{ /* catch dictionary screw-ups */ { /* catch dictionary screw-ups */
format = QSE_T("format=4,0"); format = QSE_T("format=4,0");
} }
else if (value == VENDORPEC_LUCENT) else if (value == VENDORPEC_LUCENT)
{ {
@ -1526,13 +1508,10 @@ static int process_vendor (qse_raddic_t* dic, const qse_char_t* fn, const qse_si
return 0; return 0;
} }
static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t *fn, const qse_char_t *src_file, int src_line) static int load_file (qse_raddic_t* dic, const qse_char_t* dir, const qse_char_t* fn, const qse_char_t* src_file, qse_size_t src_line)
{ {
qse_sio_t* sio = QSE_NULL; qse_sio_t* sio = QSE_NULL;
#if 0 qse_char_t buf[256]; /* TODO: is this a good size? */
qse_char_t dirtmp[256]; /* TODO: longer path */
#endif
qse_char_t buf[256];
qse_char_t* p; qse_char_t* p;
qse_size_t line = 0; qse_size_t line = 0;
qse_raddic_vendor_t* vendor; qse_raddic_vendor_t* vendor;
@ -1541,40 +1520,31 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
qse_char_t* argv[16]; /* TODO: what is the best size? */ qse_char_t* argv[16]; /* TODO: what is the best size? */
int argc; int argc;
qse_raddic_attr_t* da, * block_tlv = QSE_NULL; qse_raddic_attr_t* da, * block_tlv = QSE_NULL;
qse_char_t* fname = (qse_char_t*)fn;
#if 0 if (!qse_isabspath(fn) && src_file)
if (qse_strlen(fn) >= QSE_SIZEOF(dirtmp) / 2 ||
qse_strlen(dir) >= QSE_SIZEOF(dirtmp) / 2)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("filename name too long"); const qse_char_t* b = qse_basename(src_file);
if (b != src_file)
{
fname = qse_substbasenamedup (src_file, fn, dic->mmgr);
if (!fname)
{
qse_raddic_seterrfmt (dic, QSE_RADDIC_ENOMEM, QSE_T("%s[%zd]: out of memory before including %s"), fn);
return -1; return -1;
} }
qse_canonpath (fname, fname, 0);
/*
* First see if fn is relative to dir. If so, create
* new filename. If not, remember the absolute dir.
*/
if ((p = qse_strrchr(fn, FR_DIR_SEP)) != QSE_NULL)
{
qse_strcpy(dirtmp, fn);
dirtmp[p - fn] = 0;
dir = dirtmp;
} }
else if (dir && dir[0] && qse_strcmp(dir, ".") != 0)
{
snprintf(dirtmp, QSE_SIZEOF(dirtmp), "%s/%s", dir, fn);
fn = dirtmp;
} }
#endif
sio = qse_sio_open (dic->mmgr, 0, fn, QSE_SIO_READ); sio = qse_sio_open (dic->mmgr, 0, fname, QSE_SIO_READ);
if (!sio) if (!sio)
{ {
if (src_file) if (src_file)
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot open %s"), src_file, src_line, fn); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: cannot open %s"), src_file, src_line, fname);
else else
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("cannot open %s"), fn); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("cannot open %s"), fname);
return -1; goto oops;
} }
block_vendor = 0; block_vendor = 0;
@ -1598,7 +1568,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
if (argc == 1) if (argc == 1)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid entry"), fn, line); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid entry"), fname, line);
goto oops; goto oops;
} }
@ -1607,7 +1577,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
*/ */
if (qse_strcasecmp(argv[0], QSE_T("VALUE")) == 0) if (qse_strcasecmp(argv[0], QSE_T("VALUE")) == 0)
{ {
if (process_constant(dic, fn, line, argv + 1, argc - 1) == -1) goto oops; if (process_constant(dic, fname, line, argv + 1, argc - 1) == -1) goto oops;
continue; continue;
} }
@ -1616,7 +1586,7 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
*/ */
if (qse_strcasecmp(argv[0], QSE_T("ATTRIBUTE")) == 0) if (qse_strcasecmp(argv[0], QSE_T("ATTRIBUTE")) == 0)
{ {
if (process_attribute(dic, fn, line, (block_vendor? block_vendor->vendorpec: 0), block_tlv, argv + 1, argc - 1) == -1) goto oops; if (process_attribute(dic, fname, line, (block_vendor? block_vendor->vendorpec: 0), block_tlv, argv + 1, argc - 1) == -1) goto oops;
continue; continue;
} }
@ -1625,24 +1595,16 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
*/ */
if (qse_strcasecmp(argv[0], QSE_T("$INCLUDE")) == 0) if (qse_strcasecmp(argv[0], QSE_T("$INCLUDE")) == 0)
{ {
if (load_file(dic, dir, argv[1], fn, line) < 0) goto oops; if (load_file(dic, dir, argv[1], fname, line) < 0) goto oops;
continue; continue;
} /* $INCLUDE */ } /* $INCLUDE */
#if 0
if (qse_strcasecmp(argv[0], QSE_T("VALUE-ALIAS")) == 0)
{
if (process_constant_alias(dic, fn, line, argv + 1, argc - 1) == -1) goto oops;
continue;
}
#endif
/* /*
* Process VENDOR lines. * Process VENDOR lines.
*/ */
if (qse_strcasecmp(argv[0], QSE_T("VENDOR")) == 0) if (qse_strcasecmp(argv[0], QSE_T("VENDOR")) == 0)
{ {
if (process_vendor(dic, fn, line, argv + 1, argc - 1) == -1) goto oops; if (process_vendor(dic, fname, line, argv + 1, argc - 1) == -1) goto oops;
continue; continue;
} }
@ -1650,20 +1612,20 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
{ {
if (argc != 2) if (argc != 2)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid BEGIN-TLV entry"), fn, line); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid BEGIN-TLV entry"), fname, line);
goto oops; goto oops;
} }
da = qse_raddic_findattrbyname (dic, argv[1]); da = qse_raddic_findattrbyname (dic, argv[1]);
if (!da) if (!da)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown attribute %s"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown attribute %s"), fname, line, argv[1]);
goto oops; goto oops;
} }
if (da->type != QSE_RADDIC_ATTR_TYPE_TLV) if (da->type != QSE_RADDIC_ATTR_TYPE_TLV)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: attribute %s is not of type tlv"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: attribute %s is not of type tlv"), fname, line, argv[1]);
goto oops; goto oops;
} }
@ -1675,20 +1637,20 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
{ {
if (argc != 2) if (argc != 2)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid END-TLV entry"), fn, line); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid END-TLV entry"), fname, line);
goto oops; goto oops;
} }
da = qse_raddic_findattrbyname(dic, argv[1]); da = qse_raddic_findattrbyname(dic, argv[1]);
if (!da) if (!da)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown attribute %s"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown attribute %s"), fname, line, argv[1]);
goto oops; goto oops;
} }
if (da != block_tlv) if (da != block_tlv)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: END-TLV %s does not match any previous BEGIN-TLV"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: END-TLV %s does not match any previous BEGIN-TLV"), fname, line, argv[1]);
goto oops; goto oops;
} }
block_tlv = QSE_NULL; block_tlv = QSE_NULL;
@ -1699,14 +1661,14 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
{ {
if (argc != 2) if (argc != 2)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid BEGIN-VENDOR entry"), fn, line); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid BEGIN-VENDOR entry"), fname, line);
goto oops; goto oops;
} }
vendor = qse_raddic_findvendorbyname (dic, argv[1]); vendor = qse_raddic_findvendorbyname (dic, argv[1]);
if (!vendor) if (!vendor)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor %s"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor %s"), fname, line, argv[1]);
goto oops; goto oops;
} }
block_vendor = vendor; block_vendor = vendor;
@ -1717,21 +1679,21 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
{ {
if (argc != 2) if (argc != 2)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid END-VENDOR entry"), fn, line); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid END-VENDOR entry"), fname, line);
goto oops; goto oops;
} }
vendor = qse_raddic_findvendorbyname(dic, argv[1]); vendor = qse_raddic_findvendorbyname(dic, argv[1]);
if (!vendor) if (!vendor)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor %s"), fn, line, argv[1]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd]: unknown vendor %s"), fname, line, argv[1]);
goto oops; goto oops;
} }
if (vendor != block_vendor) if (vendor != block_vendor)
{ {
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR,
QSE_T("%s[%zd]: END-VENDOR %s does not match any previous BEGIN-VENDOR"), fn, line, argv[1]); QSE_T("%s[%zd]: END-VENDOR %s does not match any previous BEGIN-VENDOR"), fname, line, argv[1]);
goto oops; goto oops;
} }
block_vendor = 0; block_vendor = 0;
@ -1741,16 +1703,18 @@ static int load_file (qse_raddic_t* dic, const qse_char_t *dir, const qse_char_t
/* /*
* Any other string: We don't recognize it. * Any other string: We don't recognize it.
*/ */
qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid keyword \"%s\""), fn, line, argv[0]); qse_raddic_seterrfmt (dic, QSE_RADDIC_ESYNERR, QSE_T("%s[%zd] invalid keyword \"%s\""), fname, line, argv[0]);
goto oops; goto oops;
} }
qse_sio_close (sio); qse_sio_close (sio);
if (fname != fn) QSE_MMGR_FREE (dic->mmgr, fname);
return 0; return 0;
oops: oops:
if (sio) qse_sio_close (sio); if (sio) qse_sio_close (sio);
if (fname != fn) QSE_MMGR_FREE (dic->mmgr, fname);
return -1; return -1;
} }

View File

@ -398,11 +398,11 @@ static int test3 ()
dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0); dic = qse_raddic_open (QSE_MMGR_GETDFL(), 0);
_assert (dic != QSE_NULL, QSE_T("unable to create a radius dictionary")); _assert (dic != QSE_NULL, QSE_T("unable to create a radius dictionary"));
trait = QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR; trait = QSE_RADDIC_ALLOW_CONST_WITHOUT_ATTR | QSE_RADDIC_ALLOW_DUPLICATE_CONST;
n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait); n = qse_raddic_setopt (dic, QSE_RADDIC_TRAIT, &trait);
_assert (n == 0, QSE_T("cannot set trait")); _assert (n == 0, QSE_T("cannot set trait"));
n = qse_raddic_load (dic, QSE_T("dictionary")); n = qse_raddic_load (dic, QSE_T("fr/dictionary"));
_assert (n == 0, qse_raddic_geterrmsg(dic)); _assert (n == 0, qse_raddic_geterrmsg(dic));
qse_raddic_close (dic); qse_raddic_close (dic);