2018-12-11 02:23:17 +03:00
#!/usr/bin/env python3
2014-03-25 00:35:50 +04:00
#
# Unix SMB/CIFS implementation.
#
# HRESULT Error definitions
#
# Copyright (C) Noel Power <noel.power@suse.com> 2014
#
# 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 <http://www.gnu.org/licenses/>.
#
import sys , os . path , io , string
2017-01-20 02:11:30 +03:00
from gen_error_common import parseErrorDescriptions , ErrorDef
2014-03-25 00:35:50 +04:00
2017-01-20 02:11:30 +03:00
def generateHeaderFile ( out_file , errors ) :
2014-03-25 00:35:50 +04:00
out_file . write ( " /* \n " )
2017-01-12 03:20:37 +03:00
out_file . write ( " * Descriptions for errors generated from \n " )
2014-03-25 00:35:50 +04:00
out_file . write ( " * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx \n " )
out_file . write ( " */ \n \n " )
2017-01-12 03:20:37 +03:00
out_file . write ( " #ifndef _NTSTATUS_GEN_H \n " )
out_file . write ( " #define _NTSTATUS_GEN_H \n " )
2017-01-20 02:11:30 +03:00
for err in errors :
2017-10-25 18:37:24 +03:00
line = " #define %s NT_STATUS( %#x ) \n " % ( err . err_define , err . err_code )
2014-03-25 00:35:50 +04:00
out_file . write ( line )
2017-01-12 03:20:37 +03:00
out_file . write ( " \n #endif /* _NTSTATUS_GEN_H */ \n " )
2014-03-25 00:35:50 +04:00
2017-01-20 02:11:30 +03:00
def generateSourceFile ( out_file , errors ) :
2014-03-25 00:35:50 +04:00
out_file . write ( " /* \n " )
2017-01-12 03:20:37 +03:00
out_file . write ( " * Names for errors generated from \n " )
2014-03-25 00:35:50 +04:00
out_file . write ( " * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx \n " )
out_file . write ( " */ \n " )
2017-01-12 03:20:37 +03:00
out_file . write ( " static const nt_err_code_struct nt_errs[] = \n " )
out_file . write ( " { \n " )
2017-01-20 02:11:30 +03:00
for err in errors :
2017-01-12 03:20:37 +03:00
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 " )
out_file . write ( " \n /* \n " )
out_file . write ( " * Descriptions for errors generated from \n " )
2014-03-25 00:35:50 +04:00
out_file . write ( " * [MS-ERREF] http://msdn.microsoft.com/en-us/library/cc704588.aspx \n " )
out_file . write ( " */ \n " )
2017-01-12 03:20:37 +03:00
out_file . write ( " static const nt_err_code_struct nt_err_desc[] = \n " )
out_file . write ( " { \n " )
2017-01-20 02:11:30 +03:00
for err in errors :
2017-01-12 03:20:37 +03:00
# Account for the possibility that some errors may not have descriptions
if err . err_string == " " :
continue
out_file . write ( " \t { N_( \" %s \" ), %s }, \n " % ( err . err_string , err . err_define ) )
out_file . write ( " { 0, NT_STATUS(0) } \n " )
out_file . write ( " }; " )
2014-03-25 00:35:50 +04:00
2017-01-20 02:11:30 +03:00
def generatePythonFile ( out_file , errors ) :
2016-09-27 21:31:58 +03:00
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 " )
out_file . write ( " */ \n " )
out_file . write ( " #include <Python.h> \n " )
2017-08-08 12:50:30 +03:00
out_file . write ( " #include \" python/py3compat.h \" \n " )
2016-09-27 21:31:58 +03:00
out_file . write ( " #include \" includes.h \" \n \n " )
out_file . write ( " static inline PyObject *ndr_PyLong_FromUnsignedLongLong(unsigned long long v) \n " ) ;
out_file . write ( " { \n " ) ;
out_file . write ( " \t if (v > LONG_MAX) { \n " ) ;
out_file . write ( " \t \t return PyLong_FromUnsignedLongLong(v); \n " ) ;
out_file . write ( " \t } else { \n " ) ;
out_file . write ( " \t \t return PyInt_FromLong(v); \n " ) ;
out_file . write ( " \t } \n " ) ;
out_file . write ( " } \n \n " ) ;
2017-02-01 01:55:39 +03:00
# This is needed to avoid a missing prototype error from the C
# compiler. There is never a prototype for this function, it is a
# module loaded by python with dlopen() and found with dlsym().
2017-08-08 12:50:30 +03:00
out_file . write ( " static struct PyModuleDef moduledef = { \n " )
out_file . write ( " \t PyModuleDef_HEAD_INIT, \n " )
out_file . write ( " \t .m_name = \" ntstatus \" , \n " )
out_file . write ( " \t .m_doc = \" NTSTATUS error defines \" , \n " )
out_file . write ( " \t .m_size = -1, \n " )
out_file . write ( " }; \n \n " )
out_file . write ( " MODULE_INIT_FUNC(ntstatus) \n " )
2016-09-27 21:31:58 +03:00
out_file . write ( " { \n " )
out_file . write ( " \t PyObject *m; \n \n " )
2017-08-08 12:50:30 +03:00
out_file . write ( " \t m = PyModule_Create(&moduledef); \n " ) ;
2016-09-27 21:31:58 +03:00
out_file . write ( " \t if (m == NULL) \n " ) ;
2017-08-08 12:50:30 +03:00
out_file . write ( " \t \t return NULL; \n \n " ) ;
2017-01-20 02:11:30 +03:00
for err in errors :
2017-01-12 04:39:52 +03:00
line = """ \t PyModule_AddObject(m, \" %s \" ,
\t \tndr_PyLong_FromUnsignedLongLong ( NT_STATUS_V ( % s ) ) ) ; \n """ % (err.err_define, err.err_define)
2016-09-27 21:31:58 +03:00
out_file . write ( line )
2017-08-08 12:50:30 +03:00
out_file . write ( " \n " ) ;
out_file . write ( " \t return m; \n " ) ;
2016-09-27 21:31:58 +03:00
out_file . write ( " } \n " ) ;
2017-01-20 02:11:30 +03:00
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
2017-01-12 03:20:37 +03:00
# Very simple script to generate files nterr_gen.c & ntstatus_gen.h.
# These files contain generated definitions.
# This script takes four inputs:
# [1]: The name of the text file which is the content of an HTML table
# (e.g. the one found at http://msdn.microsoft.com/en-us/library/cc231200.aspx)
# copied and pasted.
# [2]: The name of the output generated header file with NTStatus #defines
# [3]: The name of the output generated source file with C arrays
# [4]: The name of the output generated python file
2014-03-25 00:35:50 +04:00
def main ( ) :
2017-01-12 03:20:37 +03:00
input_file = None ;
if len ( sys . argv ) == 5 :
input_file = sys . argv [ 1 ]
gen_headerfile_name = sys . argv [ 2 ]
gen_sourcefile_name = sys . argv [ 3 ]
gen_pythonfile_name = sys . argv [ 4 ]
2014-03-25 00:35:50 +04:00
else :
2017-08-08 11:56:17 +03:00
print ( " usage: %s winerrorfile headerfile sourcefile pythonfile " % ( sys . argv [ 0 ] ) )
2014-03-25 00:35:50 +04:00
sys . exit ( )
# read in the data
2017-01-12 03:20:37 +03:00
file_contents = open ( input_file , " r " )
2017-01-20 02:11:30 +03:00
errors = parseErrorDescriptions ( file_contents , False , transformErrorName )
2017-01-12 04:39:52 +03:00
2017-08-08 11:56:17 +03:00
print ( " writing new header file: %s " % gen_headerfile_name )
2017-01-12 04:39:52 +03:00
out_file = open ( gen_headerfile_name , " w " )
2017-01-20 02:11:30 +03:00
generateHeaderFile ( out_file , errors )
2014-03-25 00:35:50 +04:00
out_file . close ( )
2017-08-08 11:56:17 +03:00
print ( " writing new source file: %s " % gen_sourcefile_name )
2017-01-12 03:20:37 +03:00
out_file = open ( gen_sourcefile_name , " w " )
2017-01-20 02:11:30 +03:00
generateSourceFile ( out_file , errors )
2014-03-25 00:35:50 +04:00
out_file . close ( )
2017-08-08 11:56:17 +03:00
print ( " writing new python file: %s " % gen_pythonfile_name )
2017-01-12 03:20:37 +03:00
out_file = open ( gen_pythonfile_name , " w " )
2017-01-20 02:11:30 +03:00
generatePythonFile ( out_file , errors )
2016-09-27 21:31:58 +03:00
out_file . close ( )
2014-03-25 00:35:50 +04:00
if __name__ == ' __main__ ' :
main ( )