2 * collectd - src/sn-normalize.c
3 * Copyright (C) 2008-2010 Florian octo Forster
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Florian octo Forster <ff at octo.it>
22 #ifndef _ISOC99_SOURCE
23 # define _ISOC99_SOURCE
25 #ifndef _POSIX_C_SOURCE
26 # define _POSIX_C_SOURCE 200112L
33 #include "sn_network.h"
35 #include "sn_comparator.h"
37 struct shmoo_line_info_s
43 typedef struct shmoo_line_info_s shmoo_line_info_t;
51 typedef struct shmoo_chart_s shmoo_chart_t;
52 #define STATE(sc, i, s, z) \
53 (sc)->state[((z) * (sc)->inputs_num * (sc)->stages_num) \
54 + ((s) * (sc)->inputs_num) \
57 static int account_values (shmoo_chart_t *sc, /* {{{ */
58 int stage_num, int zeros_num, int *values)
62 for (i = 0; i < sc->inputs_num; i++)
66 state = STATE (sc, i, stage_num, zeros_num);
71 else if (state == '1')
73 else /* if ((state == '0') || (state == '?')) */
76 else /* if (values[i] == 1) */
80 else if (state == '0')
82 else /* if ((state == '1') || (state == '?')) */
86 STATE (sc, i, stage_num, zeros_num) = state;
90 } /* }}} int account_values */
92 static int try_all_stages (const sn_network_t *n, /* {{{ */
93 shmoo_chart_t *sc, int *pattern)
95 int values[n->inputs_num];
99 /* Copy the test pattern */
100 memcpy (values, pattern, sizeof (values));
102 /* Count the zeros.. */
104 for (i = 0; i < n->inputs_num; i++)
108 for (i = 0; i < n->stages_num; i++)
113 sn_stage_sort (s, values);
114 account_values (sc, i, zeros_num, values);
118 } /* }}} int try_all_stages */
120 static int try_all_patterns (const sn_network_t *n, /* {{{ */
123 int test_pattern[n->inputs_num];
125 /* Initialize the pattern */
126 memset (test_pattern, 0, sizeof (test_pattern));
133 try_all_stages (n, sc, test_pattern);
135 /* Generate the next test pattern */
137 for (i = 0; i < n->inputs_num; i++)
139 if (test_pattern[i] == 0)
152 /* Break out of the while loop if we tested all possible patterns */
157 /* All tests successfull */
159 } /* }}} int try_all_patterns */
161 static shmoo_chart_t *shmoo_chart_create (const sn_network_t *n)
166 sc = malloc (sizeof (*sc));
167 memset (sc, 0, sizeof (*sc));
169 sc->inputs_num = SN_NETWORK_INPUT_NUM (n);
170 sc->stages_num = SN_NETWORK_STAGE_NUM (n);
172 state_size = sc->inputs_num * (sc->inputs_num + 1) * sc->stages_num;
173 sc->state = calloc (state_size, sizeof (*sc->state));
175 memset (sc->state, (int) '?', state_size);
177 try_all_patterns (n, sc);
180 } /* shmoo_chart_t *shmoo_chart_create */
182 static int compare_line_info (const void *av, const void *bv) /* {{{ */
184 const shmoo_line_info_t *al;
185 const shmoo_line_info_t *bl;
190 if (al->zeros_num > bl->zeros_num)
192 else if (al->zeros_num < bl->zeros_num)
194 else if (al->ones_num > bl->ones_num)
196 else if (al->ones_num < bl->ones_num)
198 else if (al->line_num < bl->line_num)
200 else if (al->line_num > bl->line_num)
204 } /* }}} int compare_line_info */
211 * 123: 00000000--------1
212 * 111: 000000--------111
213 * 23: 0000--------11111
214 * 101: 0---------1111111
216 static void print_shmoo_stage (shmoo_chart_t *sc, int stage_num) /* {{{ */
218 shmoo_line_info_t line_info[sc->inputs_num];
219 char buffer[sc->inputs_num + 2];
222 for (i = 0; i < sc->inputs_num; i++)
226 line_info[i].line_num = i;
227 line_info[i].zeros_num = 0;
228 line_info[i].ones_num = 0;
230 for (j = 0; j < sc->inputs_num; j++)
231 if (STATE(sc, i, stage_num, j) == '0')
232 line_info[i].zeros_num++;
233 else if (STATE(sc, i, stage_num, j) == '1')
234 line_info[i].ones_num++;
238 qsort (line_info, sc->inputs_num, sizeof (line_info[0]),
241 printf ("=== After applying stage %i ===\n\n", stage_num);
243 if (sc->inputs_num > 9)
245 for (i = 0; i < (sc->inputs_num + 1); i++)
249 j = (sc->inputs_num - i) / 10;
253 buffer[sizeof (buffer) - 1] = 0;
254 printf (" %s\n", buffer);
257 for (i = 0; i < (sc->inputs_num + 1); i++)
261 j = (sc->inputs_num - i) % 10;
265 buffer[sizeof (buffer) - 1] = 0;
266 printf (" %s\n\n", buffer);
268 for (i = 0; i < sc->inputs_num; i++)
273 line_num = line_info[i].line_num;
275 for (j = 0; j < (sc->inputs_num + 1); j++)
279 zeros_num = sc->inputs_num - j;
281 buffer[j] = STATE(sc, line_num, stage_num, zeros_num);
283 buffer[sizeof (buffer) - 1] = 0;
285 printf (" %3i: %s\n", line_num, buffer);
289 } /* }}} void print_shmoo_stage */
291 static void print_shmoo (shmoo_chart_t *sc) /* {{{ */
295 for (i = 0; i < sc->stages_num; i++)
296 print_shmoo_stage (sc, i);
297 } /* }}} void print_shmoo */
299 static void exit_usage (const char *name)
301 printf ("%s [file]\n", name);
305 int main (int argc, char **argv)
312 exit_usage (argv[0]);
316 if ((strcmp ("-h", argv[1]) == 0)
317 || (strcmp ("--help", argv[1]) == 0)
318 || (strcmp ("-help", argv[1]) == 0))
319 exit_usage (argv[0]);
321 n = sn_network_read_file (argv[1]);
325 n = sn_network_read (stdin);
330 printf ("n == NULL!\n");
334 sc = shmoo_chart_create (n);
337 return (EXIT_SUCCESS);
340 /* vim: set sw=2 sts=2 et fdm=marker : */