mirror of
https://github.com/Unidata/netcdf-c.git
synced 2025-01-18 15:55:12 +08:00
fix Jira NCF-208; but note that this causes test.06 to fail because thredds mishandles grids
This commit is contained in:
parent
0eef2f4c87
commit
0803ba20ba
4
cf
4
cf
@ -7,7 +7,7 @@ if test $# != 0 ; then
|
||||
cmds=$@
|
||||
fi
|
||||
|
||||
#HDF5=1
|
||||
HDF5=1
|
||||
DAP=1
|
||||
#CDMR=1
|
||||
#RPC=1
|
||||
@ -137,7 +137,7 @@ FLAGS="$FLAGS --disable-pnetcdf"
|
||||
#FLAGS="$FLAGS --enable-benchmarks"
|
||||
FLAGS="$FLAGS --enable-extra-tests"
|
||||
FLAGS="$FLAGS --enable-logging"
|
||||
FLAGS="$FLAGS --enable-large-file-tests"
|
||||
#FLAGS="$FLAGS --enable-large-file-tests"
|
||||
#FLAGS="$FLAGS --disable-testsets"
|
||||
#FLAGS="$FLAGS --disable-dap-remote-tests"
|
||||
#FLAGS="$FLAGS --enable-doxygen"
|
||||
|
@ -212,7 +212,7 @@ cpp::
|
||||
|
||||
##################################################
|
||||
# ncd
|
||||
NCDUMPC=../ncdump/dumplib.c ../ncdump/indent.c ../ncdump/ncdump.c ../ncdump/nctime0.c ../ncdump/vardata.c ../ncdump/utils.c
|
||||
NCDUMPC=../ncdump/dumplib.c ../ncdump/indent.c ../ncdump/ncdump.c ../ncdump/nctime0.c ../ncdump/vardata.c ../ncdump/utils.c ../ncdump/nciter.c
|
||||
NCDUMPH=../ncdump/cdl.h ../ncdump/dumplib.h ../ncdump/indent.h ../ncdump/isnan.h ../ncdump/ncdump.h ../ncdump/nctime0.h ../ncdump/vardata.h ../ncdump/utils.h
|
||||
|
||||
NCDUMPOBJ=${NCDUMPC:../ncdump/%.c=%.o}
|
||||
|
@ -467,17 +467,31 @@ mapnodes3r(CDFnode* connode, CDFnode* fullnode, int depth)
|
||||
ASSERT((simplenodematch34(connode,fullnode)));
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
{
|
||||
char* path1 = makecdfpathstring3(fullnode,".");
|
||||
char * path2 = makecdfpathstring3(connode,".");
|
||||
fprintf(stderr,"mapnode: %s->%s\n",path1,path2);
|
||||
nullfree(path1); nullfree(path2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Map node */
|
||||
mapfcn(connode,fullnode);
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<nclistlength(fullnode->subnodes);i++) {
|
||||
CDFnode* n = (CDFnode*)nclistget(fullnode->subnodes,i);
|
||||
fprintf(stderr,"fullnode.subnode[%d]: (%d) %s\n",i,n->nctype,n->ocname);
|
||||
}
|
||||
for(i=0;i<nclistlength(connode->subnodes);i++) {
|
||||
CDFnode* n = (CDFnode*)nclistget(connode->subnodes,i);
|
||||
fprintf(stderr,"connode.subnode[%d]: (%d) %s\n",i,n->nctype,n->ocname);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to match connode subnodes against fullnode subnodes */
|
||||
ASSERT(nclistlength(connode->subnodes) <= nclistlength(fullnode->subnodes));
|
||||
|
||||
|
@ -18,14 +18,16 @@ F="file://$TOP/ncdap_test/testdata3/$T"
|
||||
#F="http://motherlode.ucar.edu:8080/thredds/dodsC/testdods/coads_climatology.nc"
|
||||
#F="http://nomads.ncep.noaa.gov:9090/dods/gfs_hd/gfs_hd20120801/gfs_hd_00z"
|
||||
#F="http://hycom.coaps.fsu.edu/thredds/dodsC/atl_ops"
|
||||
#F="http://testbedapps-dev.sura.org/thredds/dodsC/auto/in.usf.fvcom.ike.ultralite.vardrag.nowave.2d"
|
||||
F="http://motherlode.ucar.edu:8081/dts/test.06"
|
||||
|
||||
CON="OneD.amp,TwoD.amp,ThreeD.amp"
|
||||
|
||||
VAR=f64
|
||||
|
||||
PARMS="[log]"
|
||||
#PARMS="${PARMS}[netcdf3]"
|
||||
#PARMS="${PARMS}[fetch=disk]"
|
||||
PARMS="${PARMS}[cache]"
|
||||
#PARMS="${PARMS}[cache]"
|
||||
#PARMS="${PARMS}[prefetch]"
|
||||
#PARMS="${PARMS}[nocache]"
|
||||
#PARMS="${PARMS}[noprefetch]"
|
||||
|
@ -62,19 +62,20 @@ REMOTETESTSXC="test.03;1;s0,s1"
|
||||
# These shorter tests are always run
|
||||
REMOTEURLS1="$DTS"
|
||||
REMOTETESTSS1="\
|
||||
test.01 test.02 test.04 test.05 test.06 test.07a test.07 \
|
||||
test.01 test.02 test.04 test.05 test.07a test.07 \
|
||||
test.21 \
|
||||
test.50 test.53 test.55 test.56 test.57 \
|
||||
test.66 test.67 test.68 test.69"
|
||||
|
||||
# Server is failing on some tests ; investigate why
|
||||
S1FAIL="test.06a test.22 test.23 test.31"
|
||||
# This fails because of the duplicate name problem and the way thredds dap handles grids"
|
||||
S2FAIL="test.06"
|
||||
|
||||
# These longer tests are optional
|
||||
REMOTEURLL1="$REMOTEURLS1"
|
||||
REMOTETESTSL1="\
|
||||
test.03 \
|
||||
test.06 \
|
||||
b31 b31a D1 Drifters EOSDB \
|
||||
ingrid nestedDAS NestedSeq NestedSeq2 OverideExample \
|
||||
SimpleDrdsExample test.an1 \
|
||||
@ -99,11 +100,13 @@ test.02;1;b[1:2:10] \
|
||||
test.03;1;i32[0:1][1:2][0:2] \
|
||||
test.04;1;types.i32 \
|
||||
test.05;1;types.floats.f32 \
|
||||
test.06;1;ThreeD \
|
||||
test.07;1;person.age \
|
||||
test.07;3;person \
|
||||
test.07;4;types.f32"
|
||||
|
||||
# See S2FAIL above
|
||||
SR1FAIL="test.06;1;ThreeD"
|
||||
|
||||
# Following tests are to check selection handling
|
||||
REMOTEURLC2="http://oceanwatch.pfeg.noaa.gov/opendap/GLOBEC"
|
||||
REMOTETESTSC2="\
|
||||
@ -141,10 +144,9 @@ IGNORE="test.07.2"
|
||||
XFAILTESTS3=""
|
||||
# For now, remove some tests from windows platform.
|
||||
if [ `uname | cut -d "_" -f 1` = "MINGW32" ]; then
|
||||
XFAILTESTS3="$XFAILTESTS3 test.67 test.06.1 test.06"
|
||||
XFAILTESTS3="$XFAILTESTS3 test.67"
|
||||
fi
|
||||
|
||||
|
||||
XFAILTESTS4="$XFAILTESTS3"
|
||||
|
||||
# Server is down at the moment
|
||||
|
11
oc2/dap.y
11
oc2/dap.y
@ -11,6 +11,7 @@
|
||||
%{
|
||||
#include "config.h"
|
||||
#include "dapparselex.h"
|
||||
#include "daptab.h"
|
||||
int dapdebug = 0;
|
||||
%}
|
||||
|
||||
@ -94,7 +95,7 @@ declaration:
|
||||
declarations '}' var_name ';'
|
||||
{if(($$=dap_makegrid(parsestate,$10,$5,$8))==null) {YYABORT;}}
|
||||
| error
|
||||
{daperror(parsestate,"Unrecognized type"); YYABORT;}
|
||||
{dapsemanticerror(parsestate,OC_EBADTYPE,"Unrecognized type"); YYABORT;}
|
||||
;
|
||||
|
||||
|
||||
@ -120,13 +121,13 @@ array_decl:
|
||||
| '[' '=' WORD_WORD ']' {$$=dap_arraydecl(parsestate,null,$3);}
|
||||
| '[' name '=' WORD_WORD ']' {$$=dap_arraydecl(parsestate,$2,$4);}
|
||||
| error
|
||||
{daperror(parsestate,"Illegal dimension declaration"); YYABORT;}
|
||||
{dapsemanticerror(parsestate,OC_EDIMSIZE,"Illegal dimension declaration"); YYABORT;}
|
||||
;
|
||||
|
||||
datasetname:
|
||||
var_name {$$=$1;}
|
||||
| error
|
||||
{daperror(parsestate,"Illegal dataset declaration"); YYABORT;}
|
||||
{dapsemanticerror(parsestate,OC_EDDS,"Illegal dataset declaration"); YYABORT;}
|
||||
;
|
||||
|
||||
var_name: name {$$=$1;};
|
||||
@ -134,7 +135,7 @@ var_name: name {$$=$1;};
|
||||
attributebody:
|
||||
'{' attr_list '}' {dap_attributebody(parsestate,$2);}
|
||||
| error
|
||||
{daperror(parsestate,"Illegal DAS body"); YYABORT;}
|
||||
{dapsemanticerror(parsestate,OC_EDAS,"Illegal DAS body"); YYABORT;}
|
||||
;
|
||||
|
||||
attr_list:
|
||||
@ -164,7 +165,7 @@ attribute:
|
||||
{$$=dap_attribute(parsestate,$2,$3,(Object)SCAN_URL);}
|
||||
| name '{' attr_list '}' {$$=dap_attrset(parsestate,$1,$3);}
|
||||
| error
|
||||
{daperror(parsestate,"Illegal attribute"); YYABORT;}
|
||||
{dapsemanticerror(parsestate,OC_EDAS,"Illegal attribute"); YYABORT;}
|
||||
;
|
||||
|
||||
bytes:
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#include "dapparselex.h"
|
||||
#include "daptab.h"
|
||||
|
||||
#undef URLCVT /* NEVER turn this on */
|
||||
#define DAP2ENCODE
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "dapparselex.h"
|
||||
#include "daptab.h"
|
||||
|
||||
/* Forward */
|
||||
|
||||
@ -41,6 +42,17 @@ Object
|
||||
dap_datasetbody(DAPparsestate* state, Object name, Object decls)
|
||||
{
|
||||
OCnode* root = newocnode((char*)name,OC_Dataset,state);
|
||||
char* dupname = NULL;
|
||||
dupname = scopeduplicates((OClist*)decls);
|
||||
if(dupname != NULL) {
|
||||
/* Sometimes, some servers (i.e. Thredds)
|
||||
return a dds with duplicate field names
|
||||
at the dataset level; simulate an errorbody response
|
||||
*/
|
||||
dap_parse_error(state,"Duplicate dataset field names: %s",name,dupname);
|
||||
state->error = OC_ENAMEINUSE;
|
||||
return (Object)NULL;
|
||||
}
|
||||
root->subnodes = (OClist*)decls;
|
||||
OCASSERT((state->root == NULL));
|
||||
state->root = root;
|
||||
@ -67,7 +79,7 @@ void
|
||||
dap_errorbody(DAPparsestate* state,
|
||||
Object code, Object msg, Object ptype, Object prog)
|
||||
{
|
||||
state->svcerror = 1;
|
||||
state->error = OC_EDAPSVC;
|
||||
state->code = nulldup((char*)code);
|
||||
state->message = nulldup((char*)msg);
|
||||
/* Ignore ptype and prog for now */
|
||||
@ -116,8 +128,10 @@ dap_arraydecl(DAPparsestate* state, Object name, Object size)
|
||||
{
|
||||
long value;
|
||||
OCnode* dim;
|
||||
if(!check_int32(size,&value))
|
||||
if(!check_int32(size,&value)) {
|
||||
dap_parse_error(state,"Dimension not an integer");
|
||||
state->error = OC_EDIMSIZE; /* signal semantic error */
|
||||
}
|
||||
if(name != NULL)
|
||||
dim = newocnode((char*)name,OC_Dimension,state);
|
||||
else
|
||||
@ -140,6 +154,7 @@ dap_attrlist(DAPparsestate* state, Object attrlist, Object attrtuple)
|
||||
dap_parse_error(state,"Duplicate attribute names in same scope: %s",dupname);
|
||||
/* Remove this attribute */
|
||||
oclistpop(alist);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -258,6 +273,7 @@ dap_makestructure(DAPparsestate* state, Object name, Object dimensions, Object f
|
||||
char* dupname;
|
||||
if((dupname=scopeduplicates((OClist*)fields))!= NULL) {
|
||||
dap_parse_error(state,"Duplicate structure field names in same scope: %s.%s",(char*)name,dupname);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
return (Object)NULL;
|
||||
}
|
||||
node = newocnode(name,OC_Structure,state);
|
||||
@ -290,6 +306,7 @@ dap_makegrid(DAPparsestate* state, Object name, Object arraydecl, Object mapdecl
|
||||
char* dupname;
|
||||
if((dupname=scopeduplicates((OClist*)mapdecls)) != NULL) {
|
||||
dap_parse_error(state,"Duplicate grid map names in same scope: %s.%s",(char*)name,dupname);
|
||||
state->error = OC_ENAMEINUSE; /* semantic error */
|
||||
return (Object)NULL;
|
||||
}
|
||||
node = newocnode(name,OC_Grid,state);
|
||||
@ -322,8 +339,15 @@ setroot(OCnode* root, OClist* ocnodes)
|
||||
|
||||
int
|
||||
daperror(DAPparsestate* state, const char* msg)
|
||||
{
|
||||
return dapsemanticerror(state,OC_EINVAL,msg);
|
||||
}
|
||||
|
||||
int
|
||||
dapsemanticerror(DAPparsestate* state, OCerror err, const char* msg)
|
||||
{
|
||||
dap_parse_error(state,msg);
|
||||
state->error = err; /* semantic error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -439,6 +463,7 @@ dap_parse_init(char* buf)
|
||||
MEMCHECK(state,NULL);
|
||||
if(buf==NULL) {
|
||||
dap_parse_error(state,"dap_parse_init: no input buffer");
|
||||
state->error = OC_EINVAL; /* semantic error */
|
||||
dap_parse_cleanup(state);
|
||||
return NULL;
|
||||
}
|
||||
@ -459,8 +484,8 @@ DAPparse(OCstate* conn, OCtree* tree, char* parsestring)
|
||||
dapdebug = 1;
|
||||
parseresult = dapparse(state);
|
||||
if(parseresult == 0) {/* 0 => parse ok */
|
||||
/* Check to see if we ended up parsing an error message */
|
||||
if(state->svcerror) {
|
||||
if(state->error == OC_EDAPSVC) {
|
||||
/* we ended up parsing an error message from server */
|
||||
conn->error.code = nulldup(state->code);
|
||||
conn->error.message = nulldup(state->message);
|
||||
tree->root = NULL;
|
||||
@ -471,8 +496,10 @@ DAPparse(OCstate* conn, OCtree* tree, char* parsestring)
|
||||
ocerr = OC_ENOFILE;
|
||||
else
|
||||
ocerr = OC_EDAPSVC;
|
||||
} else if(state->error != OC_NOERR) {
|
||||
/* Parse failed for semantic reasons */
|
||||
ocerr = state->error;
|
||||
} else {
|
||||
OCASSERT((state->root != NULL));
|
||||
tree->root = state->root;
|
||||
state->root = NULL; /* avoid reclaim */
|
||||
tree->nodes = state->ocnodes;
|
||||
|
@ -6,12 +6,6 @@
|
||||
|
||||
#include "ocinternal.h"
|
||||
#include "ocdebug.h"
|
||||
#ifdef USE_DAP
|
||||
/* To avoid "make distclean" wiping out dap.tab.h */
|
||||
#include "daptab.h"
|
||||
#else
|
||||
#include "daptab.h"
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define strcasecmp stricmp
|
||||
@ -48,8 +42,8 @@ typedef struct DAPparsestate {
|
||||
DAPlexstate* lexstate;
|
||||
OClist* ocnodes;
|
||||
struct OCstate* conn;
|
||||
/* For error returns from the server */
|
||||
int svcerror; /* 1 => we had an error from the server */
|
||||
/* Provide a flag for semantic failures during parse */
|
||||
OCerror error; /* OC_EDAPSVC=> we had a server failure; else we had a semantic error */
|
||||
char* code;
|
||||
char* message;
|
||||
char* progtype;
|
||||
@ -60,7 +54,8 @@ typedef struct DAPparsestate {
|
||||
|
||||
extern int dapdebug; /* global state */
|
||||
|
||||
extern int daperror(DAPparsestate* state, const char* msg);
|
||||
extern int daperror(DAPparsestate*, const char*);
|
||||
extern int dapsemanticerror(DAPparsestate* state, OCerror, const char* msg);
|
||||
extern void dap_parse_error(DAPparsestate*,const char *fmt, ...);
|
||||
/* bison parse entry point */
|
||||
extern int dapparse(DAPparsestate*);
|
||||
|
1343
oc2/daptab.c
1343
oc2/daptab.c
File diff suppressed because it is too large
Load Diff
32
oc2/daptab.h
32
oc2/daptab.h
@ -1,9 +1,8 @@
|
||||
/* A Bison parser, made by GNU Bison 2.4.3. */
|
||||
/* A Bison parser, made by GNU Bison 2.6.4. */
|
||||
|
||||
/* Skeleton interface for Bison's Yacc-like parsers in C
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
|
||||
2009, 2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -31,6 +30,15 @@
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_DAP_DAP_TAB_H_INCLUDED
|
||||
# define YY_DAP_DAP_TAB_H_INCLUDED
|
||||
/* Enabling traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 1
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int dapdebug;
|
||||
#endif
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
@ -67,7 +75,6 @@
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef int YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
@ -76,5 +83,18 @@ typedef int YYSTYPE;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef YYPARSE_PARAM
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int dapparse (void *YYPARSE_PARAM);
|
||||
#else
|
||||
int dapparse ();
|
||||
#endif
|
||||
#else /* ! YYPARSE_PARAM */
|
||||
#if defined __STDC__ || defined __cplusplus
|
||||
int dapparse (DAPparsestate* parsestate);
|
||||
#else
|
||||
int dapparse ();
|
||||
#endif
|
||||
#endif /* ! YYPARSE_PARAM */
|
||||
|
||||
|
||||
#endif /* !YY_DAP_DAP_TAB_H_INCLUDED */
|
||||
|
@ -615,8 +615,8 @@ ocdumpdatapath(OCstate* state, OCdata* data, OCbytes* buffer)
|
||||
if(fisset(next->datamode,OCDT_FIELD)
|
||||
|| fisset(next->datamode,OCDT_ELEMENT)
|
||||
|| fisset(next->datamode,OCDT_RECORD)) {
|
||||
snprintf(tmp,sizeof(tmp),".%lu",(unsigned long)next->index);
|
||||
ocbytescat(buffer,tmp);
|
||||
snprintf(tmp,sizeof(tmp),".%lu",(unsigned long)next->index);
|
||||
ocbytescat(buffer,tmp);
|
||||
}
|
||||
}
|
||||
if(template->octype == OC_Atomic) {
|
||||
|
@ -541,12 +541,10 @@ curllookup(char* suffix, char* url)
|
||||
{
|
||||
char key[2048];
|
||||
char* value = NULL;
|
||||
strncpy(key,HTTPPREFIX,2047);
|
||||
strncat(key,suffix,2047-strlen(HTTPPREFIX));
|
||||
snprintf(key,sizeof(key),"%s%s",HTTPPREFIX,suffix);
|
||||
value = ocdodsrc_lookup(key,url);
|
||||
if(value == NULL) {
|
||||
strcpy(key,HTTPPREFIXDEPRECATED);
|
||||
strncat(key,suffix,2047);
|
||||
snprintf(key,sizeof(key),"%s%s",HTTPPREFIXDEPRECATED,suffix);
|
||||
value = ocdodsrc_lookup(key,url);
|
||||
}
|
||||
return value;
|
||||
|
12
oc2/ocread.c
12
oc2/ocread.c
@ -11,6 +11,10 @@
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#include "ocinternal.h"
|
||||
#include "ocdebug.h"
|
||||
#include "ochttp.h"
|
||||
@ -18,11 +22,6 @@
|
||||
#include "ocrc.h"
|
||||
#include "occurlfunctions.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
|
||||
/*Forward*/
|
||||
static int readpacket(OCstate* state, OCURI*, OCbytes*, OCdxd, long*);
|
||||
static int readfile(const char* path, const char* suffix, OCbytes* packet);
|
||||
@ -213,8 +212,7 @@ readfile(const char* path, const char* suffix, OCbytes* packet)
|
||||
off_t totalread = 0;
|
||||
/* check for leading file:/// */
|
||||
if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/
|
||||
strncpy(filename,path,1023);
|
||||
if(suffix != NULL) strncat(filename,suffix,1023-strlen(path)); /* A char is reserved for terminating '\0' */
|
||||
snprintf(filename,sizeof(filename),"%s%s",path,(suffix == NULL ? "" : suffix));
|
||||
flags = O_RDONLY;
|
||||
#ifdef O_BINARY
|
||||
flags |= O_BINARY;
|
||||
|
@ -347,10 +347,7 @@ ocuriparse(const char* uri0, OCURI** durip)
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
#endif
|
||||
if(durip != NULL) *durip = duri;
|
||||
else {
|
||||
free(duri);
|
||||
}
|
||||
if(durip != NULL) *durip = duri; else free(duri);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
|
10
oc2/ocutil.c
10
oc2/ocutil.c
@ -528,21 +528,21 @@ NULL,
|
||||
const char*
|
||||
ocdtmodestring(OCDT mode,int compact)
|
||||
{
|
||||
|
||||
static char result[1+(NMODES*(MAXMODENAME+1))]; /* hack to avoid malloc */
|
||||
#define MAXMODESTRING (NMODES*(MAXMODENAME+1))
|
||||
static char result[1+MAXMODESTRING]; /* hack to avoid malloc */
|
||||
int i;
|
||||
char* p = result;
|
||||
result[0] = '\0';
|
||||
if(mode == 0) {
|
||||
if(compact) *p++ = '-';
|
||||
else strcat(result,"NONE");
|
||||
else strncat(result,"NONE",strlen("NONE"));
|
||||
} else for(i=0;;i++) {
|
||||
char* ms = modestrings[i];
|
||||
if(ms == NULL) break;
|
||||
if(!compact && i > 0) strcat(result,",");
|
||||
if(!compact && i > 0) strncat(result,",",1);
|
||||
if(fisset(mode,(1<<i))) {
|
||||
if(compact) *p++ = ms[0];
|
||||
else strncat(result,ms,sizeof(result)-1);
|
||||
else strncat(result,ms,strlen(ms));
|
||||
}
|
||||
}
|
||||
/* pad compact list out to NMODES in length (+1 for null terminator) */
|
||||
|
Loading…
Reference in New Issue
Block a user