Skip to content

Commit

Permalink
Handle CDF attribute scope collisions
Browse files Browse the repository at this point in the history
  • Loading branch information
cpiker committed Jun 2, 2024
1 parent 9b04081 commit 54e08d8
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ subprojects/zlib-*
.xmake/
.DS_Store
test/sizeof
temp/*

2 changes: 2 additions & 0 deletions das2/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ extern "C" {
#define DASIDX_FUNC -2
#define DASIDX_UNUSED -3

#define ARYIDX_LAST {-1,-1,-1,-1-1,-1,-1,-1}

/*
#define DASIDX_INIT_UNUSED {-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3}
#define DASIDX_INIT_BEGIN { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
Expand Down
16 changes: 8 additions & 8 deletions das2/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ extern "C" {

/** Definition of the callback function invoked when a stream header is
* encountered in the input.
* @param sd A pointer to the parsed StreamDesc
* @param sd A pointer to the parsed DasStream
* @param pd A pointer to a user data structure, may be NULL.
* @see StreamHandler
*/
typedef DasErrCode (*StreamDescHandler)(StreamDesc* sd, void* ud);
typedef DasErrCode (*DasStreamHandler)(DasStream* sd, void* ud);

/** Definition of the callback function invoked when a packet header is
* encountered in the input.
Expand All @@ -47,7 +47,7 @@ typedef DasErrCode (*StreamDescHandler)(StreamDesc* sd, void* ud);
* @param ud A pointer to a user data structure, may be NULL.
* @see StreamHandler
*/
typedef DasErrCode (*PktDescHandler)(StreamDesc* sd, PktDesc* pd, void* ud);
typedef DasErrCode (*PktDescHandler)(DasStream* sd, PktDesc* pd, void* ud);

/** Definition of the callback function invoked when a packet header is
* going to be deleted. This only occurs if streams re-define packet IDs
Expand All @@ -57,7 +57,7 @@ typedef DasErrCode (*PktDescHandler)(StreamDesc* sd, PktDesc* pd, void* ud);
* @param ud A pointer to a user data structure, may be NULL.
* @see StreamHandler
*/
typedef DasErrCode (*PktRedefHandler)(StreamDesc* sd, PktDesc* pd, void* ud);
typedef DasErrCode (*PktRedefHandler)(DasStream* sd, PktDesc* pd, void* ud);

/** Callback function invoked when a data packet is encountered in the input.
* @param sd A pointer to the parsed Packet Descriptor
Expand All @@ -77,7 +77,7 @@ typedef DasErrCode (*PktDataHandler)(PktDesc* pd, void* ud);
*
* @param
*/
typedef DasErrCode (*DsDescHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud);
typedef DasErrCode (*DsDescHandler)(DasStream* sd, int pi, DasDs* dd, void* ud);

/** Callback function invoked when a new data packets for a dataset are
* encountered on the stream.
Expand All @@ -89,15 +89,15 @@ typedef DasErrCode (*DsDescHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud)
* new data were added
* @param ud A pointer to a user data structure, may be NULL
*/
typedef DasErrCode (*DsDataHandler)(StreamDesc* sd, int pi, DasDs* dd, void* ud);
typedef DasErrCode (*DsDataHandler)(DasStream* sd, int pi, DasDs* dd, void* ud);

/** Callback functions that are invoked on Stream Close
* callback function that is called at the end of the stream
* @param sd A pointer to the parsed Stream Descriptor
* @param ud A pointer to a user data structure, may be NULL.
* @see StreamHandler
*/
typedef DasErrCode (*CloseHandler)(StreamDesc* sd, void* ud);
typedef DasErrCode (*CloseHandler)(DasStream* sd, void* ud);

/** Callback functions that handle exceptions
* @param se A pointer to the parsed Exception
Expand All @@ -123,7 +123,7 @@ typedef struct _streamHandler {
* This is the header with the element \<stream\>\</stream\> in the input
* file.
*/
StreamDescHandler streamDescHandler;
DasStreamHandler streamDescHandler;

/** Sets the function to be called when each \<packet\\> element
* is read in.
Expand Down
1 change: 1 addition & 0 deletions das2/serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ static void _serial_onOpenVar(
strncpy(sIndex, psAttr[i+1], 31);
else if(strcmp(psAttr[i], "units") == 0)
pCtx->varUnits = Units_fromStr(psAttr[i+1]);
/* else if(strcmp(psAttr[i], )) */

/* Temporarily ignore values that are running around in wild */
else
Expand Down
126 changes: 111 additions & 15 deletions utilities/das3_cdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,6 @@
#define PROG "das3_cdf"
#define PERR 63

/* Handle lack of const qualifier on CDFvarNum */
#define CDFvarId(id, str) CDFgetVarNum((id), (char*) (str))

#define NEW_FILE_MODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH

#define DEF_AUTH_FILE ".dasauth"
Expand Down Expand Up @@ -465,7 +462,7 @@ bool _cdfOkayish(CDFstatus iStatus){

ubyte g_propBuf[PROP_XFORM_SZ];

const char* DasProp_cdfName(const DasProp* pProp)
const char* DasProp_cdfVarName(const DasProp* pProp)
{
/* Translate some of the common das property names to CDF names */
const char* sName = DasProp_name(pProp);
Expand All @@ -489,6 +486,40 @@ const char* DasProp_cdfName(const DasProp* pProp)
return sName;
}

const char* DasProp_cdfGlobalName(const DasProp* pProp)
{
/* Make sure some common variable property names are not used in
the global section, since CDF has only one property namespace */
const char* sName = DasProp_name(pProp);

/* Converts some das dataset level properties to CDF global names */
if(strcmp(sName, "summary" ) == 0) return "TEXT";
if(strcmp(sName, "info" ) == 0) return "TEXT";
if(strcmp(sName, "title" ) == 0) return "TITLE";
if(strcmp(sName, "label" ) == 0) return "TITLE";

/* Otherwise, just make sure we don't accidentally step on variable attributes */
if(strcmp(sName, "CATDESC" ) == 0) return "G_CATDESC";
if(strcmp(sName, "FILLVAL" ) == 0) return "G_FILLVAL";
if(strcmp(sName, "FORMAT" ) == 0) return "G_FORMAT";
if(strcmp(sName, "VAR_NOTES" ) == 0) return "G_VAR_NOTES";
if(strcmp(sName, "LABLAXIS" ) == 0) return "G_LABLAXIS";
if(strcmp(sName, "LIMITS_NOMINAL_MIN") == 0) return "G_LIMITS_NOMINAL_MIN";
if(strcmp(sName, "LIMITS_NOMINAL_MAX") == 0) return "G_LIMITS_NOMINAL_MAX";
if(strcmp(sName, "SCALEMIN" ) == 0) return "G_SCALEMIN";
if(strcmp(sName, "SCALEMAX" ) == 0) return "G_SCALEMAX";
if(strcmp(sName, "SCALETYP" ) == 0) return "G_SCALETYP";
if(strcmp(sName, "VAR_NOTES" ) == 0) return "G_VAR_NOTES";
if(strcmp(sName, "FIELDNAM" ) == 0) return "G_FIELDNAM";
if(strcmp(sName, "VALIDMIN" ) == 0) return "G_VALIDMIN";
if(strcmp(sName, "VALIDMAX" ) == 0) return "G_VALIDMAX";
if(strcmp(sName, "LIMITS_WARN_MIN" ) == 0) return "G_LIMITS_WARN_MIN";
if(strcmp(sName, "LIMITS_WARN_M" ) == 0) return "G_LIMITS_WARN_M";

return sName;
}


/* Get the number of entries for a property. Only global properties are
allowed to have multiple entries. Typically only string data are
allowed to have entries. We'll interpret this to be 1 except for long
Expand Down Expand Up @@ -533,6 +564,31 @@ long DasProp_cdfType(const DasProp* pProp)
return 0;
}

/* Make logging output more readable */
const char* cdfTypeStr(long nCdfType){
switch(nCdfType){
case CDF_INT1: return "CDF_INT1";
case CDF_INT2: return "CDF_INT2";
case CDF_INT4: return "CDF_INT4";
case CDF_INT8: return "CDF_INT8";
case CDF_UINT1: return "CDF_UINT1";
case CDF_UINT2: return "CDF_UINT2";
case CDF_UINT4: return "CDF_UINT4";
case CDF_REAL4: return "CDF_REAL4";
case CDF_REAL8: return "CDF_REAL8";
case CDF_EPOCH: return "CDF_EPOCH"; /* Standard style. */
case CDF_EPOCH16: return "CDF_EPOCH16"; /* Extended style. */
/* One more style with leap seconds and J2000 base time. */
case CDF_TIME_TT2000: return "CDF_TIME_TT2000";
case CDF_BYTE: return "CDF_BYTE"; /* same as CDF_INT1 (signed) */
case CDF_FLOAT: return "CDF_FLOAT"; /* same as CDF_REAL4 */
case CDF_DOUBLE: return "CDF_DOUBLE"; /* same as CDF_REAL8 */
case CDF_CHAR: return "CDF_CHAR"; /* a "string" data type */
case CDF_UCHAR: return "CDF_UCHAR"; /* a "string" data type */
default: return "CDF_UNKNOWN";
}
}

long DasProp_cdfEntLen(const DasProp* pProp, long iEntry)
{
/* Non-strings only have one entry */
Expand Down Expand Up @@ -676,7 +732,7 @@ DasErrCode writeGlobalProp(struct context* pCtx, const DasProp* pProp)
long n = DasProp_cdfEntries(pProp);
for(long iEntry = 0; iEntry < n; ++iEntry){

sName = DasProp_cdfName(pProp);
sName = DasProp_cdfGlobalName(pProp);

/* Prop filtering,
1. For global props that start with inst just skip past that part
Expand Down Expand Up @@ -705,7 +761,10 @@ DasErrCode writeGlobalProp(struct context* pCtx, const DasProp* pProp)

/* Get attribute number or make a new (why can't CDFlib use "const",
is it really so hard? */
if((iAttr = CDFgetAttrNum(pCtx->nCdfId, (char*)sName)) <= 0){
if((iAttr = CDFattrId(pCtx->nCdfId, sName)) <= 0){
daslog_info_v(
"Auto global attribute %s (%s)", sName, cdfTypeStr(DasProp_cdfType(pProp))
);
if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId, sName, GLOBAL_SCOPE, &iAttr)))
return PERR;
}
Expand All @@ -729,12 +788,25 @@ DasErrCode writeVarProp(struct context* pCtx, long iVarNum, const DasProp* pProp
{
CDFstatus iStatus; /* Used by CDF_MAD macro */

/* If the attribute doesn't exist, we'll need to create it first */
long iAttr;

const char* sName = DasProp_cdfName(pProp);
const char* sName = DasProp_cdfVarName(pProp);
long iAttr = CDFattrId(pCtx->nCdfId, sName);
long nScope = 0L; /* from cdf.h, this is NO_SCOPE */
if(iAttr >= 0){
if(CDF_MAD(CDFgetAttrScope(pCtx->nCdfId, iAttr, &nScope)))
return PERR;
if(nScope != VARIABLE_SCOPE){
return das_error(PERR,
"CDF Limitiation: attribute name '%s' cannot be used for variables"
" because it's already a global attribute.", sName
);
}
}

if((iAttr = CDFattrId(pCtx->nCdfId, sName)) < 0){
/* If the attribute doesn't exist in var scope, we'll need to create it first */
if((iAttr < 0)){
daslog_info_v(
"Auto variable attribute %s (%s)", sName, cdfTypeStr(DasProp_cdfType(pProp))
);
if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId,sName,VARIABLE_SCOPE,&iAttr)))
return PERR;
}
Expand All @@ -744,13 +816,21 @@ DasErrCode writeVarProp(struct context* pCtx, long iVarNum, const DasProp* pProp
if(DasProp_cdfType(pProp) == CDF_UCHAR)
nElements = strlen(DasProp_value(pProp));

/* Hook in spots for debugging */
long nType = DasProp_cdfType(pProp);
void* pVal = DasProp_cdfValues(pProp);

daslog_debug_v("New attribute entry for varible #%ld, %s (attrid: %ld attrtype %ld)",
iVarNum, sName, iAttr, nType
);

if(CDF_MAD(CDFputAttrzEntry(
pCtx->nCdfId,
iAttr,
iVarNum,
DasProp_cdfType(pProp),
nType,
nElements,
DasProp_cdfValues(pProp)
pVal
)))
return PERR;

Expand All @@ -770,15 +850,20 @@ DasErrCode writeVarStrAttr(
/* If the attribute doesn't exist, we'll need to create it first */
long iAttr;
if((iAttr = CDFattrId(pCtx->nCdfId, sAttrName)) < 0){
daslog_info_v("Auto variable attribute %s (%s)", sAttrName, cdfTypeStr(CDF_UCHAR));
if(CDF_MAD(CDFcreateAttr(pCtx->nCdfId, sAttrName, VARIABLE_SCOPE, &iAttr )))
return PERR;
}

daslog_debug_v("Writing attribute %s (attrid: %ld attrtype:%ld) for variable #%ld",
sAttrName, iAttr, CDF_UCHAR, iVarNum
);

if(CDF_MAD(CDFputAttrzEntry(
pCtx->nCdfId,
iAttr,
iVarNum,
CDF_CHAR,
CDF_UCHAR,
(long) strlen(sValue),
(void*)sValue
)))
Expand Down Expand Up @@ -806,6 +891,10 @@ DasErrCode writeVarAttr(
return PERR;
}

daslog_debug_v("Writing attribute %s (attrid: %ld attrtype:%ld) for variable #%ld",
sAttrName, iAttr, nCdfType, iVarNum
);

if(CDF_MAD(CDFputAttrzEntry(
pCtx->nCdfId,
iAttr,
Expand Down Expand Up @@ -1341,6 +1430,11 @@ long DasVar_cdfNonRecDims(
return nUsed;
}

/** create a unique variable in the cdf output file
*
* @param[out] sNmaeBuf a buffer to reciver the variable name must point to at least
* DAS_MAX_ID_BUFSZ bytes of space
*/
DasErrCode makeCdfVar(
struct context* pCtx, DasDim* pDim, DasVar* pVar, int nDsRank, ptrdiff_t* pDsShape,
char* sNameBuf
Expand Down Expand Up @@ -1378,6 +1472,8 @@ DasErrCode makeCdfVar(
nCharLen = aIntr[0];
}

daslog_info_v("Auto variable %s", sNameBuf);

CDFstatus iStatus = CDFcreatezVar(
pCtx->nCdfId, /* CDF File ID */
sNameBuf, /* Varible's name */
Expand Down Expand Up @@ -1537,7 +1633,7 @@ DasErrCode makeCompLabels(struct context* pCtx, DasDim* pDim, DasVar* pVar)
if(CDF_MAD(CDFcreatezVar(
pCtx->nCdfId, /* CDF File ID */
sLblVarName, /* label varible's name */
CDF_CHAR, /* CDF type of variable data */
CDF_UCHAR, /* CDF type of variable data */
nMaxCompLen, /* Character length */
1, /* We have 1 non-record dim */
&nNumComp, /* Number of components in first non-record dim */
Expand Down

0 comments on commit 54e08d8

Please sign in to comment.