@@ -7779,7 +7779,7 @@ static FnCallResult ReadDataGeneric(const char *const fname,
77797779 assert (fname != NULL );
77807780 assert (input_path != NULL );
77817781
7782- JsonElement * json = JsonReadDataFile (fname , input_path , requested_mode , size_max );
7782+ JsonElement * json = JsonReadDataFile (fname , input_path , requested_mode , size_max , true );
77837783 if (json == NULL )
77847784 {
77857785 return FnFailure ();
@@ -7788,6 +7788,23 @@ static FnCallResult ReadDataGeneric(const char *const fname,
77887788 return FnReturnContainerNoCopy (json );
77897789}
77907790
7791+ static DataFileType ParseRequestedMode (const char * fname , const char * input_path , const char * const mode_string )
7792+ {
7793+ DataFileType requested_mode = DATAFILETYPE_UNKNOWN ;
7794+ if (StringEqual ("auto" , mode_string ))
7795+ {
7796+ requested_mode = GetDataFileTypeFromSuffix (input_path );
7797+ Log (LOG_LEVEL_VERBOSE ,
7798+ "%s: automatically selected data type %s from filename %s" ,
7799+ fname , DataFileTypeToString (requested_mode ), input_path );
7800+ }
7801+ else
7802+ {
7803+ requested_mode = GetDataFileTypeFromString (mode_string );
7804+ }
7805+ return requested_mode ;
7806+ }
7807+
77917808static FnCallResult FnCallReadData (ARG_UNUSED EvalContext * ctx ,
77927809 ARG_UNUSED const Policy * policy ,
77937810 const FnCall * fp ,
@@ -7802,20 +7819,32 @@ static FnCallResult FnCallReadData(ARG_UNUSED EvalContext *ctx,
78027819
78037820 const char * input_path = RlistScalarValue (args );
78047821 const char * const mode_string = RlistScalarValue (args -> next );
7805- DataFileType requested_mode = DATAFILETYPE_UNKNOWN ;
7806- if (StringEqual ("auto" , mode_string ))
7807- {
7808- requested_mode = GetDataFileTypeFromSuffix (input_path );
7809- Log (LOG_LEVEL_VERBOSE ,
7810- "%s: automatically selected data type %s from filename %s" ,
7811- fp -> name , DataFileTypeToString (requested_mode ), input_path );
7812- }
7813- else
7822+ DataFileType requested_mode = ParseRequestedMode (fp -> name , input_path , mode_string );
7823+
7824+ return ReadDataGeneric (fp -> name , input_path , CF_INFINITY , requested_mode );
7825+ }
7826+
7827+ static FnCallResult FnCallValidFileData (ARG_UNUSED EvalContext * ctx ,
7828+ ARG_UNUSED const Policy * policy ,
7829+ const FnCall * fp ,
7830+ const Rlist * args )
7831+ {
7832+ assert (fp != NULL );
7833+ if (args == NULL )
78147834 {
7815- requested_mode = GetDataFileTypeFromString (mode_string );
7835+ Log (LOG_LEVEL_ERR , "Function '%s' requires at least one argument" , fp -> name );
7836+ return FnFailure ();
78167837 }
78177838
7818- return ReadDataGeneric (fp -> name , input_path , CF_INFINITY , requested_mode );
7839+ const char * input_path = RlistScalarValue (args );
7840+ const char * const mode_string = RlistScalarValue (args -> next );
7841+ DataFileType requested_mode = ParseRequestedMode (fp -> name , input_path , mode_string );
7842+
7843+ JsonElement * json = JsonReadDataFile (fp -> name , input_path , requested_mode , CF_INFINITY , false);
7844+ bool is_valid = (json != NULL );
7845+ JsonDestroy (json );
7846+
7847+ return FnReturnContext (is_valid );
78197848}
78207849
78217850static FnCallResult ReadGenericDataType (const FnCall * fp ,
@@ -10326,7 +10355,7 @@ void ModuleProtocol(EvalContext *ctx, const char *command, const char *line, int
1032610355 Log (LOG_LEVEL_DEBUG , "Module protocol parsing %s file '%s'" ,
1032710356 DataFileTypeToString (requested_mode ), content );
1032810357
10329- JsonElement * json = JsonReadDataFile ("module file protocol" , content , requested_mode , size_max );
10358+ JsonElement * json = JsonReadDataFile ("module file protocol" , content , requested_mode , size_max , true );
1033010359 if (json != NULL )
1033110360 {
1033210361 Buffer * tagbuf = StringSetToBuffer (tags , ',' );
@@ -11906,6 +11935,8 @@ const FnCallType CF_FNCALL_TYPES[] =
1190611935 FNCALL_OPTION_NONE , FNCALL_CATEGORY_IO , SYNTAX_STATUS_NORMAL , DEFAULT_ARGC ),
1190711936 FnCallTypeNew ("readtcp" , CF_DATA_TYPE_STRING , READTCP_ARGS , & FnCallReadTcp , "Connect to tcp port, send string and assign result to variable" ,
1190811937 FNCALL_OPTION_CACHED , FNCALL_CATEGORY_COMM , SYNTAX_STATUS_NORMAL , DEFAULT_ARGC ),
11938+ FnCallTypeNew ("validfiledata" , CF_DATA_TYPE_CONTEXT , READDATA_ARGS , & FnCallValidFileData , "Validate a YAML, JSON, CSV, etc." ,
11939+ FNCALL_OPTION_NONE , FNCALL_CATEGORY_IO , SYNTAX_STATUS_NORMAL , DEFAULT_ARGC ),
1190911940
1191011941 // reg functions for regex
1191111942 FnCallTypeNew ("regarray" , CF_DATA_TYPE_CONTEXT , REGARRAY_ARGS , & FnCallRegList , "True if the regular expression in arg1 matches any item in the list or array or data container arg2" ,
0 commit comments