src/sn_stage.c: Check arguments in some of the methods.
[sort-networks.git] / src / sn_stage.c
index 3999851..7319094 100644 (file)
@@ -1,6 +1,6 @@
 /**
- * collectd - src/sn_stage.c
- * Copyright (C) 2008  Florian octo Forster
+ * libsortnetwork - src/sn_stage.c
+ * Copyright (C) 2008-2010  Florian octo Forster
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -16,7 +16,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  *
  * Authors:
- *   Florian octo Forster <octo at verplant.org>
+ *   Florian octo Forster <ff at octo.it>
  **/
 
 #ifndef _ISOC99_SOURCE
@@ -29,6 +29,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <errno.h>
 
 #include "sn_comparator.h"
 #include "sn_stage.h"
@@ -82,10 +83,17 @@ int sn_stage_comparator_add (sn_stage_t *s, const sn_comparator_t *c)
   sn_comparator_t *temp;
   int i;
 
+  if ((s == NULL) || (c == NULL))
+    return (EINVAL);
+
+  i = sn_stage_comparator_check_conflict (s, c);
+  if (i != 0)
+    return (i);
+
   temp = (sn_comparator_t *) realloc (s->comparators,
       (s->comparators_num + 1) * sizeof (sn_comparator_t));
   if (temp == NULL)
-    return (-1);
+    return (ENOMEM);
   s->comparators = temp;
   temp = NULL;
 
@@ -112,6 +120,9 @@ int sn_stage_comparator_remove (sn_stage_t *s, int c_num)
   int nmemb = s->comparators_num - (c_num + 1);
   sn_comparator_t *temp;
 
+  if ((s == NULL) || (s->comparators_num <= c_num))
+    return (EINVAL);
+
   assert (c_num < s->comparators_num);
   assert (c_num >= 0);
 
@@ -276,16 +287,39 @@ int sn_stage_invert (sn_stage_t *s)
 {
   int i;
 
+  if (s == NULL)
+    return (EINVAL);
+
   for (i = 0; i < s->comparators_num; i++)
     sn_comparator_invert (s->comparators + i);
 
   return (0);
 } /* int sn_stage_invert */
 
+int sn_stage_shift (sn_stage_t *s, int sw, int inputs_num)
+{
+  int i;
+
+  if ((s == NULL) || (inputs_num < 2))
+    return (EINVAL);
+
+  sw %= inputs_num;
+  if (sw == 0)
+    return (0);
+
+  for (i = 0; i < s->comparators_num; i++)
+    sn_comparator_shift (s->comparators + i, sw, inputs_num);
+
+  return (0);
+} /* int sn_stage_shift */
+
 int sn_stage_swap (sn_stage_t *s, int con0, int con1)
 {
   int i;
 
+  if (s == NULL)
+    return (EINVAL);
+
   for (i = 0; i < s->comparators_num; i++)
     sn_comparator_swap (s->comparators + i, con0, con1);
 
@@ -297,6 +331,9 @@ int sn_stage_cut_at (sn_stage_t *s, int input, enum sn_network_cut_dir_e dir)
   int new_position = input;
   int i;
 
+  if ((s == NULL) || (input < 0))
+    return (-EINVAL);
+
   for (i = 0; i < s->comparators_num; i++)
   {
     sn_comparator_t *c = s->comparators + i;
@@ -421,7 +458,7 @@ int sn_stage_serialize (sn_stage_t *s,
 
 #define SNPRINTF_OR_FAIL(...) \
   status = snprintf (buffer, buffer_size, __VA_ARGS__); \
-  if ((status < 1) || (status >= buffer_size)) \
+  if ((status < 1) || (((size_t) status) >= buffer_size)) \
     return (-1); \
   buffer += status; \
   buffer_size -= status;