diff options
author | Mathias Stearn <mathias@10gen.com> | 2017-10-04 16:14:25 -0400 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2017-11-02 14:25:21 -0400 |
commit | 9f8696b5ba4c9310749c5c3f1ee082c5f663b5b0 (patch) | |
tree | 53c3961ef1c4a68970d85dfc835951a00ec04b34 | |
parent | acdd51da0bda6f8bb723dd23096306a3453c8804 (diff) | |
download | mongo-9f8696b5ba4c9310749c5c3f1ee082c5f663b5b0.tar.gz |
SERVER-31390 Use a templating language to generate error_codes.{h,cpp,js}
-rw-r--r-- | .eslintignore | 1 | ||||
-rw-r--r-- | buildscripts/requirements.txt | 2 | ||||
-rw-r--r-- | src/mongo/base/SConscript | 27 | ||||
-rw-r--r-- | src/mongo/base/error_codes.tpl.cpp | 77 | ||||
-rw-r--r-- | src/mongo/base/error_codes.tpl.h | 82 | ||||
-rw-r--r-- | src/mongo/base/generate_error_codes.py | 374 | ||||
-rw-r--r-- | src/mongo/shell/SConscript | 8 | ||||
-rw-r--r-- | src/mongo/shell/error_codes.tpl.js | 60 |
8 files changed, 320 insertions, 311 deletions
diff --git a/.eslintignore b/.eslintignore index a1ded284b11..97755b3f9df 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ src/mongo/gotools/* +*.tpl.js diff --git a/buildscripts/requirements.txt b/buildscripts/requirements.txt index 1aef1166655..83242c053ff 100644 --- a/buildscripts/requirements.txt +++ b/buildscripts/requirements.txt @@ -10,3 +10,5 @@ pylint == 1.6.5 pydocstyle == 1.1.1 # resmoke.py -r resmokelib/requirements.txt +# generate_error_codes.py +cheetah3 == 3.0.0; python_version < "3" diff --git a/src/mongo/base/SConscript b/src/mongo/base/SConscript index db569f842a5..80dc007a4bb 100644 --- a/src/mongo/base/SConscript +++ b/src/mongo/base/SConscript @@ -4,10 +4,29 @@ Import("env") env = env.Clone() -generateErrorCodes = env.Command( - target=['error_codes.h', 'error_codes.cpp'], - source=['generate_error_codes.py', 'error_codes.err'], - action=['$PYTHON ${SOURCES[0]} cpp ${SOURCES[1]} --cpp-header=${TARGETS[0]} --cpp-source=${TARGETS[1]}']) + +# This needs to use its own env to tell scons to suppress scanning the .tpl.h and .tpl.cpp inputs +# for #includes since they aren't directly preprocessed. Scons will still scan the generated files +# to produce the correct implicit dependencies when they are compiled. +env_for_error_codes = env.Clone() +env_for_error_codes['SCANNERS'] = [] +generateErrorCodes = env_for_error_codes.Command( + target=[ + 'error_codes.h', + 'error_codes.cpp' + ], + source=[ + 'generate_error_codes.py', + 'error_codes.err', + 'error_codes.tpl.h', + 'error_codes.tpl.cpp', + ], + action=['$PYTHON ${SOURCES[0]} ${SOURCES[1]} ' + '${SOURCES[2]}=${TARGETS[0]} ' + '${SOURCES[3]}=${TARGETS[1]}' + ], +) + env.Alias('generated-sources', generateErrorCodes) env.CppUnitTest('base_test', diff --git a/src/mongo/base/error_codes.tpl.cpp b/src/mongo/base/error_codes.tpl.cpp new file mode 100644 index 00000000000..c1188c3bd15 --- /dev/null +++ b/src/mongo/base/error_codes.tpl.cpp @@ -0,0 +1,77 @@ +/** + * Copyright 2017 MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#include "mongo/platform/basic.h" + +#include "mongo/base/error_codes.h" + +#include "mongo/base/static_assert.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/mongoutils/str.h" + +namespace mongo { + +MONGO_STATIC_ASSERT(sizeof(ErrorCodes::Error) == sizeof(int)); + +std::string ErrorCodes::errorString(Error err) { + switch (err) { + //#for $ec in $codes + case $ec.name: + return "$ec.name"; + //#end for + default: + return mongoutils::str::stream() << "Location" << int(err); + } +} + +ErrorCodes::Error ErrorCodes::fromString(StringData name) { + //#for $ec in $codes + if (name == "$ec.name"_sd) + return $ec.name; + //#end for + return UnknownError; +} + +std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code) { + return stream << ErrorCodes::errorString(code); +} + +//#for $cat in $categories +bool ErrorCodes::is${cat.name}(Error err) { + switch (err) { + //#for $code in $cat.codes + case $code: + return true; + //#end for + default: + return false; + } +} +//#end for + +} // namespace mongo diff --git a/src/mongo/base/error_codes.tpl.h b/src/mongo/base/error_codes.tpl.h new file mode 100644 index 00000000000..a5ebd55042b --- /dev/null +++ b/src/mongo/base/error_codes.tpl.h @@ -0,0 +1,82 @@ +/** + * Copyright 2017 MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +#pragma once + +#include <cstdint> +#include <iosfwd> +#include <string> + +#include "mongo/base/string_data.h" + +namespace mongo { + +/** + * This is a generated class containing a table of error codes and their corresponding error + * strings. The class is derived from the definitions in src/mongo/base/error_codes.err file and the + * src/mongo/base/error_codes.tpl.h template. + * + * Do not update this file directly. Update src/mongo/base/error_codes.err instead. + */ +class ErrorCodes { +public: + // Explicitly 32-bits wide so that non-symbolic values, + // like uassert codes, are valid. + enum Error : std::int32_t { + //#for $ec in $codes + $ec.name = $ec.code, + //#end for + MaxError + }; + + static std::string errorString(Error err); + + /** + * Parses an Error from its "name". Returns UnknownError if "name" is unrecognized. + * + * NOTE: Also returns UnknownError for the string "UnknownError". + */ + static Error fromString(StringData name); + + /** + * Casts an integer "code" to an Error. Unrecognized codes are preserved, meaning + * that the result of a call to fromInt() may not be one of the values in the + * Error enumeration. + */ + static Error fromInt(int code) { + return static_cast<Error>(code); + } + + //#for $cat in $categories + static bool is${cat.name}(Error err); + //#end for +}; + +std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code); + +} // namespace mongo diff --git a/src/mongo/base/generate_error_codes.py b/src/mongo/base/generate_error_codes.py index b431cff415c..d3da9970692 100644 --- a/src/mongo/base/generate_error_codes.py +++ b/src/mongo/base/generate_error_codes.py @@ -36,29 +36,62 @@ error_code("symbol2", code2) error_class("class1", ["symbol1", "symbol2, ..."]) Usage: - python generate_error_codes.py <cpp|js> <path to error_codes.err> [options] + python generate_error_codes.py <path to error_codes.err> <template>=<output>... """ -usage_msg = "usage: %prog <cpp|js> /path/to/error_codes.err [options]" +usage_msg = "usage: %prog /path/to/error_codes.err <template>=<output>..." -from optparse import OptionParser +from collections import namedtuple +from Cheetah.Template import Template import sys + +def render_template(template_path, **kw): + '''Renders the template file located at template_path, using the variables defined by kw, and + returns the result as a string''' + + template = Template.compile( + file=template_path, + compilerSettings=dict(directiveStartToken="//#",directiveEndToken="//#"), + baseclass=dict, + useCache=False) + return str(template(**kw)) + +ErrorCode = namedtuple('ErrorCode', ['name', 'code']) +def makeErrorCode(name, code): + return ErrorCode(name, code) + +ErrorClass = namedtuple('ErrorClass', ['name', 'codes']) +def makeErrorClass(name, codes): + return ErrorClass(name, codes) + def main(argv): - generator = argv[1] - error_codes, error_classes = parse_error_definitions_from_file(argv[2]) + # Parse and validate argv. + if len(sys.argv) < 2: + usage("Must specify error_codes.err") + if len(sys.argv) < 3: + usage("Must specify at least one template=output pair") + + template_outputs = [] + for arg in sys.argv[2:]: + try: + template, output = arg.split('=', 1) + template_outputs.append((template, output)) + except Exception: + usage("Error parsing template=output pair: " + arg) + + # Parse and validate error_codes.err. + error_codes, error_classes = parse_error_definitions_from_file(argv[1]) check_for_conflicts(error_codes, error_classes) - if (generator == 'cpp'): - if (len(argv) != 5): - usage('Wrong number of arguments') - cpp_gen = cpp_generator(error_codes, error_classes) - cpp_gen.generate() - elif (generator == 'js'): - if (len(argv) != 4): - usage('Wrong number of arguments') - js_gen = js_generator(error_codes, error_classes) - js_gen.generate() - else: - usage('Must specify which generator(s) to use.') + + # Render the templates to the output files. + for template, output in template_outputs: + text = render_template(template, + codes=error_codes, + categories=error_classes, + ) + + with open(output, 'wb') as outfile: + outfile.write(text) def die(message=None): sys.stderr.write(message or "Fatal error\n") @@ -73,9 +106,10 @@ def parse_error_definitions_from_file(errors_filename): errors_code = compile(errors_file.read(), errors_filename, 'exec') error_codes = [] error_classes = [] - eval(errors_code, dict(error_code=lambda *args: error_codes.append(args), - error_class=lambda *args: error_classes.append(args))) - error_codes.sort(key=lambda x: x[1]) + eval(errors_code, + dict(error_code=lambda *args, **kw: error_codes.append(makeErrorCode(*args, **kw)), + error_class=lambda *args: error_classes.append(makeErrorClass(*args)))) + error_codes.sort(key=lambda x: x.code) return error_codes, error_classes def check_for_conflicts(error_codes, error_classes): @@ -88,28 +122,30 @@ def check_for_conflicts(error_codes, error_classes): die() def has_duplicate_error_codes(error_codes): - sorted_by_name = sorted(error_codes, key=lambda x: x[0]) - sorted_by_code = sorted(error_codes, key=lambda x: x[1]) + sorted_by_name = sorted(error_codes, key=lambda x: x.name) + sorted_by_code = sorted(error_codes, key=lambda x: x.code) failed = False - prev_name, prev_code = sorted_by_name[0] - for name, code in sorted_by_name[1:]: - if name == prev_name: - sys.stdout.write('Duplicate name %s with codes %s and %s\n' % (name, code, prev_code)) + prev = sorted_by_name[0] + for curr in sorted_by_name[1:]: + if curr.name == prev.name: + sys.stdout.write('Duplicate name %s with codes %s and %s\n' + % (curr.name, curr.code, prev.code)) failed = True - prev_name, prev_code = name, code + prev = curr - prev_name, prev_code = sorted_by_code[0] - for name, code in sorted_by_code[1:]: - if code == prev_code: - sys.stdout.write('Duplicate code %s with names %s and %s\n' % (code, name, prev_name)) + prev = sorted_by_code[0] + for curr in sorted_by_code[1:]: + if curr.code == prev.code: + sys.stdout.write('Duplicate code %s with names %s and %s\n' + % (curr.code, curr.name, prev.name)) failed = True - prev_name, prev_code = name, code + prev = curr return failed def has_duplicate_error_classes(error_classes): - names = sorted(ec[0] for ec in error_classes) + names = sorted(ec.name for ec in error_classes) failed = False prev_name = names[0] @@ -130,277 +166,5 @@ def has_missing_error_codes(error_codes, error_classes): failed = True return failed -class base_generator(object): - def __init__(self, error_codes, error_classes): - self.error_codes = error_codes - self.error_classes = error_classes - - def parseOptions(self, options, usage_msg): - parser = OptionParser(usage=usage_msg) - for (f,d,n,m,h) in options: - parser.add_option(f,dest=d,nargs=n,metavar=m,help=h) - (options, args) = parser.parse_args() - return options - - -class js_generator(base_generator): - def __init__(self, error_codes, error_classes): - super(js_generator, self).__init__(error_codes, error_classes) - options = [('--js-source','js_source',1,'DEST_JS_SOURCE','specify dest JS source file to save to')] - options = self.parseOptions(options, usage_msg) - if (options.js_source): - self.js_source = options.js_source - else: - usage('Must specify JS source files') - - def generate(self): - self.generate_source() - - def generate_source(self): - string_to_int_cases = ',\n '.join( - '%s: %s' % (ec[0], ec[1]) for ec in self.error_codes) - int_to_string_cases = ',\n '.join( - '%s: \'%s\'' % (ec[1], ec[0]) for ec in self.error_codes) - predicate_definitions = '\n\n'.join( - self.generate_error_class_predicate_definition(*ec) for ec in self.error_classes) - open(self.js_source, 'wb').write(self.source_template % dict( - string_to_int_cases=string_to_int_cases, - int_to_string_cases=int_to_string_cases - )) - - def generate_error_class_predicate_definition(self, class_name, code_names): - cases = '\n '.join('case \'%s\':' % c for c in code_names) - return self.error_class_predicate_template % dict(class_name=class_name, cases=cases) - - source_template = '''// AUTO-GENERATED FILE DO NOT EDIT -// See src/mongo/base/generate_error_codes.py -/* Copyright 2015 MongoDB, Inc. -* -* This program is free software: you can redistribute it and/or modify -* it under the terms of the GNU Affero General Public License, version 3, -* as published by the Free Software Foundation. -* -* 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 Affero General Public License for more details. -* -* You should have received a copy of the GNU Affero General Public License -* along with this program. If not, see <http://www.gnu.org/licenses/>. -* -* As a special exception, the copyright holders give permission to link the -* code of portions of this program with the OpenSSL library under certain -* conditions as described in each individual source file and distribute -* linked combinations including the program with the OpenSSL library. You -* must comply with the GNU Affero General Public License in all respects -* for all of the code used other than as permitted herein. If you modify -* file(s) with this exception, you may extend this exception to your -* version of the file(s), but you are not obligated to do so. If you do not -* wish to do so, delete this exception statement from your version. If you -* delete this exception statement from all source files in the program, -* then also delete it in the license file. -*/ - -var ErrorCodes = { - %(string_to_int_cases)s -}; - -var ErrorCodeStrings = { - %(int_to_string_cases)s -}; -''' - - error_class_predicate_template = '''function is%(class_name)s(err) { - if (typeof err === 'string') { - error = err; - } else if (typeof err === 'number') { - error = ErrorCodeStrings[err]; - } - switch (error) { - %(cases)s - return true; - default: - return false; - } -} -''' - -class cpp_generator(base_generator): - def __init__(self, error_codes, error_classes): - super(cpp_generator, self).__init__(error_codes, error_classes) - options = [('--cpp-header','cpp_header',1,'DEST_CPP_HEADER','specify dest CPP header file to save to'), ('--cpp-source','cpp_source',1,'DEST_CPP_SOURCE','specify dest CPP source file to save to')] - options = self.parseOptions(options, usage_msg) - if (options.cpp_header and options.cpp_source): - self.cpp_header = options.cpp_header - self.cpp_source = options.cpp_source - else: - usage('Must specify CPP header and source files') - - def generate(self): - self.generate_header() - self.generate_source() - - def generate_header(self): - - enum_declarations = ',\n '.join('%s = %s' % ec for ec in self.error_codes) - predicate_declarations = ';\n '.join( - 'static bool is%s(Error err)' % ec[0] for ec in self.error_classes) - - open(self.cpp_header, 'wb').write(self.header_template % dict( - error_code_enum_declarations=enum_declarations, - error_code_class_predicate_declarations=predicate_declarations)) - - def generate_source(self): - symbol_to_string_cases = ';\n '.join( - 'case %s: return "%s"' % (ec[0], ec[0]) for ec in self.error_codes) - string_to_symbol_cases = ';\n '.join( - 'if (name == "%s") return %s' % (ec[0], ec[0]) - for ec in self.error_codes) - int_to_symbol_cases = ';\n '.join( - 'case %s: return %s' % (ec[0], ec[0]) for ec in self.error_codes) - predicate_definitions = '\n '.join( - self.generate_error_class_predicate_definition(*ec) for ec in self.error_classes) - open(self.cpp_source, 'wb').write(self.source_template % dict( - symbol_to_string_cases=symbol_to_string_cases, - string_to_symbol_cases=string_to_symbol_cases, - int_to_symbol_cases=int_to_symbol_cases, - error_code_class_predicate_definitions=predicate_definitions)) - - def generate_error_class_predicate_definition(self, class_name, code_names): - cases = '\n '.join('case %s:' % c for c in code_names) - return self.error_class_predicate_template % dict(class_name=class_name, cases=cases) - - header_template = '''// AUTO-GENERATED FILE DO NOT EDIT -// See src/mongo/base/generate_error_codes.py -/* Copyright 2014 MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ -#pragma once -#include <string> -#include <cstdint> -#include <iosfwd> -#include "mongo/base/string_data.h" -namespace mongo { - /** - * This is a generated class containing a table of error codes and their corresponding error - * strings. The class is derived from the definitions in src/mongo/base/error_codes.err file. - * - * Do not update this file directly. Update src/mongo/base/error_codes.err instead. - */ - class ErrorCodes { - public: - // Explicitly 32-bits wide so that non-symbolic values, - // like uassert codes, are valid. - enum Error : std::int32_t { - %(error_code_enum_declarations)s, - MaxError - }; - static std::string errorString(Error err); - /** - * Parses an Error from its "name". Returns UnknownError if "name" is unrecognized. - * - * NOTE: Also returns UnknownError for the string "UnknownError". - */ - static Error fromString(StringData name); - /** - * Casts an integer "code" to an Error. Unrecognized codes are preserved, meaning - * that the result of a call to fromInt() may not be one of the values in the - * Error enumeration. - */ - static Error fromInt(int code) { - return static_cast<Error>(code); - } - %(error_code_class_predicate_declarations)s; - }; - - std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code); -} // namespace mongo -''' - - source_template = '''// AUTO-GENERATED FILE DO NOT EDIT -// See src/mongo/base/generate_error_codes.py -/* Copyright 2014 MongoDB, Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License, version 3, - * as published by the Free Software Foundation. - * - * 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 Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * As a special exception, the copyright holders give permission to link the - * code of portions of this program with the OpenSSL library under certain - * conditions as described in each individual source file and distribute - * linked combinations including the program with the OpenSSL library. You - * must comply with the GNU Affero General Public License in all respects - * for all of the code used other than as permitted herein. If you modify - * file(s) with this exception, you may extend this exception to your - * version of the file(s), but you are not obligated to do so. If you do not - * wish to do so, delete this exception statement from your version. If you - * delete this exception statement from all source files in the program, - * then also delete it in the license file. - */ -#include "mongo/base/error_codes.h" -#include "mongo/util/mongoutils/str.h" -namespace mongo { - std::string ErrorCodes::errorString(Error err) { - switch (err) { - %(symbol_to_string_cases)s; - default: return mongoutils::str::stream() << "Location" << int(err); - } - } - ErrorCodes::Error ErrorCodes::fromString(StringData name) { - %(string_to_symbol_cases)s; - return UnknownError; - } - std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code) { - return stream << ErrorCodes::errorString(code); - } - %(error_code_class_predicate_definitions)s -namespace { - static_assert(sizeof(ErrorCodes::Error) == sizeof(int), "sizeof(ErrorCodes::Error) == sizeof(int)"); -} // namespace -} // namespace mongo -''' - - error_class_predicate_template = '''bool ErrorCodes::is%(class_name)s(Error err) { - switch (err) { - %(cases)s - return true; - default: - return false; - } - } -''' - - if __name__ == '__main__': main(sys.argv) diff --git a/src/mongo/shell/SConscript b/src/mongo/shell/SConscript index d342f1edc68..090ec5b7cc6 100644 --- a/src/mongo/shell/SConscript +++ b/src/mongo/shell/SConscript @@ -6,8 +6,12 @@ env = env.Clone() generateJSErrorCodes = env.Command( target=['error_codes.js'], - source=['$BUILD_DIR/mongo/base/generate_error_codes.py', '$BUILD_DIR/mongo/base/error_codes.err'], - action=['$PYTHON ${SOURCES[0]} js ${SOURCES[1]} --js-source=${TARGETS[0]}']) + source=[ + '$BUILD_DIR/mongo/base/generate_error_codes.py', + '$BUILD_DIR/mongo/base/error_codes.err', + 'error_codes.tpl.js', + ], + action=['$PYTHON ${SOURCES[0]} ${SOURCES[1]} ${SOURCES[2]}=${TARGETS[0]}']) env.Alias('generated-sources', generateJSErrorCodes) # Files added here need to be added in scripting/engine.cpp and buildscripts/vcxproj.header as well. diff --git a/src/mongo/shell/error_codes.tpl.js b/src/mongo/shell/error_codes.tpl.js new file mode 100644 index 00000000000..120c0626eb2 --- /dev/null +++ b/src/mongo/shell/error_codes.tpl.js @@ -0,0 +1,60 @@ +/** + * Copyright 2017 MongoDB, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * As a special exception, the copyright holders give permission to link the + * code of portions of this program with the OpenSSL library under certain + * conditions as described in each individual source file and distribute + * linked combinations including the program with the OpenSSL library. You + * must comply with the GNU Affero General Public License in all respects + * for all of the code used other than as permitted herein. If you modify + * file(s) with this exception, you may extend this exception to your + * version of the file(s), but you are not obligated to do so. If you do not + * wish to do so, delete this exception statement from your version. If you + * delete this exception statement from all source files in the program, + * then also delete it in the license file. + */ + +var ErrorCodes = { + //#for $ec in $codes + '$ec.name': $ec.code, + //#end for +}; + +var ErrorCodeStrings = { + //#for $ec in $codes + $ec.code: '$ec.name', + //#end for +}; + +//#for $cat in $categories +ErrorCodes.is${cat.name} = function(err) { + 'use strict'; + + var error; + if (typeof err === 'string') { + error = err; + } else if (typeof err === 'number') { + error = ErrorCodeStrings[err]; + } + switch (error) { + //#for $code in $cat.codes + case '$code': + return true; + //#end for + default: + return false; + } +}; +//#end for |