Skip to content

Commit 9f8696b

Browse files
committed
SERVER-31390 Use a templating language to generate error_codes.{h,cpp,js}
1 parent acdd51d commit 9f8696b

8 files changed

+320
-311
lines changed

.eslintignore

+1
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
src/mongo/gotools/*
2+
*.tpl.js

buildscripts/requirements.txt

+2
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ pylint == 1.6.5
1010
pydocstyle == 1.1.1
1111
# resmoke.py
1212
-r resmokelib/requirements.txt
13+
# generate_error_codes.py
14+
cheetah3 == 3.0.0; python_version < "3"

src/mongo/base/SConscript

+23-4
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,29 @@ Import("env")
44

55
env = env.Clone()
66

7-
generateErrorCodes = env.Command(
8-
target=['error_codes.h', 'error_codes.cpp'],
9-
source=['generate_error_codes.py', 'error_codes.err'],
10-
action=['$PYTHON ${SOURCES[0]} cpp ${SOURCES[1]} --cpp-header=${TARGETS[0]} --cpp-source=${TARGETS[1]}'])
7+
8+
# This needs to use its own env to tell scons to suppress scanning the .tpl.h and .tpl.cpp inputs
9+
# for #includes since they aren't directly preprocessed. Scons will still scan the generated files
10+
# to produce the correct implicit dependencies when they are compiled.
11+
env_for_error_codes = env.Clone()
12+
env_for_error_codes['SCANNERS'] = []
13+
generateErrorCodes = env_for_error_codes.Command(
14+
target=[
15+
'error_codes.h',
16+
'error_codes.cpp'
17+
],
18+
source=[
19+
'generate_error_codes.py',
20+
'error_codes.err',
21+
'error_codes.tpl.h',
22+
'error_codes.tpl.cpp',
23+
],
24+
action=['$PYTHON ${SOURCES[0]} ${SOURCES[1]} '
25+
'${SOURCES[2]}=${TARGETS[0]} '
26+
'${SOURCES[3]}=${TARGETS[1]}'
27+
],
28+
)
29+
1130
env.Alias('generated-sources', generateErrorCodes)
1231

1332
env.CppUnitTest('base_test',

src/mongo/base/error_codes.tpl.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/**
2+
* Copyright 2017 MongoDB, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License, version 3,
6+
* as published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU Affero General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU Affero General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*
16+
* As a special exception, the copyright holders give permission to link the
17+
* code of portions of this program with the OpenSSL library under certain
18+
* conditions as described in each individual source file and distribute
19+
* linked combinations including the program with the OpenSSL library. You
20+
* must comply with the GNU Affero General Public License in all respects
21+
* for all of the code used other than as permitted herein. If you modify
22+
* file(s) with this exception, you may extend this exception to your
23+
* version of the file(s), but you are not obligated to do so. If you do not
24+
* wish to do so, delete this exception statement from your version. If you
25+
* delete this exception statement from all source files in the program,
26+
* then also delete it in the license file.
27+
*/
28+
29+
#include "mongo/platform/basic.h"
30+
31+
#include "mongo/base/error_codes.h"
32+
33+
#include "mongo/base/static_assert.h"
34+
#include "mongo/util/assert_util.h"
35+
#include "mongo/util/mongoutils/str.h"
36+
37+
namespace mongo {
38+
39+
MONGO_STATIC_ASSERT(sizeof(ErrorCodes::Error) == sizeof(int));
40+
41+
std::string ErrorCodes::errorString(Error err) {
42+
switch (err) {
43+
//#for $ec in $codes
44+
case $ec.name:
45+
return "$ec.name";
46+
//#end for
47+
default:
48+
return mongoutils::str::stream() << "Location" << int(err);
49+
}
50+
}
51+
52+
ErrorCodes::Error ErrorCodes::fromString(StringData name) {
53+
//#for $ec in $codes
54+
if (name == "$ec.name"_sd)
55+
return $ec.name;
56+
//#end for
57+
return UnknownError;
58+
}
59+
60+
std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code) {
61+
return stream << ErrorCodes::errorString(code);
62+
}
63+
64+
//#for $cat in $categories
65+
bool ErrorCodes::is${cat.name}(Error err) {
66+
switch (err) {
67+
//#for $code in $cat.codes
68+
case $code:
69+
return true;
70+
//#end for
71+
default:
72+
return false;
73+
}
74+
}
75+
//#end for
76+
77+
} // namespace mongo

src/mongo/base/error_codes.tpl.h

+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/**
2+
* Copyright 2017 MongoDB, Inc.
3+
*
4+
* This program is free software: you can redistribute it and/or modify
5+
* it under the terms of the GNU Affero General Public License, version 3,
6+
* as published by the Free Software Foundation.
7+
*
8+
* This program is distributed in the hope that it will be useful,
9+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+
* GNU Affero General Public License for more details.
12+
*
13+
* You should have received a copy of the GNU Affero General Public License
14+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
15+
*
16+
* As a special exception, the copyright holders give permission to link the
17+
* code of portions of this program with the OpenSSL library under certain
18+
* conditions as described in each individual source file and distribute
19+
* linked combinations including the program with the OpenSSL library. You
20+
* must comply with the GNU Affero General Public License in all respects
21+
* for all of the code used other than as permitted herein. If you modify
22+
* file(s) with this exception, you may extend this exception to your
23+
* version of the file(s), but you are not obligated to do so. If you do not
24+
* wish to do so, delete this exception statement from your version. If you
25+
* delete this exception statement from all source files in the program,
26+
* then also delete it in the license file.
27+
*/
28+
29+
#pragma once
30+
31+
#include <cstdint>
32+
#include <iosfwd>
33+
#include <string>
34+
35+
#include "mongo/base/string_data.h"
36+
37+
namespace mongo {
38+
39+
/**
40+
* This is a generated class containing a table of error codes and their corresponding error
41+
* strings. The class is derived from the definitions in src/mongo/base/error_codes.err file and the
42+
* src/mongo/base/error_codes.tpl.h template.
43+
*
44+
* Do not update this file directly. Update src/mongo/base/error_codes.err instead.
45+
*/
46+
class ErrorCodes {
47+
public:
48+
// Explicitly 32-bits wide so that non-symbolic values,
49+
// like uassert codes, are valid.
50+
enum Error : std::int32_t {
51+
//#for $ec in $codes
52+
$ec.name = $ec.code,
53+
//#end for
54+
MaxError
55+
};
56+
57+
static std::string errorString(Error err);
58+
59+
/**
60+
* Parses an Error from its "name". Returns UnknownError if "name" is unrecognized.
61+
*
62+
* NOTE: Also returns UnknownError for the string "UnknownError".
63+
*/
64+
static Error fromString(StringData name);
65+
66+
/**
67+
* Casts an integer "code" to an Error. Unrecognized codes are preserved, meaning
68+
* that the result of a call to fromInt() may not be one of the values in the
69+
* Error enumeration.
70+
*/
71+
static Error fromInt(int code) {
72+
return static_cast<Error>(code);
73+
}
74+
75+
//#for $cat in $categories
76+
static bool is${cat.name}(Error err);
77+
//#end for
78+
};
79+
80+
std::ostream& operator<<(std::ostream& stream, ErrorCodes::Error code);
81+
82+
} // namespace mongo

0 commit comments

Comments
 (0)