bpo-40179: Fix translation of #elif in Argument Clinic (GH-19364)
Co-authored-by: Ammar Askar <ammar@ammaraskar.com>
diff --git a/Lib/test/clinic.test b/Lib/test/clinic.test
index 6ee9dc5..cb76c37 100644
--- a/Lib/test/clinic.test
+++ b/Lib/test/clinic.test
@@ -3260,3 +3260,108 @@
static PyObject *
test_keyword_only_parameter_impl(PyObject *module, PyBytesObject *co_lnotab)
/*[clinic end generated code: output=f25914b402039493 input=303df5046c7e37a3]*/
+
+
+/*[clinic input]
+output push
+output preset buffer
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5bff3376ee0df0b5]*/
+
+#ifdef CONDITION_A
+/*[clinic input]
+test_preprocessor_guarded_condition_a
+[clinic start generated code]*/
+
+static PyObject *
+test_preprocessor_guarded_condition_a_impl(PyObject *module)
+/*[clinic end generated code: output=ad012af18085add6 input=8edb8706a98cda7e]*/
+#elif CONDITION_B
+/*[clinic input]
+test_preprocessor_guarded_elif_condition_b
+[clinic start generated code]*/
+
+static PyObject *
+test_preprocessor_guarded_elif_condition_b_impl(PyObject *module)
+/*[clinic end generated code: output=615f2dee82b138d1 input=53777cebbf7fee32]*/
+#else
+/*[clinic input]
+test_preprocessor_guarded_else
+[clinic start generated code]*/
+
+static PyObject *
+test_preprocessor_guarded_else_impl(PyObject *module)
+/*[clinic end generated code: output=13af7670aac51b12 input=6657ab31d74c29fc]*/
+#endif
+
+/*[clinic input]
+dump buffer
+output pop
+[clinic start generated code]*/
+
+#if defined(CONDITION_A)
+
+PyDoc_STRVAR(test_preprocessor_guarded_condition_a__doc__,
+"test_preprocessor_guarded_condition_a($module, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF \
+ {"test_preprocessor_guarded_condition_a", (PyCFunction)test_preprocessor_guarded_condition_a, METH_NOARGS, test_preprocessor_guarded_condition_a__doc__},
+
+static PyObject *
+test_preprocessor_guarded_condition_a(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return test_preprocessor_guarded_condition_a_impl(module);
+}
+
+#endif /* defined(CONDITION_A) */
+
+#if !defined(CONDITION_A) && (CONDITION_B)
+
+PyDoc_STRVAR(test_preprocessor_guarded_elif_condition_b__doc__,
+"test_preprocessor_guarded_elif_condition_b($module, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF \
+ {"test_preprocessor_guarded_elif_condition_b", (PyCFunction)test_preprocessor_guarded_elif_condition_b, METH_NOARGS, test_preprocessor_guarded_elif_condition_b__doc__},
+
+static PyObject *
+test_preprocessor_guarded_elif_condition_b(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return test_preprocessor_guarded_elif_condition_b_impl(module);
+}
+
+#endif /* !defined(CONDITION_A) && (CONDITION_B) */
+
+#if !defined(CONDITION_A) && !(CONDITION_B)
+
+PyDoc_STRVAR(test_preprocessor_guarded_else__doc__,
+"test_preprocessor_guarded_else($module, /)\n"
+"--\n"
+"\n");
+
+#define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF \
+ {"test_preprocessor_guarded_else", (PyCFunction)test_preprocessor_guarded_else, METH_NOARGS, test_preprocessor_guarded_else__doc__},
+
+static PyObject *
+test_preprocessor_guarded_else(PyObject *module, PyObject *Py_UNUSED(ignored))
+{
+ return test_preprocessor_guarded_else_impl(module);
+}
+
+#endif /* !defined(CONDITION_A) && !(CONDITION_B) */
+
+#ifndef TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF
+ #define TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF
+#endif /* !defined(TEST_PREPROCESSOR_GUARDED_CONDITION_A_METHODDEF) */
+
+#ifndef TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF
+ #define TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF
+#endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELIF_CONDITION_B_METHODDEF) */
+
+#ifndef TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF
+ #define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF
+#endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF) */
+/*[clinic end generated code: output=3804bb18d454038c input=3fc80c9989d2f2e1]*/
diff --git a/Misc/NEWS.d/next/Tools-Demos/2020-04-04-19-35-22.bpo-40179.u9FH10.rst b/Misc/NEWS.d/next/Tools-Demos/2020-04-04-19-35-22.bpo-40179.u9FH10.rst
new file mode 100644
index 0000000..61bd2e3
--- /dev/null
+++ b/Misc/NEWS.d/next/Tools-Demos/2020-04-04-19-35-22.bpo-40179.u9FH10.rst
@@ -0,0 +1 @@
+Fixed translation of ``#elif`` in Argument Clinic.
diff --git a/Modules/clinic/posixmodule.c.h b/Modules/clinic/posixmodule.c.h
index 8ff06fe..9465be9 100644
--- a/Modules/clinic/posixmodule.c.h
+++ b/Modules/clinic/posixmodule.c.h
@@ -3900,7 +3900,7 @@
#endif /* defined(HAVE_WAITPID) */
-#if defined(HAVE_CWAIT)
+#if !defined(HAVE_WAITPID) && defined(HAVE_CWAIT)
PyDoc_STRVAR(os_waitpid__doc__,
"waitpid($module, pid, options, /)\n"
@@ -3936,7 +3936,7 @@
return return_value;
}
-#endif /* defined(HAVE_CWAIT) */
+#endif /* !defined(HAVE_WAITPID) && defined(HAVE_CWAIT) */
#if defined(HAVE_WAIT)
@@ -8869,4 +8869,4 @@
#ifndef OS_WAITSTATUS_TO_EXITCODE_METHODDEF
#define OS_WAITSTATUS_TO_EXITCODE_METHODDEF
#endif /* !defined(OS_WAITSTATUS_TO_EXITCODE_METHODDEF) */
-/*[clinic end generated code: output=4e28994a729eddf9 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=ca63e471c11dc6e7 input=a9049054013a1b77]*/
diff --git a/Tools/clinic/cpp.py b/Tools/clinic/cpp.py
index e099590..77f5f96 100644
--- a/Tools/clinic/cpp.py
+++ b/Tools/clinic/cpp.py
@@ -141,23 +141,15 @@
token = fields[0].lower()
condition = ' '.join(fields[1:]).strip()
- if_tokens = {'if', 'ifdef', 'ifndef'}
- all_tokens = if_tokens | {'elif', 'else', 'endif'}
-
- if token not in all_tokens:
- return
-
- # cheat a little here, to reuse the implementation of if
- if token == 'elif':
- pop_stack()
- token = 'if'
-
- if token in if_tokens:
+ if token in {'if', 'ifdef', 'ifndef', 'elif'}:
if not condition:
self.fail("Invalid format for #" + token + " line: no argument!")
- if token == 'if':
+ if token in {'if', 'elif'}:
if not self.is_a_simple_defined(condition):
condition = "(" + condition + ")"
+ if token == 'elif':
+ previous_token, previous_condition = pop_stack()
+ self.stack.append((previous_token, negate(previous_condition)))
else:
fields = condition.split()
if len(fields) != 1:
@@ -166,18 +158,21 @@
condition = 'defined(' + symbol + ')'
if token == 'ifndef':
condition = '!' + condition
+ token = 'if'
- self.stack.append(("if", condition))
- if self.verbose:
- print(self.status())
+ self.stack.append((token, condition))
+
+ elif token == 'else':
+ previous_token, previous_condition = pop_stack()
+ self.stack.append((previous_token, negate(previous_condition)))
+
+ elif token == 'endif':
+ while pop_stack()[0] != 'if':
+ pass
+
+ else:
return
- previous_token, previous_condition = pop_stack()
-
- if token == 'else':
- self.stack.append(('else', negate(previous_condition)))
- elif token == 'endif':
- pass
if self.verbose:
print(self.status())