From: Bob Campbell Date: Thu, 19 Jan 2017 23:11:30 +0000 (+1300) Subject: errors: pull out code into common file X-Git-Tag: talloc-2.1.9~178 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=aad57f9f1f476608b86931f865a5874e69f61a0e;p=thirdparty%2Fsamba.git errors: pull out code into common file This is a precursor to generating other types of errors. Signed-off-by: Bob Campbell Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam --- diff --git a/libcli/util/wscript_build b/libcli/util/wscript_build index bc14b0bbf49..00425478e8f 100644 --- a/libcli/util/wscript_build +++ b/libcli/util/wscript_build @@ -13,7 +13,7 @@ bld.SAMBA_LIBRARY('samba-errors', ) bld.SAMBA_GENERATOR('ntstatus_generated', - source='../../source4/scripting/bin/gen_ntstatus.py ntstatus_err_table.txt', + source='../../source4/scripting/bin/gen_ntstatus.py ntstatus_err_table.txt ../../source4/scripting/bin/gen_error_common.py', target='ntstatus_gen.h nterr_gen.c py_ntstatus.c', group='build_source', rule='${PYTHON} ${SRC[0].abspath(env)} ${SRC[1].abspath(env)} ${TGT[0].abspath(env)} ${TGT[1].abspath(env)} ${TGT[2].abspath(env)}' diff --git a/source4/scripting/bin/gen_error_common.py b/source4/scripting/bin/gen_error_common.py new file mode 100644 index 00000000000..a55baeaf788 --- /dev/null +++ b/source4/scripting/bin/gen_error_common.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +# +# Unix SMB/CIFS implementation. +# +# Utility methods for generating error codes from a file. +# +# Copyright (C) Noel Power 2014 +# Copyright (C) Catalyst IT Ltd. 2017 +# +# 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 +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +# error data model +class ErrorDef: + def __init__(self): + self.err_code = None + self.err_define = None + self.err_string = "" + self.linenum = "" + +def escapeString( input ): + output = input.replace('"','\\"') + output = output.replace("\\<","\\\\<") + output = output.replace('\t',"") + return output + +# Parse error descriptions from a file which is the content +# of an HTML table. +# The file must be formatted as: +# [error code hex] +# [error name short] +# [error description] +# Blank lines are allowed and errors do not have to have a +# description. +# Returns a list of ErrorDef objects. +def parseErrorDescriptions( file_contents, isWinError, transformErrorFunction ): + errors = [] + count = 0 + for line in file_contents: + if line == None or line == '\t' or line == "" or line == '\n': + continue + content = line.strip().split(None,1) + # start new error definition ? + if line.startswith("0x"): + newError = ErrorDef() + newError.err_code = int(content[0],0) + # escape the usual suspects + if len(content) > 1: + newError.err_string = escapeString(content[1]) + newError.linenum = count + newError.isWinError = isWinError + errors.append(newError) + else: + if len(errors) == 0: + continue + err = errors[-1] + if err.err_define == None: + err.err_define = transformErrorFunction(content[0]) + else: + if len(content) > 0: + desc = escapeString(line.strip()) + if len(desc): + if err.err_string == "": + err.err_string = desc + else: + err.err_string = err.err_string + " " + desc + count = count + 1 + print "parsed %d lines generated %d error definitions"%(count,len(errors)) + return errors + diff --git a/source4/scripting/bin/gen_ntstatus.py b/source4/scripting/bin/gen_ntstatus.py index a9ba9e8b502..9592ab22bfd 100755 --- a/source4/scripting/bin/gen_ntstatus.py +++ b/source4/scripting/bin/gen_ntstatus.py @@ -22,83 +22,21 @@ # import sys, os.path, io, string +from gen_error_common import parseErrorDescriptions, ErrorDef -# parsed error data -Errors = [] - -# error data model -class ErrorDef: - - def __init__(self): - self.err_code = None - self.err_define = None - self.err_string = "" - self.linenum = "" - -def escapeString( input ): - output = input.replace('"','\\"') - output = output.replace("\\<","\\\\<") - output = output.replace('\t',"") - return output - -def transformErrorName( error_name ): - new_name = error_name - if error_name.startswith("STATUS_"): - error_name = error_name.replace("STATUS_","",1) - elif error_name.startswith("RPC_NT_"): - error_name = error_name.replace("RPC_NT_","RPC_",1) - elif error_name.startswith("EPT_NT_"): - error_name = error_name.replace("EPT_NT_","EPT_",1) - new_name = "NT_STATUS_" + error_name - return new_name - -def parseErrorDescriptions( file_contents, isWinError ): - count = 0 - for line in file_contents: - if line == None or line == '\t' or line == "" or line == '\n': - continue - content = line.strip().split(None,1) - # start new error definition ? - if line.startswith("0x"): - newError = ErrorDef() - newError.err_code = int(content[0],0) - # escape the usual suspects - if len(content) > 1: - newError.err_string = escapeString(content[1]) - newError.linenum = count - newError.isWinError = isWinError - Errors.append(newError) - else: - if len(Errors) == 0: - # It's the license - continue - err = Errors[-1] - if err.err_define == None: - err.err_define = transformErrorName(content[0]) - else: - if len(content) > 0: - desc = escapeString(line.strip()) - if len(desc): - if err.err_string == "": - err.err_string = desc - else: - err.err_string = err.err_string + " " + desc - count = count + 1 - print "parsed %d lines generated %d error definitions"%(count,len(Errors)) - -def generateHeaderFile(out_file): +def generateHeaderFile(out_file, errors): out_file.write("/*\n") out_file.write(" * Descriptions for errors generated from\n") out_file.write(" * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx\n") out_file.write(" */\n\n") out_file.write("#ifndef _NTSTATUS_GEN_H\n") out_file.write("#define _NTSTATUS_GEN_H\n") - for err in Errors: + for err in errors: line = "#define %s NT_STATUS(%s)\n" % (err.err_define, hex(err.err_code)) out_file.write(line) out_file.write("\n#endif /* _NTSTATUS_GEN_H */\n") -def generateSourceFile(out_file): +def generateSourceFile(out_file, errors): out_file.write("/*\n") out_file.write(" * Names for errors generated from\n") out_file.write(" * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx\n") @@ -106,7 +44,7 @@ def generateSourceFile(out_file): out_file.write("static const nt_err_code_struct nt_errs[] = \n") out_file.write("{\n") - for err in Errors: + for err in errors: out_file.write("\t{ \"%s\", %s },\n" % (err.err_define, err.err_define)) out_file.write("{ 0, NT_STATUS(0) }\n") out_file.write("};\n") @@ -118,7 +56,7 @@ def generateSourceFile(out_file): out_file.write("static const nt_err_code_struct nt_err_desc[] = \n") out_file.write("{\n") - for err in Errors: + for err in errors: # Account for the possibility that some errors may not have descriptions if err.err_string == "": continue @@ -126,7 +64,7 @@ def generateSourceFile(out_file): out_file.write("{ 0, NT_STATUS(0) }\n") out_file.write("};") -def generatePythonFile(out_file): +def generatePythonFile(out_file, errors): out_file.write("/*\n") out_file.write(" * New descriptions for existing errors generated from\n") out_file.write(" * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx\n") @@ -151,12 +89,21 @@ def generatePythonFile(out_file): out_file.write("\tm = Py_InitModule3(\"ntstatus\", NULL, \"NTSTATUS error defines\");\n"); out_file.write("\tif (m == NULL)\n"); out_file.write("\t\treturn;\n\n"); - for err in Errors: + for err in errors: line = """\tPyModule_AddObject(m, \"%s\", \t\tndr_PyLong_FromUnsignedLongLong(NT_STATUS_V(%s)));\n""" % (err.err_define, err.err_define) out_file.write(line) out_file.write("}\n"); +def transformErrorName( error_name ): + if error_name.startswith("STATUS_"): + error_name = error_name.replace("STATUS_", "", 1) + elif error_name.startswith("RPC_NT_"): + error_name = error_name.replace("RPC_NT_", "RPC_", 1) + elif error_name.startswith("EPT_NT_"): + error_name = error_name.replace("EPT_NT_", "EPT_", 1) + return "NT_STATUS_" + error_name + # Very simple script to generate files nterr_gen.c & ntstatus_gen.h. # These files contain generated definitions. # This script takes four inputs: @@ -180,19 +127,20 @@ def main (): # read in the data file_contents = open(input_file, "r") - parseErrorDescriptions(file_contents, False) + + errors = parseErrorDescriptions(file_contents, False, transformErrorName) print "writing new header file: %s" % gen_headerfile_name out_file = open(gen_headerfile_name, "w") - generateHeaderFile(out_file) + generateHeaderFile(out_file, errors) out_file.close() print "writing new source file: %s" % gen_sourcefile_name out_file = open(gen_sourcefile_name, "w") - generateSourceFile(out_file) + generateSourceFile(out_file, errors) out_file.close() print "writing new python file: %s" % gen_pythonfile_name out_file = open(gen_pythonfile_name, "w") - generatePythonFile(out_file) + generatePythonFile(out_file, errors) out_file.close() if __name__ == '__main__':