1From 23d7ab77865f8b17042f5cd4c6720cca475e0eb5 Mon Sep 17 00:00:00 2001
2From: Khem Raj <raj.khem@gmail.com>
3Date: Wed, 13 Jan 2016 14:27:10 -0800
4Subject: [PATCH] Remove nested functions
5
6nested functions are not supported on llvm/clang compiler, replacing
7them helps make code portable and be compilable with non-gcc compilers
8additionally fix the diagnostic messages clang reported
9
10source/c_gpio.c:130:18: warning: comparison of distinct pointer types
11('volatile uint32_t *' (aka 'volatile unsigned int *') an
12d 'void *') [-Wcompare-distinct-pointer-types]
13    if (gpio_map < MAP_FAILED)
14        ~~~~~~~~ ^ ~~~~~~~~~~
15
16        source/c_gpio.c:89:13: warning: variable 'peri_base' is used
17uninitialized whenever 'if' condition is false [-Wsometimes-uninit
18ialized]
19        if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
20            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21source/c_gpio.c:116:17: note: uninitialized use occurs here
22    gpio_base = peri_base + GPIO_BASE_OFFSET;
23                ^~~~~~~~~
24source/c_gpio.c:89:9: note: remove the 'if' if its condition is always
25true
26        if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
27        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
28source/c_gpio.c:64:23: note: initialize the variable 'peri_base' to
29silence this warning
30    uint32_t peri_base;
31
32Signed-off-by: Khem Raj <raj.khem@gmail.com>
33[Pierre-Jean: update for version 0.7.0]
34Signed-off-by: Pierre-Jean Texier <pjtexier@koncepto.io>
35---
36Upstream-Status: Submitted
37
38 source/c_gpio.c  |   6 +--
39 source/py_gpio.c | 135 ++++++++++++++++++++++++++++---------------------------
40 2 files changed, 71 insertions(+), 70 deletions(-)
41
42diff --git a/source/py_gpio.c b/source/py_gpio.c
43index d54cc7f..007bad5 100644
44--- a/source/py_gpio.c
45+++ b/source/py_gpio.c
46@@ -69,6 +69,20 @@ static int mmap_gpio_mem(void)
47       return 0;
48    }
49 }
50+static inline int cleanup_one(unsigned int gpio)
51+{
52+   // clean up any /sys/class exports
53+   event_cleanup(gpio);
54+
55+   // set everything back to input
56+   if (gpio_direction[gpio] != -1) {
57+      setup_gpio(gpio, INPUT, PUD_OFF);
58+      gpio_direction[gpio] = -1;
59+      return 1;
60+   }
61+   return 0;
62+}
63+
64
65 // python function cleanup(channel=None)
66 static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
67@@ -83,19 +97,6 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
68    PyObject *tempobj;
69    static char *kwlist[] = {"channel", NULL};
70
71-   void cleanup_one(void)
72-   {
73-      // clean up any /sys/class exports
74-      event_cleanup(gpio);
75-
76-      // set everything back to input
77-      if (gpio_direction[gpio] != -1) {
78-         setup_gpio(gpio, INPUT, PUD_OFF);
79-         gpio_direction[gpio] = -1;
80-         found = 1;
81-      }
82-   }
83-
84    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &chanlist))
85       return NULL;
86
87@@ -140,7 +141,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
88       } else if (channel != -666) {    // channel was an int indicating single channel
89          if (get_gpio_number(channel, &gpio))
90             return NULL;
91-         cleanup_one();
92+         found = cleanup_one(gpio);
93       } else {  // channel was a list/tuple
94          for (i=0; i<chancount; i++) {
95             if (chanlist) {
96@@ -169,7 +170,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
97
98             if (get_gpio_number(channel, &gpio))
99                return NULL;
100-            cleanup_one();
101+            found = cleanup_one(gpio);
102          }
103       }
104    }
105@@ -182,6 +183,37 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
106    Py_RETURN_NONE;
107 }
108
109+static inline int setup_one(unsigned int *gpio, int channel, int pud, int direction, int initial) {
110+   if (get_gpio_number(channel, gpio))
111+      return 0;
112+
113+   int func = gpio_function(*gpio);
114+   if (gpio_warnings &&                             // warnings enabled and
115+       ((func != 0 && func != 1) ||                 // (already one of the alt functions or
116+       (gpio_direction[*gpio] == -1 && func == 1)))  // already an output not set from this program)
117+   {
118+      PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.", 1);
119+   }
120+
121+   // warn about pull/up down on i2c channels
122+   if (gpio_warnings) {
123+      if (rpiinfo.p1_revision == 0) { // compute module - do nothing
124+      } else if ((rpiinfo.p1_revision == 1 && (*gpio == 0 || *gpio == 1)) ||
125+                 (*gpio == 2 || *gpio == 3)) {
126+         if (pud == PUD_UP || pud == PUD_DOWN)
127+            PyErr_WarnEx(NULL, "A physical pull up resistor is fitted on this channel!", 1);
128+      }
129+   }
130+
131+   if (direction == OUTPUT && (initial == LOW || initial == HIGH)) {
132+      output_gpio(*gpio, initial);
133+   }
134+   setup_gpio(*gpio, direction, pud);
135+   gpio_direction[*gpio] = direction;
136+   return 1;
137+}
138+
139+
140 // python function setup(channel(s), direction, pull_up_down=PUD_OFF, initial=None)
141 static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
142 {
143@@ -195,37 +227,6 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
144    int pud = PUD_OFF + PY_PUD_CONST_OFFSET;
145    int initial = -1;
146    static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
147-   int func;
148-
149-   int setup_one(void) {
150-      if (get_gpio_number(channel, &gpio))
151-         return 0;
152-
153-      func = gpio_function(gpio);
154-      if (gpio_warnings &&                             // warnings enabled and
155-          ((func != 0 && func != 1) ||                 // (already one of the alt functions or
156-          (gpio_direction[gpio] == -1 && func == 1)))  // already an output not set from this program)
157-      {
158-         PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.", 1);
159-      }
160-
161-      // warn about pull/up down on i2c channels
162-      if (gpio_warnings) {
163-         if (rpiinfo.p1_revision == 0) { // compute module - do nothing
164-         } else if ((rpiinfo.p1_revision == 1 && (gpio == 0 || gpio == 1)) ||
165-                    (gpio == 2 || gpio == 3)) {
166-            if (pud == PUD_UP || pud == PUD_DOWN)
167-               PyErr_WarnEx(NULL, "A physical pull up resistor is fitted on this channel!", 1);
168-         }
169-      }
170-
171-      if (direction == OUTPUT && (initial == LOW || initial == HIGH)) {
172-         output_gpio(gpio, initial);
173-      }
174-      setup_gpio(gpio, direction, pud);
175-      gpio_direction[gpio] = direction;
176-      return 1;
177-   }
178
179    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii", kwlist, &chanlist, &direction, &pud, &initial))
180       return NULL;
181@@ -290,7 +291,7 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
182    } else if (chantuple) {
183        chancount = PyTuple_Size(chantuple);
184    } else {
185-       if (!setup_one())
186+       if (!setup_one(&gpio, channel, pud, direction, initial))
187           return NULL;
188        Py_RETURN_NONE;
189    }
190@@ -320,12 +321,29 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
191           return NULL;
192       }
193
194-      if (!setup_one())
195+      if (!setup_one(&gpio, channel, pud, direction, initial))
196          return NULL;
197    }
198
199    Py_RETURN_NONE;
200 }
201+static inline int output_val(unsigned int *gpio, int channel, int value) {
202+   if (get_gpio_number(channel, gpio))
203+       return 0;
204+
205+   if (gpio_direction[*gpio] != OUTPUT)
206+   {
207+      PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT");
208+      return 0;
209+   }
210+
211+   if (check_gpio_priv())
212+      return 0;
213+
214+   output_gpio(*gpio, value);
215+   return 1;
216+}
217+
218
219 // python function output(channel(s), value(s))
220 static PyObject *py_output_gpio(PyObject *self, PyObject *args)
221@@ -342,23 +360,6 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
222    int chancount = -1;
223    int valuecount = -1;
224
225-   int output(void) {
226-      if (get_gpio_number(channel, &gpio))
227-          return 0;
228-
229-      if (gpio_direction[gpio] != OUTPUT)
230-      {
231-         PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT");
232-         return 0;
233-      }
234-
235-      if (check_gpio_priv())
236-         return 0;
237-
238-      output_gpio(gpio, value);
239-      return 1;
240-   }
241-
242    if (!PyArg_ParseTuple(args, "OO", &chanlist, &valuelist))
243        return NULL;
244
245@@ -416,7 +417,7 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
246    }
247
248    if (chancount == -1) {
249-      if (!output())
250+      if (!output_val(&gpio, channel, value))
251          return NULL;
252       Py_RETURN_NONE;
253    }
254@@ -472,7 +473,7 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
255               return NULL;
256           }
257       }
258-      if (!output())
259+      if (!output_val(&gpio, channel, value))
260          return NULL;
261    }
262
263--
2642.7.0
265
266