From 23d7ab77865f8b17042f5cd4c6720cca475e0eb5 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 13 Jan 2016 14:27:10 -0800
Subject: [PATCH] Remove nested functions

nested functions are not supported on llvm/clang compiler, replacing
them helps make code portable and be compilable with non-gcc compilers
additionally fix the diagnostic messages clang reported

source/c_gpio.c:130:18: warning: comparison of distinct pointer types
('volatile uint32_t *' (aka 'volatile unsigned int *') an
d 'void *') [-Wcompare-distinct-pointer-types]
    if (gpio_map < MAP_FAILED)
        ~~~~~~~~ ^ ~~~~~~~~~~

        source/c_gpio.c:89:13: warning: variable 'peri_base' is used
uninitialized whenever 'if' condition is false [-Wsometimes-uninit
ialized]
        if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
source/c_gpio.c:116:17: note: uninitialized use occurs here
    gpio_base = peri_base + GPIO_BASE_OFFSET;
                ^~~~~~~~~
source/c_gpio.c:89:9: note: remove the 'if' if its condition is always
true
        if (fread(buf, 1, sizeof buf, fp) == sizeof buf) {
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
source/c_gpio.c:64:23: note: initialize the variable 'peri_base' to
silence this warning
    uint32_t peri_base;

Signed-off-by: Khem Raj <raj.khem@gmail.com>
[Pierre-Jean: update for version 0.7.0]
Signed-off-by: Pierre-Jean Texier <pjtexier@koncepto.io>
---
Upstream-Status: Submitted

 source/c_gpio.c  |   6 +--
 source/py_gpio.c | 135 ++++++++++++++++++++++++++++---------------------------
 2 files changed, 71 insertions(+), 70 deletions(-)

diff --git a/source/py_gpio.c b/source/py_gpio.c
index d54cc7f..007bad5 100644
--- a/source/py_gpio.c
+++ b/source/py_gpio.c
@@ -69,6 +69,20 @@ static int mmap_gpio_mem(void)
       return 0;
    }
 }
+static inline int cleanup_one(unsigned int gpio)
+{
+   // clean up any /sys/class exports
+   event_cleanup(gpio);
+
+   // set everything back to input
+   if (gpio_direction[gpio] != -1) {
+      setup_gpio(gpio, INPUT, PUD_OFF);
+      gpio_direction[gpio] = -1;
+      return 1;
+   }
+   return 0;
+}
+
 
 // python function cleanup(channel=None)
 static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
@@ -83,19 +97,6 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
    PyObject *tempobj;
    static char *kwlist[] = {"channel", NULL};
 
-   void cleanup_one(void)
-   {
-      // clean up any /sys/class exports
-      event_cleanup(gpio);
-
-      // set everything back to input
-      if (gpio_direction[gpio] != -1) {
-         setup_gpio(gpio, INPUT, PUD_OFF);
-         gpio_direction[gpio] = -1;
-         found = 1;
-      }
-   }
-
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", kwlist, &chanlist))
       return NULL;
 
@@ -140,7 +141,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
       } else if (channel != -666) {    // channel was an int indicating single channel
          if (get_gpio_number(channel, &gpio))
             return NULL;
-         cleanup_one();
+         found = cleanup_one(gpio);
       } else {  // channel was a list/tuple
          for (i=0; i<chancount; i++) {
             if (chanlist) {
@@ -169,7 +170,7 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
 
             if (get_gpio_number(channel, &gpio))
                return NULL;
-            cleanup_one();
+            found = cleanup_one(gpio);
          }
       }
    }
@@ -182,6 +183,37 @@ static PyObject *py_cleanup(PyObject *self, PyObject *args, PyObject *kwargs)
    Py_RETURN_NONE;
 }
 
+static inline int setup_one(unsigned int *gpio, int channel, int pud, int direction, int initial) {
+   if (get_gpio_number(channel, gpio))
+      return 0;
+
+   int func = gpio_function(*gpio);
+   if (gpio_warnings &&                             // warnings enabled and
+       ((func != 0 && func != 1) ||                 // (already one of the alt functions or
+       (gpio_direction[*gpio] == -1 && func == 1)))  // already an output not set from this program)
+   {
+      PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.", 1);
+   }
+
+   // warn about pull/up down on i2c channels
+   if (gpio_warnings) {
+      if (rpiinfo.p1_revision == 0) { // compute module - do nothing
+      } else if ((rpiinfo.p1_revision == 1 && (*gpio == 0 || *gpio == 1)) ||
+                 (*gpio == 2 || *gpio == 3)) {
+         if (pud == PUD_UP || pud == PUD_DOWN)
+            PyErr_WarnEx(NULL, "A physical pull up resistor is fitted on this channel!", 1);
+      }
+   }
+
+   if (direction == OUTPUT && (initial == LOW || initial == HIGH)) {
+      output_gpio(*gpio, initial);
+   }
+   setup_gpio(*gpio, direction, pud);
+   gpio_direction[*gpio] = direction;
+   return 1;
+}
+
+
 // python function setup(channel(s), direction, pull_up_down=PUD_OFF, initial=None)
 static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwargs)
 {
@@ -195,37 +227,6 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
    int pud = PUD_OFF + PY_PUD_CONST_OFFSET;
    int initial = -1;
    static char *kwlist[] = {"channel", "direction", "pull_up_down", "initial", NULL};
-   int func;
-
-   int setup_one(void) {
-      if (get_gpio_number(channel, &gpio))
-         return 0;
-
-      func = gpio_function(gpio);
-      if (gpio_warnings &&                             // warnings enabled and
-          ((func != 0 && func != 1) ||                 // (already one of the alt functions or
-          (gpio_direction[gpio] == -1 && func == 1)))  // already an output not set from this program)
-      {
-         PyErr_WarnEx(NULL, "This channel is already in use, continuing anyway.  Use GPIO.setwarnings(False) to disable warnings.", 1);
-      }
-
-      // warn about pull/up down on i2c channels
-      if (gpio_warnings) {
-         if (rpiinfo.p1_revision == 0) { // compute module - do nothing
-         } else if ((rpiinfo.p1_revision == 1 && (gpio == 0 || gpio == 1)) ||
-                    (gpio == 2 || gpio == 3)) {
-            if (pud == PUD_UP || pud == PUD_DOWN)
-               PyErr_WarnEx(NULL, "A physical pull up resistor is fitted on this channel!", 1);
-         }
-      }
-
-      if (direction == OUTPUT && (initial == LOW || initial == HIGH)) {
-         output_gpio(gpio, initial);
-      }
-      setup_gpio(gpio, direction, pud);
-      gpio_direction[gpio] = direction;
-      return 1;
-   }
 
    if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii", kwlist, &chanlist, &direction, &pud, &initial))
       return NULL;
@@ -290,7 +291,7 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
    } else if (chantuple) {
        chancount = PyTuple_Size(chantuple);
    } else {
-       if (!setup_one())
+       if (!setup_one(&gpio, channel, pud, direction, initial))
           return NULL;
        Py_RETURN_NONE;
    }
@@ -320,12 +321,29 @@ static PyObject *py_setup_channel(PyObject *self, PyObject *args, PyObject *kwar
           return NULL;
       }
 
-      if (!setup_one())
+      if (!setup_one(&gpio, channel, pud, direction, initial))
          return NULL;
    }
 
    Py_RETURN_NONE;
 }
+static inline int output_val(unsigned int *gpio, int channel, int value) {
+   if (get_gpio_number(channel, gpio))
+       return 0;
+
+   if (gpio_direction[*gpio] != OUTPUT)
+   {
+      PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT");
+      return 0;
+   }
+
+   if (check_gpio_priv())
+      return 0;
+
+   output_gpio(*gpio, value);
+   return 1;
+}
+
 
 // python function output(channel(s), value(s))
 static PyObject *py_output_gpio(PyObject *self, PyObject *args)
@@ -342,23 +360,6 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
    int chancount = -1;
    int valuecount = -1;
 
-   int output(void) {
-      if (get_gpio_number(channel, &gpio))
-          return 0;
-
-      if (gpio_direction[gpio] != OUTPUT)
-      {
-         PyErr_SetString(PyExc_RuntimeError, "The GPIO channel has not been set up as an OUTPUT");
-         return 0;
-      }
-
-      if (check_gpio_priv())
-         return 0;
-
-      output_gpio(gpio, value);
-      return 1;
-   }
-
    if (!PyArg_ParseTuple(args, "OO", &chanlist, &valuelist))
        return NULL;
 
@@ -416,7 +417,7 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
    }
 
    if (chancount == -1) {
-      if (!output())
+      if (!output_val(&gpio, channel, value))
          return NULL;
       Py_RETURN_NONE;
    }
@@ -472,7 +473,7 @@ static PyObject *py_output_gpio(PyObject *self, PyObject *args)
               return NULL;
           }
       }
-      if (!output())
+      if (!output_val(&gpio, channel, value))
          return NULL;
    }
 
-- 
2.7.0

