@@ -195,18 +195,37 @@ def create_yaml_file():
195195
196196# If user has supplied an argument, treat it as a schema file
197197if bool (data ) and len (sys .argv [1 :]) > 0 :
198- # If pykwalify is installed, then validate the yaml
198+ # If jsonschema is installed, then validate the yaml
199199 try :
200- import pykwalify . core
200+ import jsonschema
201201
202202 def yaml_validate (data , schema ):
203203 if not schema :
204204 return
205- c = pykwalify .core .Core (source_data = data , schema_files = [schema ])
206- c .validate (raise_exception = True )
205+
206+ try :
207+ from yaml import CSafeLoader as SafeLoader
208+ except ImportError :
209+ from yaml import SafeLoader
210+
211+ with open (schema ) as f :
212+ net_schema = yaml .load (f .read (), Loader = SafeLoader )
213+
214+ validator_class = jsonschema .validators .validator_for (net_schema )
215+ validator_class .check_schema (net_schema )
216+ validator = validator_class (net_schema )
217+
218+ errors = sorted (validator .iter_errors (data ), key = lambda e : e .path )
219+ if errors :
220+ # Build a readable message with each error and its path
221+ lines = []
222+ for e in errors :
223+ path = "." .join (map (str , list (e .path ))) or "<root>"
224+ lines .append (f"{ path } : { e .message } " )
225+ raise jsonschema .ValidationError ("\n " .join (lines ))
207226
208227 except ImportError as e :
209- sys .stderr .write ("can't import pykwalify ; won't validate YAML (%s)" , e )
228+ sys .stderr .write ("can't import jsonschema ; won't validate YAML (%s)" , e )
210229
211230 def yaml_validate (data , schema ):
212231 pass
@@ -311,33 +330,52 @@ def walk_dict_schema(level, top_level_name, cdict, key_upper, map, indent):
311330 global changed
312331 for key , value in map .items ():
313332 if key == "type" :
314- if value == "str" :
333+ # Use value instead of items to avoid changing too many places in C code
334+ if key_upper == "items" :
335+ key_upper = "value"
336+
337+ if value == "string" :
315338 output (indent , "const char *" + key_upper + ";" )
316339 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
317- elif value == "bool " :
340+ elif value == "boolean " :
318341 output (indent , "bool " + key_upper + ";" )
319342 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
320- elif value == "int " :
343+ elif value == "integer " :
321344 output (indent , "int " + key_upper + ";" )
322345 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
323- elif value == "seq " :
346+ elif value == "array " :
324347 print (changed , end = "" )
325348 changed = ""
326349 output (indent , "struct " + top_level_name + "_" + key_upper + " {" )
327- elif value == "map " :
350+ elif value == "object " :
328351 print (changed , end = "" )
329352 changed = ""
330353 if key_upper != "value" :
331354 if level == 1 :
332355 output (indent , "struct " + key_upper + " {" )
333356 else :
334357 output (indent , "struct " + top_level_name + "_" + key_upper + " {" )
335- elif value == "any" and key_upper == "bind_to" :
336- output (indent , "int bind_to;" )
337- changed += indent + "bool " + "__bind_to_changed : 1;" + "\n "
338358 continue
339- elif key == "mapping" :
359+
360+ if key == "bind_to" :
361+ output (indent , "int bind_to;" )
362+ changed += indent + "bool " + "__bind_to_changed : 1;" + "\n "
363+ continue
364+
365+ if isinstance (value , dict ):
340366 walk_dict_schema (level + 1 , top_level_name , cdict , key , value , "\t " + indent )
367+ elif isinstance (value , list ):
368+ walk_list_schema (level + 1 , top_level_name , cdict , key , value , "\t " + indent )
369+
370+ if key == "items" :
371+ print (changed , end = "" )
372+ changed = ""
373+ if key_upper in combined_data :
374+ output (indent , "} " + key_upper + "[" + str (combined_data [key_upper ]) + "];" )
375+ else :
376+ output (indent , "} " + key_upper + "[1];" )
377+
378+ elif key == "properties" :
341379 print (changed , end = "" )
342380 changed = ""
343381 if key_upper != "value" :
@@ -347,19 +385,6 @@ def walk_dict_schema(level, top_level_name, cdict, key_upper, map, indent):
347385 output (indent , "};" )
348386 else :
349387 output (indent , "} " + key_upper + ";" )
350- continue
351- elif key == "sequence" :
352- walk_list_schema (level + 1 , top_level_name , cdict , "value" , value , "\t " + indent )
353- print (changed , end = "" )
354- changed = ""
355- if key_upper in combined_data :
356- output (indent , "} " + key_upper + "[" + str (combined_data [key_upper ]) + "];" )
357- else :
358- output (indent , "} " + key_upper + "[1];" )
359- continue
360-
361- if isinstance (value , dict ):
362- walk_dict_schema (level + 1 , top_level_name , cdict , key , value , indent )
363388
364389
365390def walk_list_schema (level , top_level_name , cdict , key , lst , indent ):
@@ -384,6 +409,8 @@ def walk_list_schema(level, top_level_name, cdict, key, lst, indent):
384409# Create C struct definition. Prefix some of the generated C struct fields with
385410# by the name of the struct to make them unambiguous.
386411for key , value in schema .items ():
412+ if key in ('$id' , '$schema' , 'title' , 'description' ):
413+ print ("/* " + key + ": " + str (value ) + " */" )
387414 if isinstance (value , dict ):
388415 walk_dict_schema (0 , list (data .keys ())[0 ], schema_data , key , value , "" )
389416
0 commit comments