@@ -196,18 +196,37 @@ def create_yaml_file():
196196
197197# If user has supplied an argument, treat it as a schema file
198198if bool (data ) and len (sys .argv [1 :]) > 0 :
199- # If pykwalify is installed, then validate the yaml
199+ # If jsonschema is installed, then validate the yaml
200200 try :
201- import pykwalify . core
201+ import jsonschema
202202
203203 def yaml_validate (data , schema ):
204204 if not schema :
205205 return
206- c = pykwalify .core .Core (source_data = data , schema_files = [schema ])
207- c .validate (raise_exception = True )
206+
207+ try :
208+ from yaml import CSafeLoader as SafeLoader
209+ except ImportError :
210+ from yaml import SafeLoader
211+
212+ with open (schema ) as f :
213+ net_schema = yaml .load (f .read (), Loader = SafeLoader )
214+
215+ validator_class = jsonschema .validators .validator_for (net_schema )
216+ validator_class .check_schema (net_schema )
217+ validator = validator_class (net_schema )
218+
219+ errors = sorted (validator .iter_errors (data ), key = lambda e : e .path )
220+ if errors :
221+ # Build a readable message with each error and its path
222+ lines = []
223+ for e in errors :
224+ path = "." .join (map (str , list (e .path ))) or "<root>"
225+ lines .append (f"{ path } : { e .message } " )
226+ raise jsonschema .ValidationError ("\n " .join (lines ))
208227
209228 except ImportError as e :
210- sys .stderr .write ("can't import pykwalify ; won't validate YAML (%s)" , e )
229+ sys .stderr .write ("can't import jsonschema ; won't validate YAML (%s)" , e )
211230
212231 def yaml_validate (data , schema ):
213232 pass
@@ -267,7 +286,7 @@ def walk_list(lst, indent):
267286 elif isinstance (v , dict ):
268287 walk_dict (v , "\t " + indent )
269288 elif isinstance (v , str ):
270- print (indent + "\t " + "\" " + v + "\" ," )
289+ print (indent + "\t " + ".value = \" " + v + "\" ," )
271290 elif isinstance (v , bool ):
272291 print (indent + "\t " + str (v ).lower () + "," )
273292 elif isinstance (v , int ):
@@ -310,35 +329,67 @@ def output(indent, str):
310329
311330def walk_dict_schema (level , top_level_name , cdict , key_upper , map , indent ):
312331 global changed
332+ str_val = ""
333+
313334 for key , value in map .items ():
314335 if key == "type" :
315- if value == "str" :
316- output (indent , "const char *" + key_upper + ";" )
336+ # Use value instead of items to avoid changing too many places in C code
337+ if key_upper == "items" :
338+ key_upper = "value"
339+
340+ if value == "string" :
341+ str_val = "const char *" + key_upper + ";"
317342 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
318- elif value == "bool " :
343+ elif value == "boolean " :
319344 output (indent , "bool " + key_upper + ";" )
320345 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
321- elif value == "int " :
346+ elif value == "integer " :
322347 output (indent , "int " + key_upper + ";" )
323348 changed += indent + "bool " + "__" + key_upper + "_changed : 1;" + "\n "
324- elif value == "seq " :
349+ elif value == "array " :
325350 print (changed , end = "" )
326351 changed = ""
327352 output (indent , "struct " + top_level_name + "_" + key_upper + " {" )
328- elif value == "map " :
353+ elif value == "object " :
329354 print (changed , end = "" )
330355 changed = ""
331356 if key_upper != "value" :
332357 if level == 1 :
333358 output (indent , "struct " + key_upper + " {" )
334359 else :
335360 output (indent , "struct " + top_level_name + "_" + key_upper + " {" )
336- elif value == "any" and key_upper == "bind_to" :
337- output (indent , "int bind_to;" )
338- changed += indent + "bool " + "__bind_to_changed : 1;" + "\n "
339361 continue
340- elif key == "mapping" :
362+
363+ if key == "bind_to" :
364+ output (indent + "\t " , "int bind_to;" )
365+ changed += indent + "\t " + "bool " + "__bind_to_changed : 1;" + "\n "
366+ continue
367+
368+ if key == "maxLength" :
369+ output (indent , "char " + key_upper + "[" + str (value ) + "];" )
370+ str_val = ""
371+ continue
372+
373+ # Print the string as a pointer if it is set without maxLength
374+ if len (str_val ) > 0 :
375+ output (indent , str_val )
376+ str_val = ""
377+ continue
378+
379+ if isinstance (value , dict ):
341380 walk_dict_schema (level + 1 , top_level_name , cdict , key , value , "\t " + indent )
381+ elif isinstance (value , list ):
382+ walk_list_schema (level + 1 , top_level_name , cdict , key , value , "\t " + indent )
383+
384+ if key == "items" :
385+ print (changed , end = "" )
386+ changed = ""
387+ if key_upper in combined_data :
388+ output (indent , "} " + key_upper + "[" + str (combined_data [key_upper ]) + "];" )
389+ else :
390+ output (indent , "} " + key_upper + "[1];" )
391+
392+ elif key == "properties" :
342393 print (changed , end = "" )
343394 changed = ""
344395 if key_upper != "value" :
@@ -348,19 +399,10 @@ def walk_dict_schema(level, top_level_name, cdict, key_upper, map, indent):
348399 output (indent , "};" )
349400 else :
350401 output (indent , "} " + key_upper + ";" )
351- continue
352- elif key == "sequence" :
353- walk_list_schema (level + 1 , top_level_name , cdict , "value" , value , "\t " + indent )
354- print (changed , end = "" )
355- changed = ""
356- if key_upper in combined_data :
357- output (indent , "} " + key_upper + "[" + str (combined_data [key_upper ]) + "];" )
358- else :
359- output (indent , "} " + key_upper + "[1];" )
360- continue
361402
362- if isinstance (value , dict ):
363- walk_dict_schema (level + 1 , top_level_name , cdict , key , value , indent )
403+ # Print the string as a pointer if it is set without maxLength
404+ if len (str_val ) > 0 :
405+ output (indent , str_val )
364406
365407
366408def walk_list_schema (level , top_level_name , cdict , key , lst , indent ):
@@ -385,6 +427,8 @@ def walk_list_schema(level, top_level_name, cdict, key, lst, indent):
385427# Create C struct definition. Prefix some of the generated C struct fields with
386428# by the name of the struct to make them unambiguous.
387429for key , value in schema .items ():
430+ if key in ('$id' , '$schema' , 'title' , 'description' ):
431+ print ("/* " + key + ": " + str (value ) + " */" )
388432 if isinstance (value , dict ):
389433 walk_dict_schema (0 , list (data .keys ())[0 ], schema_data , key , value , "" )
390434
0 commit comments