Bug Summary

File:build-analysis/../src/lib/s4/src/tools/s4/print.c
Warning:line 93, column 8
Assigned value is garbage or undefined

Annotated Source Code

1/* S4 - An XMMS2 medialib backend
2 * Copyright (C) 2009, 2010 Sivert Berg
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 */
14
15#include "cli.h"
16#include <stdio.h>
17#include <stdlib.h>
18#include <string.h>
19
20/* Converts a value into a string
21 * Uses a static buffer, can not be called twice without
22 * possibly destroying the first value
23 */
24const char *value_to_string (const s4_val_t *val)
25{
26 static char buf[12];
27 const char *ret;
28 int32_t i;
29
30 if (!s4_val_get_str (val, &ret)) {
31 s4_val_get_int (val, &i);
32 sprintf (buf, "%i", i);
33 ret = buf;
34 }
35
36 return ret;
37}
38
39void print_list (list_t *l)
40{
41 list_data_t *data;
42 GList *list = l->list;
43 int first = 1;
44 const char *sep;
45 const char *print_mode = get_var ("print_mode");
46
47 if (strcmp (print_mode, "compact") == 0) {
48 sep = ", ";
49 } else {
50 sep = ",\n";
51 }
52
53 printf ("[");
54 for (; list != NULL((void*)0); list = g_list_next (list)((list) ? (((GList *)(list))->next) : ((void*)0))) {
55 if (first) {
56 first = 0;
57 } else {
58 printf ("%s", sep);
59 }
60 data = list->data;
61 printf ("%s=%s (%s)", data->key,
62 value_to_string (data->val),
63 data->src);
64 }
65 printf ("]\n");
66}
67
68/* Check if there are any non-empty columns */
69static int columns_has_data (int count, const s4_result_t **cols)
70{
71 int i;
72 for (i = 0; i < count; i++) {
73 if (cols[i] != NULL((void*)0))
74 return 1;
75 }
76
77 return 0;
78}
79
80/* Prints a row (for the compact and pretty printer). */
81static void print_row (int row, int column_width, int column_count,
82 const s4_result_t **columns, const char *print_format)
83{
84 int i;
85 const s4_result_t *res;
86 char col_str[column_width];
87 int compact = strcmp (print_format, "compact") == 0;
88
89 printf ("\r|%5i ", row);
90
91 do {
92 for (i = 0; i < column_count; i++) {
19
Assuming 'i' is < 'column_count'
20
Loop condition is true. Entering loop body
93 res = columns[i];
21
Assigned value is garbage or undefined
94 if (res != NULL((void*)0)) {
95 columns[i] = s4_result_next (res);
96 if (compact) {
97 snprintf (col_str, column_width + 1, "| %-*s", column_width,
98 value_to_string (s4_result_get_val (res)));
99 } else {
100 snprintf (col_str, column_width + 1, "| %s (%s) %*s",
101 value_to_string (s4_result_get_val (res)),
102 s4_result_get_src (res),
103 column_width, "");
104 }
105 printf ("%s", col_str);
106 } else {
107 printf ("| %*s", column_width - 2, "");
108 }
109 }
110 printf ("|\n| ");
111 } while (columns_has_data (column_count, columns));
112}
113
114/* Finds the key in a resultset column. If there are more than one
115 * key is returns "_"
116 */
117static const char *column_key (int col, const s4_resultset_t *set)
118{
119 int row;
120 const char *ret = NULL((void*)0);
121 const s4_result_t *res;
122
123 for (row = 0; row < s4_resultset_get_rowcount (set); row++) {
124 res = s4_resultset_get_result (set, row, col);
125 while (res != NULL((void*)0)) {
126 const char *key = s4_result_get_key (res);
127 if (ret != NULL((void*)0) && strcmp (ret, key)) {
128 return "_";
129 } else if (ret == NULL((void*)0)) {
130 ret = key;
131 }
132 res = s4_result_next (res);
133 }
134 }
135
136 return ret;
137}
138
139/* Search for a column where all the fields have the given key. */
140int find_column (const char *key, const s4_resultset_t *set)
141{
142 int col;
143
144 for (col = 0; col < s4_resultset_get_colcount (set); col++) {
145 const char *col_key = column_key (col, set);
146 if (col_key != NULL((void*)0) && strcmp (col_key, key) == 0) {
147 return col;
148 }
149 }
150
151 return -1;
152}
153
154/* Uses the COLUMNS env. var to find the terminal width.
155 * If it is not set it defaults to 80 chars
156 */
157static int terminal_width (void)
158{
159 const char *width = getenv ("COLUMNS");
160 int ret;
161
162 if (width == NULL((void*)0) || (ret = atoi (width)) == 0) {
163 return 80;
164 }
165
166 return ret;
167}
168
169/* Prints a resultset. Affected by the print_format config variable */
170void print_result (const s4_resultset_t *set)
171{
172 int col, row, total_width, col_width;
173 const s4_result_t **columns, *res;
174 const char *print_format = get_var ("print_mode");
175 char *col_str;
176
177 if (s4_resultset_get_rowcount (set) == 0) {
8
Assuming the condition is false
9
Taking false branch
178 printf ("No results\n");
179 return;
180 }
181
182 columns = malloc (sizeof (s4_result_t*) * s4_resultset_get_colcount (set));
183 total_width = terminal_width () - 8;
184 col_width = total_width / s4_resultset_get_colcount (set);
185 col_str = malloc (col_width + 1);
186
187 if (strcmp (print_format, "pretty") == 0
188 || strcmp (print_format, "compact") == 0) {
189 /* Print the header */
190 printf ("| row ");
191 for (col = 0; col < s4_resultset_get_colcount (set); col++) {
10
Assuming the condition is false
11
Loop condition is false. Execution continues on line 196
192 snprintf (col_str, col_width + 1, "| %-*s",
193 col_width - 2, column_key (col, set));
194 printf ("%s", col_str);
195 }
196 printf ("|\n|------|");
197 for (col = 0; col < s4_resultset_get_colcount (set); col++) {
12
Assuming the condition is false
13
Loop condition is false. Execution continues on line 203
198 for (row = 1; row < col_width; row++) {
199 putchar ('-');
200 }
201 putchar ('|');
202 }
203 putchar ('\n');
204
205 /* Print the rows */
206 for (row = 0; row < s4_resultset_get_rowcount (set); row++) {
14
Assuming the condition is true
15
Loop condition is true. Entering loop body
207 for (col = 0; col < s4_resultset_get_colcount (set); col++) {
16
Assuming the condition is false
17
Loop condition is false. Execution continues on line 210
208 columns[col] = s4_resultset_get_result (set, row, col);
209 }
210 print_row (row, col_width, s4_resultset_get_colcount (set),
18
Calling 'print_row'
211 columns, print_format);
212 }
213 } else { /* verbose */
214 /* Print the header */
215 printf (" row | col | data\n");
216
217 /* Print the data */
218 for (row = 0; row < s4_resultset_get_rowcount (set); row++) {
219 printf ("\r%5i ", row);
220 for (col = 0; col < s4_resultset_get_colcount (set); col++) {
221 printf ("| %5i ", col);
222 for (res = s4_resultset_get_result (set, row, col);
223 res != NULL((void*)0);
224 res = s4_result_next (res)) {
225 printf ("| %s=%s (%s)\n | ", s4_result_get_key (res),
226 value_to_string (s4_result_get_val (res)),
227 s4_result_get_src (res));
228 }
229 printf ("\r ");
230 }
231 }
232 }
233 printf (" \r"); /* Cleans up any left over | and spaces */
234
235 free (col_str);
236 free (columns);
237}
238
239void print_cond (s4_condition_t *cond)
240{
241 int i;
242 const char *operation;
243 s4_condition_t *operand;
244
245 if (s4_cond_is_filter (cond)) {
246 switch (s4_cond_get_filter_type (cond)) {
247 case S4_FILTER_EQUAL: operation = "="; break;
248 case S4_FILTER_NOTEQUAL: operation = "!="; break;
249 case S4_FILTER_SMALLER: operation = "<"; break;
250 case S4_FILTER_GREATER: operation = ">"; break;
251 case S4_FILTER_SMALLEREQ: operation = "<="; break;
252 case S4_FILTER_GREATEREQ: operation = ">="; break;
253 case S4_FILTER_MATCH: operation = "~"; break;
254 case S4_FILTER_EXISTS: operation = "+"; break;
255 case S4_FILTER_TOKEN: operation = "^"; break;
256 default: operation = "unknown filter"; break;
257 }
258 if (s4_cond_get_key (cond) != NULL((void*)0)) {
259 printf ("%s %s", s4_cond_get_key (cond), operation);
260 } else {
261 printf ("%s", operation);
262 }
263 if (s4_cond_get_filter_type (cond) == S4_FILTER_MATCH) {
264 printf (" pattern");
265 } else if (s4_cond_get_filter_type (cond) == S4_FILTER_TOKEN) {
266 printf (" %s", (const char *)s4_cond_get_funcdata (cond));
267 } else if (s4_cond_get_filter_type (cond) != S4_FILTER_EXISTS) {
268 printf (" %s", value_to_string (s4_cond_get_funcdata (cond)));
269 }
270 } else {
271 switch (s4_cond_get_combiner_type (cond)) {
272 case S4_COMBINE_AND: operation = "&"; break;
273 case S4_COMBINE_NOT: operation = "!"; break;
274 case S4_COMBINE_OR: operation = "|"; break;
275 default: operation = "unknown combiner"; break;
276 }
277
278 if (s4_cond_get_combiner_type (cond) == S4_COMBINE_NOT) {
279 printf ("!(");
280 } else {
281 printf ("(");
282 }
283 for (i = 0; (operand = s4_cond_get_operand (cond, i)) != NULL((void*)0); i++) {
284 if (i != 0)
285 printf (") %s (", operation);
286 print_cond (operand);
287 }
288 printf (")");
289 }
290}
291
292void print_fetch (s4_fetchspec_t *fetch)
293{
294 int i;
295 const char *sep;
296 const char *print_mode = get_var ("print_mode");
297
298 if (strcmp (print_mode, "compact") == 0) {
299 sep = ", ";
300 } else {
301 sep = ",\n";
302 }
303 printf ("(");
304 for (i = 0; i < s4_fetchspec_size (fetch); i++) {
305 if (i != 0) {
306 printf ("%s", sep);
307 }
308 printf ("%s", s4_fetchspec_get_key (fetch, i));
309 }
310 printf (")\n");
311}
312
313void print_vars ()
314{
315 GHashTableIter iter;
316 char *str;
317 void *val;
318
319 g_hash_table_iter_init (&iter, cond_table);
320 printf ("Cond table\n");
321 while (g_hash_table_iter_next (&iter, (void**)&str, &val)) {
1
Loop condition is false. Execution continues on line 327
322 printf ("%s: ", str);
323 print_cond (val);
324 printf ("\n");
325 }
326
327 g_hash_table_iter_init (&iter, fetch_table);
328 printf ("Fetch table\n");
329 while (g_hash_table_iter_next (&iter, (void**)&str, &val)) {
2
Loop condition is false. Execution continues on line 333
330 printf ("%s: ", str);
331 print_fetch (val);
332 }
333 g_hash_table_iter_init (&iter, res_table);
334 printf ("Result table\n");
335 while (g_hash_table_iter_next (&iter, (void**)&str, &val)) {
3
Loop condition is true. Entering loop body
4
Loop condition is true. Entering loop body
5
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
336 printf ("%s: ", str);
337 print_result (val);
7
Calling 'print_result'
338 }
339 g_hash_table_iter_init (&iter, list_table);
340 printf ("List table\n");
341 while (g_hash_table_iter_next (&iter, (void**)&str, &val)) {
342 printf ("%s: ", str);
343 print_list (val);
344 }
345}
346
347void print_help (void)
348{
349 printf("All statements must end with a semicolon\n\n"
350 "Statements with no value:\n"
351 ".add <list>, <list> - For every (key, val) from the first list it adds\n"
352 " the attributes (key, val, src) from the second list\n"
353 ".del <list>, <list> - For every (key, val) from the first list it deletes\n"
354 " the attributes (key, val, src) from the second list\n"
355 ".exit - Exit the program\n"
356 ".help - Prints this help\n"
357 ".set key value - Sets the option key to val\n"
358 ".set key - Shows the value of the key\n"
359 ".set - Shows the value of all keys\n"
360 ".vars - Prints all bound variables\n\n"
361 "?var = <cond> - Assigns cond to the condition variable var\n"
362 "%%var = <fetch> - Assigns fetch to the fetch variable var\n"
363 "@var = <result> - Assigns var to something returning result\n"
364 "$var = <list> - Assigns the list to the list variable var\n"
365 "#var = <pref> - Assigns the pref to the souce preference variable var\n\n"
366 "Conditions (<cond>):\n"
367 "?var - Returns the condition bound to var\n"
368 "!cond - Matches everything cond does not match\n"
369 "cond1 & cond2 - Matches if both cond1 and cond2 matches\n"
370 "cond1 | cond2 - Matches if cond1 or cond2 matches\n\n"
371 "Filter conditions\n"
372 "key = value - Matches all entries where key equals value\n"
373 "key ~ value - Matches all entries where key matches value\n"
374 "key < value - Matches all entries where key is smaller than value\n"
375 "key > value - Matches all entries where key is greater than value\n"
376 "key ^ token - Matches all entries where key has a token equal to token\n"
377 "key != value - Matches all entries where key does not equal value\n"
378 "key <= value - Matches all entries where key is smaller or equal to value\n"
379 "key >= value - Matches all entries where key is greater or equal to value\n"
380 "= value - Matches all entries where one or more keys equals value\n"
381 "~ value - Matches all entries where one or more keys matches value\n"
382 "< value - Matches all entries where one or more keys is smaller than value\n"
383 "> value - Matches all entries where one or more keys is greater than value\n"
384 "^ token - Matches all entries where one or more keys has token\n"
385 "!= value - Matches all entries where one or more keys does not equal value\n"
386 "<= value - Matches all entries where one or more keys is smaller or equal to value\n"
387 ">= value - Matches all entries where one or more keys is greater or equal to value\n"
388 "+key - Matches all entries that has key\n"
389 "+ - Matches everything\n"
390 "<pref> may be added after all filter conditions to use a source preference to only match\n"
391 "against the highest priority source in the source preference\n\n"
392 "Fetch specification (<fetch>):\n"
393 "%%var - Returns the fetch spec bound to var\n"
394 "(key1, ..., keyn) - Fetches keys 1 through n from matching entries\n"
395 "(key1 <pref>,...) - Fetches key1 using the source preference given\n"
396 "key - Fetches key from matching entries\n"
397 "key <pref> - Fetches key using the source preference given\n"
398 "_ - Fetches everything from matching entries\n\n"
399 "Results (<result>):\n"
400 ".query <fetch> <cond> - Queries the database, returns a result\n\n"
401 "@var - Returns the result bound to var\n\n"
402 "Lists (<list>):\n"
403 "$var - Returns the list bound to the variable var\n"
404 "<result>{<rng>,<rng>} - Creates a list of the columns given by {row,col}.\n"
405 "<result>{<rng>, key} - Creates a list of the column where the column key\n"
406 " equals key and the rows are in the range\n"
407 "[key val src, ...] - Creates a list\n"
408 "[key val, ...] - Creates a list where source is set to default_source\n\n"
409 "Ranges (<rng>):\n"
410 "start - stop - Creates a range from start to stop (inclusive)\n"
411 " - stop - Creates a range from 0 to stop\n"
412 "start - - Creates a range from start with no stop\n"
413 " - - Creates a range from 0 with no stop\n\n"
414 "Source preferences (<pref>):\n"
415 "#var - Returns the source preference bound to var\n"
416 ":src1:src2:...:srcn - Creates a new source preference where src1 has the highest priority,\n"
417 " src2 seconds highest and so on\n\n"
418 "Shorthand:\n"
419 ".q = .query\n"
420 ".a = .add\n"
421 ".d = .del\n"
422 ".v = .vars\n"
423 ".h = .help\n"
424 ".? = .help\n"
425 ".s = .set\n"
426 ".e = .exit\n"
427 );
428}