Merge pull request #2408 from DennisHeimbigner/rcapi.dmh

Make public a limited API for programmatic access to internal .rc tables
This commit is contained in:
Ward Fisher 2022-06-21 10:03:45 -06:00 committed by GitHub
commit a3998aa2f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 414 additions and 127 deletions

View File

@ -69,7 +69,7 @@ endif()
if(MSVC)
SET(ISMSVC yes)
endif()
if(osname MATCHES "MINGW.*")
if(osname MATCHES "MINGW.*" OR osname MATCHES "MSYS.*")
SET(ISMINGW yes)
SET(MINGW yes)
endif()

View File

@ -7,7 +7,7 @@ This file contains a high-level description of this package's evolution. Release
## 4.9.1 - T.B.D.
* [Enhancement] Provide a simple API to allow user access to the internal .rc file table: supports get/set/overwrite of entries of the form "key=value". See [Github #2408](https://github.com/Unidata/netcdf-c/pull/2408).
* [Bug Fix] Use env variable USERPROFILE instead of HOME for windows and mingw. See [Github #2405](https://github.com/Unidata/netcdf-c/pull/2405).
* [Bug Fix] Fix the nc_def_var_fletcher32 code in hdf5 to properly test value of the fletcher32 argument. See [Github #2403](https://github.com/Unidata/netcdf-c/pull/2403).

View File

@ -107,6 +107,7 @@ case "`uname`" in
Darwin*) ISOSX=yes;;
WIN*) ISMSVC=yes;;
MINGW*) ISMINGW=yes;;
MSYS*) ISMINGW=yes;;
esac
if test "x$MSYSTEM" != x ; then

View File

@ -28,7 +28,7 @@ and accessing rc files (e.g. .daprc).
typedef struct NCRCentry {
char* host; /* combined host:port */
char* path; /* prefix to match or NULL */
char* urlpath; /* prefix to match or NULL */
char* key;
char* value;
} NCRCentry;
@ -67,7 +67,7 @@ extern "C" {
/* From drc.c */
EXTERNL void ncrc_initialize(void);
EXTERNL int NC_rcfile_insert(const char* key, const char* value, const char* hostport, const char* path);
EXTERNL int NC_rcfile_insert(const char* key, const char* hostport, const char* path, const char* value);
EXTERNL char* NC_rclookup(const char* key, const char* hostport, const char* path);
EXTERNL char* NC_rclookupx(NCURI* uri, const char* key);

View File

@ -2095,6 +2095,14 @@ EXTERNL int nc_initialize(void);
*/
EXTERNL int nc_finalize(void);
/* Programmatic access to the internal .rc table */
/* Get the value corresponding to key | return NULL; caller frees result */
EXTERNL char* nc_rc_get(const char* key);
/* Set/overwrite the value corresponding to key */
EXTERNL int nc_rc_set(const char* key, const char* value);
#if defined(__cplusplus)
}
#endif

View File

@ -95,7 +95,6 @@ NCDISPATCH_initialize(void)
NCpathcanonical(home,&globalstate->home);
nullfree(home);
}
fprintf(stderr,">>> HOME=|%s|\n",globalstate->home); fflush(stderr);
/* Capture $CWD */
{

View File

@ -22,7 +22,9 @@
#include "nclog.h"
#include "ncbytes.h"
#include "nclist.h"
#include "ncuri.h"
#include "nchttp.h"
#include "ncauth.h"
#undef TRACE
@ -482,6 +484,23 @@ setupconn(NC_HTTP_STATE* state, const char* objecturl)
cstat = curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);
if (cstat != CURLE_OK) goto fail;
/* Pull some values from .rc tables */
{
NCURI* uri = NULL;
char* hostport = NULL;
char* value = NULL;
ncuriparse(objecturl,&uri);
if(uri == NULL) goto fail;
hostport = NC_combinehostport(uri);
value = NC_rclookup("HTTP.SSL.CAINFO",hostport,NULL);
if(value == NULL)
value = NC_rclookup("HTTP.SSL.CAINFO",NULL,NULL);
if(value != NULL) {
cstat = CURLERR(curl_easy_setopt(state->curl, CURLOPT_CAINFO, value));
if (cstat != CURLE_OK) goto fail;
}
}
/* Set the method */
if((stat = nc_http_set_method(state,state->request.method))) goto done;

View File

@ -23,6 +23,7 @@ See COPYRIGHT for license information.
#include "ncauth.h"
#include "ncpathmgr.h"
#include "nc4internal.h"
#include "ncdispatch.h"
#ifndef nulldup
#define nulldup(x) ((x)?strdup(x):(x))
@ -38,8 +39,6 @@ See COPYRIGHT for license information.
#define RTAG ']'
#define LTAG '['
#define TRIMCHARS " \t\r\n"
#undef MEMCHECK
#define MEMCHECK(x) if((x)==NULL) {goto nomem;} else {}
@ -52,9 +51,12 @@ static char* rcreadline(char** nextlinep);
static void rctrim(char* text);
static void rcorder(NClist* rc);
static int rccompile(const char* path);
static struct NCRCentry* rclocate(const char* key, const char* hostport, const char* path);
static int rcequal(NCRCentry* e1, NCRCentry* e2);
static int rclocatepos(const char* key, const char* hostport, const char* urlpath);
static struct NCRCentry* rclocate(const char* key, const char* hostport, const char* urlpath);
static int rcsearch(const char* prefix, const char* rcname, char** pathp);
static void rcfreeentries(NClist* rc);
static void rcfreeentry(NCRCentry* t);
#ifdef DRCDEBUG
static void storedump(char* msg, NClist* entrys);
#endif
@ -68,11 +70,64 @@ static const char* rcfilenames[] = {".ncrc", ".daprc", ".dodsrc",NULL};
/* Read these files */
static const char* awsconfigfiles[] = {".aws/credentials",".aws/config",NULL};
static int NCRCinitialized = 0;
/**************************************************/
/* User API */
/**
The most common case is to get the most general value for a key,
where most general means that the urlpath and hostport are null
So this function returns the value associated with the key
where the .rc entry has the simple form "key=value".
If that entry is not found, then return NULL.
@param key table entry key field
@return value matching the key -- caller frees
@return NULL if no entry of the form key=value exists
*/
char*
nc_rc_get(const char* key)
{
NCglobalstate* ncg = NULL;
char* value = NULL;
if(!NC_initialized) nc_initialize();
ncg = NC_getglobalstate();
assert(ncg != NULL && ncg->rcinfo != NULL && ncg->rcinfo->entries != NULL);
if(ncg->rcinfo->ignore) return NC_NOERR;
value = NC_rclookup(key,NULL,NULL);
return nulldup(value);
}
/**
Set simple key=value in .rc table.
Will overwrite any existing value.
@param key
@param value
@return NC_NOERR if success
@return NC_EINVAL if fail
*/
int
nc_rc_set(const char* key, const char* value)
{
int stat = NC_NOERR;
NCglobalstate* ncg = NULL;
if(!NC_initialized) nc_initialize();
ncg = NC_getglobalstate();
assert(ncg != NULL && ncg->rcinfo != NULL && ncg->rcinfo->entries != NULL);
if(ncg->rcinfo->ignore) return NC_NOERR;
stat = NC_rcfile_insert(key,NULL,NULL,value);
return stat;
}
/**************************************************/
/* External Entry Points */
static int NCRCinitialized = 0;
/*
Initialize defaults and load:
* .ncrc
@ -96,13 +151,14 @@ ncrc_initialize(void)
if(NCRCinitialized) return;
NCRCinitialized = 1; /* prevent recursion */
ncg = NC_getglobalstate();
#ifndef NOREAD
/* Load entrys */
if((stat = NC_rcload())) {
nclog(NCLOGWARN,".rc loading failed");
}
/* Load .aws/config */
ncg = NC_getglobalstate();
if((stat = aws_load_credentials(ncg))) {
nclog(NCLOGWARN,"AWS config file not loaded");
}
@ -120,6 +176,9 @@ ncrc_setrchome(void)
if(tmp == NULL || strlen(tmp) == 0)
tmp = ncg->home;
ncg->rcinfo->rchome = strdup(tmp);
#ifdef DRCDEBUG
fprintf(stderr,"ncrc_setrchome: %s\n",ncg->rcinfo->rchome);
#endif
}
void
@ -132,16 +191,23 @@ NC_rcclear(NCRCinfo* info)
freeprofilelist(info->s3profiles);
}
static void
rcfreeentry(NCRCentry* t)
{
nullfree(t->host);
nullfree(t->urlpath);
nullfree(t->key);
nullfree(t->value);
free(t);
}
static void
rcfreeentries(NClist* rc)
{
int i;
for(i=0;i<nclistlength(rc);i++) {
NCRCentry* t = (NCRCentry*)nclistget(rc,i);
nullfree(t->host);
nullfree(t->key);
nullfree(t->value);
free(t);
rcfreeentry(t);
}
nclistfree(rc);
}
@ -182,8 +248,7 @@ NC_rcload(void)
const char* dirnames[3];
const char** dir;
/* Make sure rcinfo.rchome is defined */
/* Make sure rcinfo.rchome is defined */
ncrc_setrchome();
dirnames[0] = globalstate->rcinfo->rchome;
dirnames[1] = globalstate->cwd;
@ -214,15 +279,15 @@ done:
}
/**
* Locate a entry by property key and host+port (may be null|"")
* Locate a entry by property key and host+port (may be null)
* If duplicate keys, first takes precedence.
*/
char*
NC_rclookup(const char* key, const char* hostport, const char* path)
NC_rclookup(const char* key, const char* hostport, const char* urlpath)
{
struct NCRCentry* entry = NULL;
if(!NCRCinitialized) ncrc_initialize();
entry = rclocate(key,hostport,path);
entry = rclocate(key,hostport,urlpath);
return (entry == NULL ? NULL : entry->value);
}
@ -248,8 +313,7 @@ Set the absolute path to use for the rc file.
WARNING: this MUST be called before any other
call in order for this to take effect.
\param[in] rcfile The path to use. If NULL, or "",
then do not use any rcfile.
\param[in] rcfile The path to use. If NULL then do not use any rcfile.
\retval OC_NOERR if the request succeeded.
\retval OC_ERCFILE if the file failed to load
@ -305,25 +369,26 @@ rcreadline(char** nextlinep)
static void
rctrim(char* text)
{
char* p = text;
char* p;
char* q;
size_t len = 0;
int i;
if(text == NULL) return;
if(text == NULL || *text == '\0') return;
/* locate first non-trimchar */
for(;*p;p++) {
if(strchr(TRIMCHARS,*p) == NULL) break; /* hit non-trim char */
}
memmove(text,p,strlen(p)+1);
len = strlen(text);
/* elide upto first non-trimchar */
for(q=text,p=text;*p;p++) {
if(*p != ' ' && *p != '\t' && *p != '\r') {*q++ = *p;}
}
len = strlen(p);
/* locate last non-trimchar */
if(len > 0) {
for(i=(len-1);i>=0;i--) {
if(strchr(TRIMCHARS,text[i]) == NULL) {
text[i+1] = '\0'; /* elide trailing trimchars */
break;
}
p = &text[i];
if(*p != ' ' && *p != '\t' && *p != '\r') {break;}
*p = '\0'; /* elide trailing trimchars */
}
}
}
@ -339,22 +404,22 @@ rcorder(NClist* rc)
NClist* tmprc = NULL;
if(rc == NULL || len == 0) return;
tmprc = nclistnew();
/* Copy rc into tmprc and clear rc */
for(i=0;i<len;i++) {
NCRCentry* ti = nclistget(rc,i);
nclistpush(tmprc,ti);
}
nclistclear(rc);
/* Two passes: 1) pull entries with host */
for(i=0;i<len;i++) {
NCRCentry* ti = nclistget(tmprc,i);
NCRCentry* ti = nclistget(rc,i);
if(ti->host == NULL) continue;
nclistpush(rc,ti);
nclistpush(tmprc,ti);
}
/* pass 2 pull entries without host*/
for(i=0;i<len;i++) {
NCRCentry* ti = nclistget(tmprc,i);
NCRCentry* ti = nclistget(rc,i);
if(ti->host != NULL) continue;
nclistpush(tmprc,ti);
}
/* Move tmp to rc */
nclistsetlength(rc,0);
for(i=0;i<len;i++) {
NCRCentry* ti = nclistget(tmprc,i);
nclistpush(rc,ti);
}
#ifdef DRCDEBUG
@ -365,7 +430,7 @@ rcorder(NClist* rc)
/* Merge a entry store from a file*/
static int
rccompile(const char* path)
rccompile(const char* filepath)
{
int ret = NC_NOERR;
NClist* rc = NULL;
@ -376,8 +441,8 @@ rccompile(const char* path)
NCglobalstate* globalstate = NC_getglobalstate();
char* bucket = NULL;
if((ret=NC_readfile(path,tmp))) {
nclog(NCLOGWARN, "Could not open configuration file: %s",path);
if((ret=NC_readfile(filepath,tmp))) {
nclog(NCLOGWARN, "Could not open configuration file: %s",filepath);
goto done;
}
contents = ncbytesextract(tmp);
@ -394,6 +459,7 @@ rccompile(const char* path)
char* key = NULL;
char* value = NULL;
char* host = NULL;
char* urlpath = NULL;
size_t llen;
NCRCentry* entry;
@ -406,7 +472,7 @@ rccompile(const char* path)
char* url = ++line;
char* rtag = strchr(line,RTAG);
if(rtag == NULL) {
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",filepath,line);
continue;
}
line = rtag + 1;
@ -414,17 +480,18 @@ rccompile(const char* path)
/* compile the url and pull out the host and protocol */
if(uri) ncurifree(uri);
if(ncuriparse(url,&uri)) {
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",path,line);
nclog(NCLOGERR, "Malformed [url] in %s entry: %s",filepath,line);
continue;
}
{ NCURI* newuri = NULL;
/* Rebuild the url to path format */
/* Rebuild the url to S3 "path" format */
nullfree(bucket);
if((ret = NC_s3urlrebuild(uri,&newuri,&bucket,NULL))) goto done;
ncurifree(uri);
uri = newuri;
newuri = NULL;
}
/* Get the host+port */
ncbytesclear(tmp);
ncbytescat(tmp,uri->host);
if(uri->port != NULL) {
@ -433,8 +500,11 @@ rccompile(const char* path)
}
ncbytesnull(tmp);
host = ncbytesextract(tmp);
if(strlen(host)==0)
if(strlen(host)==0) /* nullify host */
{free(host); host = NULL;}
/* Get the url path part */
urlpath = uri->path;
if(urlpath && strlen(urlpath)==0) urlpath = NULL; /* nullify */
}
/* split off key and value */
key=line;
@ -446,31 +516,33 @@ rccompile(const char* path)
value++;
}
/* See if key already exists */
entry = rclocate(key,host,path);
if(entry != NULL) {
nullfree(entry->host);
nullfree(entry->key);
nullfree(entry->value);
} else {
entry = rclocate(key,host,urlpath);
if(entry == NULL) {
entry = (NCRCentry*)calloc(1,sizeof(NCRCentry));
if(entry == NULL) {ret = NC_ENOMEM; goto done;}
nclistpush(rc,entry);
entry->host = host; host = NULL;
entry->urlpath = nulldup(urlpath);
entry->key = nulldup(key);
rctrim(entry->host);
rctrim(entry->urlpath);
rctrim(entry->key);
}
entry->host = host; host = NULL;
entry->key = nulldup(key);
nullfree(entry->value);
entry->value = nulldup(value);
rctrim(entry->host);
rctrim(entry->key);
rctrim(entry->value);
#ifdef DRCDEBUG
fprintf(stderr,"rc: host=%s key=%s value=%s\n",
fprintf(stderr,"rc: host=%s urlpath=%s key=%s value=%s\n",
(entry->host != NULL ? entry->host : "<null>"),
(entry->urlpath != NULL ? entry->urlpath : "<null>"),
entry->key,entry->value);
#endif
entry = NULL;
}
#ifdef DRCDEBUG
fprintf(stderr,"reorder.path=%s\n",filepath);
#endif
rcorder(rc);
done:
@ -480,47 +552,84 @@ done:
return (ret);
}
/**
Encapsulate equality comparison: return 1|0
*/
static int
rcequal(NCRCentry* e1, NCRCentry* e2)
{
int nulltest;
if(e1->key == NULL || e2->key == NULL) return 0;
if(strcmp(e1->key,e2->key) != 0) return 0;
/* test hostport; take NULL into account*/
nulltest = 0;
if(e1->host == NULL) nulltest |= 1;
if(e2->host == NULL) nulltest |= 2;
switch (nulltest) {
case 0: if(strcmp(e1->host,e2->host) != 0) {return 0;} break;
case 1: return 0;
case 2: return 0;
case 3: break;
default: return 0;
}
/* test urlpath take NULL into account*/
nulltest = 0;
if(e1->urlpath == NULL) nulltest |= 1;
if(e2->urlpath == NULL) nulltest |= 2;
switch (nulltest) {
case 0: if(strcmp(e1->urlpath,e2->urlpath) != 0) {return 0;} break;
case 1: return 0;
case 2: return 0;
case 3: break;
default: return 0;
}
return 1;
}
/**
* (Internal) Locate a entry by property key and host+port (may be null) and urlpath (may be null)
* If duplicate keys, first takes precedence.
*/
static int
rclocatepos(const char* key, const char* hostport, const char* urlpath)
{
int i;
NCglobalstate* globalstate = NC_getglobalstate();
struct NCRCinfo* info = globalstate->rcinfo;
NCRCentry* entry = NULL;
NCRCentry candidate;
NClist* rc = info->entries;
if(info->ignore) return -1;
candidate.key = (char*)key;
candidate.value = (char*)NULL;
candidate.host = (char*)hostport;
candidate.urlpath = (char*)urlpath;
for(i=0;i<nclistlength(rc);i++) {
entry = (NCRCentry*)nclistget(rc,i);
if(rcequal(entry,&candidate)) return i;
}
return -1;
}
/**
* (Internal) Locate a entry by property key and host+port (may be null or "").
* If duplicate keys, first takes precedence.
*/
static struct NCRCentry*
rclocate(const char* key, const char* hostport, const char* path)
rclocate(const char* key, const char* hostport, const char* urlpath)
{
int i,found;
int pos;
NCglobalstate* globalstate = NC_getglobalstate();
NClist* rc = globalstate->rcinfo->entries;
NCRCentry* entry = NULL;
struct NCRCinfo* info = globalstate->rcinfo;
if(globalstate->rcinfo->ignore)
return NULL;
if(key == NULL || rc == NULL) return NULL;
if(hostport == NULL) hostport = "";
for(found=0,i=0;i<nclistlength(rc);i++) {
int t;
size_t hplen;
entry = (NCRCentry*)nclistget(rc,i);
hplen = (entry->host == NULL ? 0 : strlen(entry->host));
if(strcmp(key,entry->key) != 0) continue; /* keys do not match */
/* If the entry entry has no url, then use it
(because we have checked all other cases)*/
if(hplen == 0) {found=1;break;}
/* do hostport match */
t = 0;
if(entry->host != NULL)
t = strcmp(hostport,entry->host);
/* do path prefix match */
if(entry->path != NULL) {
size_t pathlen = strlen(entry->path);
t = strncmp(path,entry->path,pathlen);
}
if(t == 0) {found=1; break;}
}
return (found?entry:NULL);
if(globalstate->rcinfo->ignore) return NULL;
if(key == NULL || info == NULL) return NULL;
pos = rclocatepos(key,hostport,urlpath);
if(pos < 0) return NULL;
return NC_rcfile_ith(info,(size_t)pos);
}
/**
@ -562,7 +671,7 @@ done:
}
int
NC_rcfile_insert(const char* key, const char* value, const char* hostport, const char* path)
NC_rcfile_insert(const char* key, const char* hostport, const char* urlpath, const char* value)
{
int ret = NC_NOERR;
/* See if this key already defined */
@ -571,6 +680,10 @@ NC_rcfile_insert(const char* key, const char* value, const char* hostport, const
NClist* rc = NULL;
if(!NCRCinitialized) ncrc_initialize();
if(key == NULL || value == NULL)
{ret = NC_EINVAL; goto done;}
globalstate = NC_getglobalstate();
rc = globalstate->rcinfo->entries;
@ -579,19 +692,25 @@ NC_rcfile_insert(const char* key, const char* value, const char* hostport, const
globalstate->rcinfo->entries = rc;
if(rc == NULL) {ret = NC_ENOMEM; goto done;}
}
entry = rclocate(key,hostport,path);
entry = rclocate(key,hostport,urlpath);
if(entry == NULL) {
entry = (NCRCentry*)calloc(1,sizeof(NCRCentry));
if(entry == NULL) {ret = NC_ENOMEM; goto done;}
entry->key = strdup(key);
entry->value = NULL;
rctrim(entry->key);
entry->host = (hostport == NULL ? NULL : strdup(hostport));
entry->host = nulldup(hostport);
rctrim(entry->host);
entry->urlpath = nulldup(urlpath);
rctrim(entry->urlpath);
nclistpush(rc,entry);
}
if(entry->value != NULL) free(entry->value);
entry->value = strdup(value);
rctrim(entry->value);
#ifdef DRCDEBUG
storedump("NC_rcfile_insert",rc);
#endif
done:
return ret;
}

View File

@ -2105,8 +2105,12 @@ NC_createglobalstate(void)
nc_globalstate = calloc(1,sizeof(NCglobalstate));
}
/* Initialize struct pointers */
nc_globalstate->rcinfo = (struct NCRCinfo*)calloc(1,sizeof(struct NCRCinfo));
if(nc_globalstate == NULL) return NC_ENOMEM;
if((nc_globalstate->rcinfo = calloc(1,sizeof(struct NCRCinfo)))==NULL)
{stat = NC_ENOMEM; goto done;}
if((nc_globalstate->rcinfo->entries = nclistnew())==NULL)
{stat = NC_ENOMEM; goto done;}
if((nc_globalstate->rcinfo->s3profiles = nclistnew())==NULL)
{stat = NC_ENOMEM; goto done;}
/* Get environment variables */
if(getenv(NCRCENVIGNORE) != NULL)
@ -2119,6 +2123,7 @@ NC_createglobalstate(void)
nc_globalstate->chunkcache.nelems = CHUNK_CACHE_NELEMS; /**< Default chunk cache number of elements. */
nc_globalstate->chunkcache.preemption = CHUNK_CACHE_PREEMPTION; /**< Default chunk cache preemption. */
done:
return stat;
}

View File

@ -397,7 +397,7 @@ main(int argc, char **argv)
/* This test code based on test code from Jeff Whitaker. See
* https://github.com/Unidata/netcdf-c/issues/2357. This is a
* simplified version. */
int i, varid, ncid;
int varid, ncid;
int dimids[NDIM2];
size_t start[NDIM2] = {0, 0}, count[NDIM2] = {DATALEN2, 1}, dimlen;
int data[DATALEN2] = {42, 42};
@ -422,7 +422,7 @@ main(int argc, char **argv)
SUMMARIZE_ERR;
printf("*** testing dimlen with NC_UNLIMITED reopen and rewrite...");
{
int i, varid, ncid;
int varid, ncid;
int dimid;
size_t start[NDIM1] = {0}, count[NDIM1] = {DATALEN2}, dimlen;
int data[DATALEN2] = {42, 42};

View File

@ -418,7 +418,7 @@ main(int argc, char **argv)
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
#ifdef HAVE_H5Z_SZIP
#ifdef HAVE_SZ
printf("**** testing simple szip filter setup...");
{
int ncid;
@ -757,6 +757,6 @@ main(int argc, char **argv)
if (nc_close(ncid)) ERR;
}
SUMMARIZE_ERR;
#endif /* HAVE_H5Z_SZIP */
#endif /* HAVE_SZ */
FINAL_RESULTS;
}

View File

@ -105,6 +105,7 @@ IF(ENABLE_TESTS)
ADD_EXECUTABLE(nctrunc nctrunc.c)
if(RCMERGE)
ADD_EXECUTABLE(tst_rcmerge tst_rcmerge.c)
ADD_EXECUTABLE(tst_rcmerge tst_rcapi.c)
endif()
TARGET_LINK_LIBRARIES(rewrite-scalar netcdf)
TARGET_LINK_LIBRARIES(bom netcdf)
@ -112,6 +113,7 @@ endif()
TARGET_LINK_LIBRARIES(nctrunc netcdf)
if(RCMERGE)
TARGET_LINK_LIBRARIES(tst_rcmerge netcdf)
TARGET_LINK_LIBRARIES(tst_rcapi netcdf)
endif()
IF(USE_HDF5)
@ -154,6 +156,11 @@ endif()
SET_TARGET_PROPERTIES(tst_rcmerge PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
${CMAKE_CURRENT_BINARY_DIR})
SET_TARGET_PROPERTIES(tst_rcmerge PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY
${CMAKE_CURRENT_BINARY_DIR})
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG
${CMAKE_CURRENT_BINARY_DIR})
SET_TARGET_PROPERTIES(tst_rcapi PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
endif()
IF(USE_HDF5)

View File

@ -79,7 +79,7 @@ man_MANS = ncdump.1 nccopy.1
if BUILD_TESTSETS
# C programs needed by shell scripts for classic tests.
check_PROGRAMS = rewrite-scalar ref_ctest ref_ctest64 ncdump tst_utf8 \
bom tst_dimsizes nctrunc tst_rcmerge
bom tst_dimsizes nctrunc tst_rcmerge tst_rcapi
# Tests for classic and 64-bit offset files.
TESTS = tst_inttags.sh run_tests.sh tst_64bit.sh ref_ctest \
@ -203,7 +203,8 @@ ref_roman_szip_simple.cdl ref_roman_szip_unlim.cdl ref_tst_perdimspecs.cdl \
test_keywords.sh ref_keyword1.cdl ref_keyword2.cdl ref_keyword3.cdl ref_keyword4.cdl \
ref_tst_nofilters.cdl test_scope.sh \
test_rcmerge.sh ref_rcmerge1.txt ref_rcmerge2.txt ref_rcmerge3.txt \
scope_ancestor_only.cdl scope_ancestor_subgroup.cdl scope_group_only.cdl scope_preorder.cdl
scope_ancestor_only.cdl scope_ancestor_subgroup.cdl scope_group_only.cdl scope_preorder.cdl \
ref_rcapi.txt
# The L512.bin file is file containing exactly 512 bytes each of value 0.
# It is used for creating hdf5 files with varying offsets for testing.

7
ncdump/ref_rcapi.txt Normal file
View File

@ -0,0 +1,7 @@
load:
insert: key=key1 value=value1
insert: before: key1 = (null)
insert: after: key1 = value1
replace: key=key1 value=value2
replace: before: key1 = value1
replace: after: key1 = value2

View File

@ -54,7 +54,8 @@ resetrc() {
rm -fr $HOMERCFILES
rm -f $LOCALRCFILES
unset NCRCENV_RC
rm -f tmpoutput.txt
rm -f tmp_rcmerge.txt
rm -f tmp_rcapi.txt
rm -f allfiles1 allfiles2 allfiles3
}
@ -70,36 +71,40 @@ fi
mergecase1() {
# create everything with different keys to test merge
resetrc
rm -f tmp_rcmerge.txt tmpoutput.txt
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
echo "for r=ncrc daprc dodsrc"
for r in "ncrc" "daprc" "dodsrc"; do
echo "${r}_home=${r}" >> $RCHOME/".${r}";
echo "${r}_local=${r}" >> $WD/".${r}"
done;
union 1
${abs_execdir}/tst_rcmerge |sort > tmpoutput.txt
${abs_execdir}/tst_rcmerge |sort > tmp_rcmerge.txt
# echo ">>merge1"; cat ${abs_srcdir}/ref_rcmerge1.txt;
# echo "====="; cat tmpoutput.txt
diff -b ${abs_srcdir}/ref_rcmerge1.txt tmpoutput.txt
# echo "====="; cat tmp_rcmerge.txt
diff -b ${abs_srcdir}/ref_rcmerge1.txt tmp_rcmerge.txt
}
mergecase2() {
# create with some same keys to test override
resetrc
rm -f tmp_rcmerge.txt tmpoutput.txt
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
echo "Create in $RCHOME"
for r in "ncrc" "daprc" "dodsrc" ; do
echo "${r}=${r}" >> $RCHOME/".${r}";
done;
echo "Create in $WD"
for r in "ncrc" "daprc" "dodsrc" ; do
echo "${r}=${r}" >> $WD/".${r}"
done;
union 2
${abs_execdir}/tst_rcmerge |sort > tmpoutput.txt
diff -b ${abs_srcdir}/ref_rcmerge2.txt tmpoutput.txt
${abs_execdir}/tst_rcmerge |sort > tmp_rcmerge.txt
diff -b ${abs_srcdir}/ref_rcmerge2.txt tmp_rcmerge.txt
}
mergecase3() {
# Test cross file overrides
resetrc
rm -f tmp_rcmerge.txt tmpoutput.txt
rm -f tmp_rcmerge.txt tmp_rcmerge.txt
echo "ncrc=ncrc1" >> $HOME/.ncrc
echo "ncrcx=ncrcx" >> $RCHOME/.ncrc
echo "ncrc=ncrc2" >> $RCHOME/.dodsrc
@ -111,8 +116,18 @@ mergecase3() {
echo "daprc=daprc" >> $WD/.dodsrc
echo "ncrcx=ncrcy" >> $WD/.dodsrc
union 3
${abs_execdir}/tst_rcmerge |sort -d > tmpoutput.txt
diff -b ${abs_srcdir}/ref_rcmerge3.txt tmpoutput.txt
${abs_execdir}/tst_rcmerge |sort -d > tmp_rcmerge.txt
diff -b ${abs_srcdir}/ref_rcmerge3.txt tmp_rcmerge.txt
}
rcapi1() {
resetrc
echo "[http://github.com/a/b/c]ncrc=ncrc1" >> $WD/.ncrc
echo "ncrc=ncrc2" >> $WD/.ncrc
echo "[http://github.com:8080/a/b/c]key0=v0" >> $WD/.ncrc
echo "[http://github.com]key0=v1" >> $WD/.ncrc
${abs_execdir}/tst_rcapi > tmp_rcapi.txt
diff -b ${abs_srcdir}/ref_rcapi.txt ./tmp_rcapi.txt
}
resetrc
@ -120,5 +135,10 @@ resetrc
mergecase1
mergecase2
mergecase3
# Test the .rc api
rcapi1
# Test the .rc api
rcapi1
resetrc

94
ncdump/tst_rcapi.c Executable file
View File

@ -0,0 +1,94 @@
/* This is part of the netCDF package.
Copyright 2018 University Corporation for Atmospheric Research/Unidata
See COPYRIGHT file for conditions of use.
Test RC interface
Dennis Heimbigner
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "netcdf.h"
#undef DEBUG
#ifndef nullfree
#define nullfree(x) {if((x)!=NULL) free(x);}
#endif
#if 0
static void
printrc(NCglobalstate* ngs)
{
size_t i,nentries = 0;
NCRCinfo* info = NULL;
NCRCentry* entry = NULL;
info = ngs->rcinfo;
if(info->ignore) {
fprintf(stderr,".rc ignored\n");
return;
}
/* Print out the .rc entries */
if((nentries = NC_rcfile_length(info))==0) {
printf("<empty>\n");
exit(0);
}
for(i=0;i<nentries;i++) {
entry = NC_rcfile_ith(info,i);
if(entry == NULL) abort();
if(entry->host != NULL) {
printf("[%s ",entry->host);
if(entry->urlpath != NULL)
printf("/%s] ",entry->urlpath);
printf("]");
}
printf("|%s|->|%s|\n",entry->key,entry->value);
}
}
#endif
int
main(int argc, char **argv)
{
int stat = NC_NOERR;
const char* key;
const char* value;
char* newvalue;
printf("load:\n");
key = "key1";
value = "value1";
printf("insert: key=%s value=%s\n",key, value);
newvalue = nc_rc_get(key);
printf("insert: before: %s = %s\n",key,newvalue);
nullfree(newvalue);
stat = nc_rc_set(key, value);
if(stat) {fprintf(stderr,"***Fail: nc_rc_set: %s\n",nc_strerror(stat)); goto done;}
newvalue = nc_rc_get(key);
printf("insert: after: %s = %s\n",key,newvalue);
nullfree(newvalue);
key = "key1";
value = "value2";
printf("replace: key=%s value=%s\n",key, value);
newvalue = nc_rc_get(key);
printf("replace: before: %s = %s\n",key,newvalue);
nullfree(newvalue);
stat = nc_rc_set(key, value);
if(stat) {fprintf(stderr,"***Fail: nc_rc_set: %s\n",nc_strerror(stat)); goto done;}
newvalue = nc_rc_get(key);
printf("replace: after: %s = %s\n",key,newvalue);
nullfree(newvalue);
done:
nc_finalize();
return 0;
}

View File

@ -5,23 +5,17 @@
#include "ncrc.h"
#include "nc4internal.h"
int
main(int argc, char** argv)
static void
printrc(NCglobalstate* ngs)
{
size_t i,nentries = 0;
NCglobalstate* ngs = NC_getglobalstate();
NCRCinfo* info = NULL;
NCRCentry* entry = NULL;
/* Cause the .rc files to be read and merged */
nc_initialize();
if((ngs = NC_getglobalstate())==NULL) abort();
info = ngs->rcinfo;
if(info->ignore) {
fprintf(stderr,".rc ignored\n");
exit(0);
return;
}
/* Print out the .rc entries */
@ -34,11 +28,24 @@ main(int argc, char** argv)
if(entry == NULL) abort();
if(entry->host != NULL) {
printf("[%s ",entry->host);
if(entry->path != NULL)
printf("/%s] ",entry->path);
if(entry->urlpath != NULL)
printf("/%s] ",entry->urlpath);
printf("]");
}
printf("|%s|->|%s|\n",entry->key,entry->value);
}
}
int
main(int argc, char** argv)
{
NCglobalstate* ngs = NC_getglobalstate();
/* Cause the .rc files to be read and merged */
nc_initialize();
if((ngs = NC_getglobalstate())==NULL) abort();
printrc(ngs);
return 0;
}