| File: | xlsatoms.c |
| Location: | line 206, column 5 |
| Description: | Function call argument is an uninitialized value |
| 1 | /* | |||
| 2 | * | |||
| 3 | Copyright 1989, 1998 The Open Group | |||
| 4 | Copyright 2009 Open Text Corporation | |||
| 5 | ||||
| 6 | Permission to use, copy, modify, distribute, and sell this software and its | |||
| 7 | documentation for any purpose is hereby granted without fee, provided that | |||
| 8 | the above copyright notice appear in all copies and that both that | |||
| 9 | copyright notice and this permission notice appear in supporting | |||
| 10 | documentation. | |||
| 11 | ||||
| 12 | The above copyright notice and this permission notice shall be included in | |||
| 13 | all copies or substantial portions of the Software. | |||
| 14 | ||||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| 18 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||
| 19 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||
| 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||
| 21 | ||||
| 22 | Except as contained in this notice, the name of The Open Group shall not be | |||
| 23 | used in advertising or otherwise to promote the sale, use or other dealings | |||
| 24 | in this Software without prior written authorization from The Open Group. | |||
| 25 | * | |||
| 26 | * Author: Jim Fulton, MIT X Consortium | |||
| 27 | * Author: Peter Harris, Open Text Corporation | |||
| 28 | */ | |||
| 29 | ||||
| 30 | #ifdef HAVE_CONFIG_H1 | |||
| 31 | # include "config.h" | |||
| 32 | #endif | |||
| 33 | ||||
| 34 | #include <stdio.h> | |||
| 35 | #include <stdlib.h> | |||
| 36 | #include <string.h> | |||
| 37 | #include <xcb/xcb.h> | |||
| 38 | #include <xcb/xproto.h> | |||
| 39 | ||||
| 40 | #define ATOMS_PER_BATCH100 100 /* This number can be tuned | |||
| 41 | higher for fewer round-trips | |||
| 42 | lower for less bandwidth wasted */ | |||
| 43 | ||||
| 44 | static const char *ProgramName; | |||
| 45 | static const char *DisplayString; | |||
| 46 | ||||
| 47 | static void do_name ( xcb_connection_t *c, const char *format, char *name ); | |||
| 48 | static int parse_range ( char *range, long *lowp, long *highp ); | |||
| 49 | static void do_range ( xcb_connection_t *c, const char *format, char *range ); | |||
| 50 | static void list_atoms ( xcb_connection_t *c, const char *format, int mask, | |||
| 51 | long low, long high ); | |||
| 52 | ||||
| 53 | static void | |||
| 54 | usage(const char *errmsg) | |||
| 55 | { | |||
| 56 | if (errmsg != NULL((void *)0)) | |||
| 57 | fprintf (stderr__stderrp, "%s: %s\n\n", ProgramName, errmsg); | |||
| 58 | ||||
| 59 | fprintf (stderr__stderrp, "usage: %s [-options...]\n\n%s\n", ProgramName, | |||
| 60 | "where options include:\n" | |||
| 61 | " -display dpy X server to which to connect\n" | |||
| 62 | " -format string printf-style format to use\n" | |||
| 63 | " -range [num]-[num] atom values to list\n" | |||
| 64 | " -name string name of single atom to print\n" | |||
| 65 | " -version print program version\n" | |||
| 66 | ); | |||
| 67 | exit (1); | |||
| 68 | } | |||
| 69 | ||||
| 70 | int | |||
| 71 | main(int argc, char *argv[]) | |||
| 72 | { | |||
| 73 | char *displayname = NULL((void *)0); | |||
| 74 | const char *format = "%lu\t%s"; | |||
| 75 | int i, doit; | |||
| 76 | int didit = 0; | |||
| 77 | xcb_connection_t *c = NULL((void *)0); | |||
| 78 | ||||
| 79 | ProgramName = argv[0]; | |||
| 80 | ||||
| 81 | for (doit = 0; doit < 2; doit++) { /* pre-parse to get display */ | |||
| ||||
| 82 | for (i = 1; i < argc; i++) { | |||
| 83 | char *arg = argv[i]; | |||
| 84 | ||||
| 85 | if (arg[0] == '-') { | |||
| 86 | switch (arg[1]) { | |||
| 87 | case 'd': /* -display dpy */ | |||
| 88 | if (++i >= argc) usage ("-display requires an argument"); | |||
| 89 | if (!doit) displayname = argv[i]; | |||
| 90 | continue; | |||
| 91 | case 'f': /* -format string */ | |||
| 92 | if (++i >= argc) usage ("-format requires an argument"); | |||
| 93 | if (doit) format = argv[i]; | |||
| 94 | continue; | |||
| 95 | case 'r': /* -range num-[num] */ | |||
| 96 | if (++i >= argc) usage ("-range requires an argument"); | |||
| 97 | if (doit) { | |||
| 98 | do_range (c, format, argv[i]); | |||
| 99 | didit = 1; | |||
| 100 | } | |||
| 101 | continue; | |||
| 102 | case 'n': /* -name string */ | |||
| 103 | if (++i >= argc) usage ("-name requires an argument"); | |||
| 104 | if (doit) { | |||
| 105 | do_name (c, format, argv[i]); | |||
| 106 | didit = 1; | |||
| 107 | } | |||
| 108 | continue; | |||
| 109 | case 'v': | |||
| 110 | if (strcmp(arg, "-version") == 0) { | |||
| 111 | puts(PACKAGE_STRING"xlsatoms 1.1.2"); | |||
| 112 | exit(0); | |||
| 113 | } | |||
| 114 | /* else FALLTHROUGH to unrecognized arg case below */ | |||
| 115 | } | |||
| 116 | } | |||
| 117 | fprintf (stderr__stderrp, "%s: unrecognized argument %s\n\n", | |||
| 118 | ProgramName, arg); | |||
| 119 | usage (NULL((void *)0)); | |||
| 120 | } | |||
| 121 | if (!doit) { | |||
| 122 | DisplayString = displayname; | |||
| 123 | if (!DisplayString) | |||
| 124 | DisplayString = getenv("DISPLAY"); | |||
| 125 | if (!DisplayString) | |||
| 126 | DisplayString = ""; | |||
| 127 | c = xcb_connect(displayname, NULL((void *)0)); | |||
| 128 | if (!c || xcb_connection_has_error(c)) { | |||
| 129 | fprintf (stderr__stderrp, "%s: unable to open display \"%s\"\n", | |||
| 130 | ProgramName, DisplayString); | |||
| 131 | exit (1); | |||
| 132 | } | |||
| 133 | } else | |||
| 134 | if (!didit) /* no options, default is list all */ | |||
| 135 | list_atoms(c, format, 0, 0, 0); | |||
| 136 | } | |||
| 137 | ||||
| 138 | xcb_disconnect(c); | |||
| 139 | exit (0); | |||
| 140 | } | |||
| 141 | ||||
| 142 | static void | |||
| 143 | do_name(xcb_connection_t *c, const char *format, char *name) | |||
| 144 | { | |||
| 145 | xcb_intern_atom_reply_t *a = xcb_intern_atom_reply(c, | |||
| 146 | xcb_intern_atom_unchecked(c, 1, strlen(name), name), NULL((void *)0)); | |||
| 147 | ||||
| 148 | if (a && a->atom != XCB_NONE0L) { | |||
| 149 | printf (format, (unsigned long) a->atom, name); | |||
| 150 | putchar ('\n'); | |||
| 151 | } else { | |||
| 152 | fprintf (stderr__stderrp, "%s: no atom named \"%s\" on server \"%s\"\n", | |||
| 153 | ProgramName, name, DisplayString); | |||
| 154 | } | |||
| 155 | ||||
| 156 | if (a) | |||
| 157 | free(a); | |||
| 158 | } | |||
| 159 | ||||
| 160 | ||||
| 161 | #define RangeLow(1 << 0) (1 << 0) | |||
| 162 | #define RangeHigh(1 << 1) (1 << 1) | |||
| 163 | ||||
| 164 | static int | |||
| 165 | parse_range(char *range, long *lowp, long *highp) | |||
| 166 | { | |||
| 167 | char *dash; | |||
| 168 | int mask = 0; | |||
| 169 | ||||
| 170 | if (!range) { /* NULL means default */ | |||
| 171 | *lowp = 1; | |||
| 172 | return RangeLow(1 << 0); | |||
| 173 | } | |||
| 174 | ||||
| 175 | dash = strchr(range, '-'); | |||
| 176 | if (!dash) dash = strchr(range, ':'); | |||
| 177 | if (dash) { | |||
| 178 | if (dash == range) { /* -high */ | |||
| 179 | *lowp = 1; | |||
| 180 | } else { /* low-[high] */ | |||
| 181 | *dash = '\0'; | |||
| 182 | *lowp = atoi (range); | |||
| 183 | *dash = '-'; | |||
| 184 | } | |||
| 185 | mask |= RangeLow(1 << 0); | |||
| 186 | dash++; | |||
| 187 | if (*dash) { /* [low]-high */ | |||
| 188 | *highp = atoi (dash); | |||
| 189 | mask |= RangeHigh(1 << 1); | |||
| 190 | } | |||
| 191 | } else { /* number (low == high) */ | |||
| 192 | *lowp = *highp = atoi (range); | |||
| 193 | mask |= (RangeLow(1 << 0) | RangeHigh(1 << 1)); | |||
| 194 | } | |||
| 195 | ||||
| 196 | return mask; | |||
| 197 | } | |||
| 198 | ||||
| 199 | static void | |||
| 200 | do_range(xcb_connection_t *c, const char *format, char *range) | |||
| 201 | { | |||
| 202 | int mask; | |||
| 203 | long low, high; | |||
| 204 | ||||
| 205 | mask = parse_range (range, &low, &high); | |||
| 206 | list_atoms (c, format, mask, low, high); | |||
| ||||
| 207 | } | |||
| 208 | ||||
| 209 | static int | |||
| 210 | say_batch(xcb_connection_t *c, const char *format, xcb_get_atom_name_cookie_t *cookie, long low, long count) | |||
| 211 | { | |||
| 212 | xcb_generic_error_t *e; | |||
| 213 | char atom_name[1024]; | |||
| 214 | long i; | |||
| 215 | int done = 0; | |||
| 216 | ||||
| 217 | for (i = 0; i < count; i++) | |||
| 218 | cookie[i] = xcb_get_atom_name(c, i + low); | |||
| 219 | ||||
| 220 | for (i = 0; i < count; i++) { | |||
| 221 | xcb_get_atom_name_reply_t *r; | |||
| 222 | r = xcb_get_atom_name_reply(c, cookie[i], &e); | |||
| 223 | if (r) { | |||
| 224 | /* We could just use %.*s in 'format', but we want to be compatible | |||
| 225 | with legacy command line usage */ | |||
| 226 | snprintf(atom_name, sizeof(atom_name), "%.*s",__builtin___snprintf_chk (atom_name, sizeof(atom_name), 0, __builtin_object_size (atom_name, 2 > 1 ? 1 : 0), "%.*s", r->name_len, xcb_get_atom_name_name (r)) | |||
| 227 | r->name_len, xcb_get_atom_name_name(r))__builtin___snprintf_chk (atom_name, sizeof(atom_name), 0, __builtin_object_size (atom_name, 2 > 1 ? 1 : 0), "%.*s", r->name_len, xcb_get_atom_name_name (r)); | |||
| 228 | ||||
| 229 | printf (format, i + low, atom_name); | |||
| 230 | putchar ('\n'); | |||
| 231 | free(r); | |||
| 232 | } | |||
| 233 | if (e) { | |||
| 234 | done = 1; | |||
| 235 | free(e); | |||
| 236 | } | |||
| 237 | } | |||
| 238 | ||||
| 239 | return done; | |||
| 240 | } | |||
| 241 | ||||
| 242 | static void | |||
| 243 | list_atoms(xcb_connection_t *c, const char *format, int mask, long low, long high) | |||
| 244 | { | |||
| 245 | xcb_get_atom_name_cookie_t *cookie_jar; | |||
| 246 | int done = 0; | |||
| 247 | ||||
| 248 | switch (mask) { | |||
| 249 | case RangeHigh(1 << 1): | |||
| 250 | low = 1; | |||
| 251 | /* fall through */ | |||
| 252 | case (RangeLow(1 << 0) | RangeHigh(1 << 1)): | |||
| 253 | cookie_jar = malloc((high - low + 1) * sizeof(xcb_get_atom_name_cookie_t)); | |||
| 254 | if (!cookie_jar) { | |||
| 255 | fprintf(stderr__stderrp, "Out of memory allocating space for %ld atom requests\n", high - low); | |||
| 256 | return; | |||
| 257 | } | |||
| 258 | ||||
| 259 | say_batch(c, format, cookie_jar, low, high - low + 1); | |||
| 260 | free(cookie_jar); | |||
| 261 | break; | |||
| 262 | ||||
| 263 | default: | |||
| 264 | low = 1; | |||
| 265 | /* fall through */ | |||
| 266 | case RangeLow(1 << 0): | |||
| 267 | cookie_jar = malloc(ATOMS_PER_BATCH100 * sizeof(xcb_get_atom_name_cookie_t)); | |||
| 268 | if (!cookie_jar) { | |||
| 269 | fprintf(stderr__stderrp, "Out of memory allocating space for %ld atom requests\n", (long) ATOMS_PER_BATCH100); | |||
| 270 | return; | |||
| 271 | } | |||
| 272 | while (!done) { | |||
| 273 | done = say_batch(c, format, cookie_jar, low, ATOMS_PER_BATCH100); | |||
| 274 | low += ATOMS_PER_BATCH100; | |||
| 275 | } | |||
| 276 | free(cookie_jar); | |||
| 277 | break; | |||
| 278 | } | |||
| 279 | ||||
| 280 | return; | |||
| 281 | } |