1/* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. 4 5 Contributed by Andrew Cagney. 6 7 This file is part of GDB. 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 3 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 21 22 23#include <stdio.h> 24 25#include "config.h" 26 27#ifdef HAVE_STRING_H 28#include <string.h> 29#else 30#ifdef HAVE_STRINGS_H 31#include <strings.h> 32#endif 33#endif 34 35#include "misc.h" 36#include "lf.h" 37#include "filter.h" 38 39struct _filter 40{ 41 char *member; 42 filter *next; 43}; 44 45 46void 47filter_parse (filter **filters, const char *filt) 48{ 49 while (strlen (filt) > 0) 50 { 51 filter *new_filter; 52 filter **last; 53 /* break out a member of the filter list */ 54 const char *flag = filt; 55 unsigned /*size_t */ len; 56 filt = strchr (filt, ','); 57 if (filt == NULL) 58 { 59 filt = strchr (flag, '\0'); 60 len = strlen (flag); 61 } 62 else 63 { 64 len = filt - flag; 65 filt = filt + 1; 66 } 67 /* find an insertion point - sorted order */ 68 last = filters; 69 while (*last != NULL && strncmp (flag, (*last)->member, len) > 0) 70 last = &(*last)->next; 71 if (*last != NULL 72 && strncmp (flag, (*last)->member, len) == 0 73 && strlen ((*last)->member) == len) 74 continue; /* duplicate */ 75 /* create an entry for that member */ 76 new_filter = ZALLOC (filter); 77 new_filter->member = NZALLOC (char, len + 1); 78 strncpy (new_filter->member, flag, len); 79 /* insert it */ 80 new_filter->next = *last; 81 *last = new_filter; 82 } 83} 84 85 86void 87filter_add (filter **set, filter *add) 88{ 89 while (add != NULL) 90 { 91 int cmp; 92 if (*set == NULL) 93 cmp = 1; /* set->member > add->member */ 94 else 95 cmp = strcmp ((*set)->member, add->member); 96 if (cmp > 0) 97 { 98 /* insert it here */ 99 filter *new = ZALLOC (filter); 100 new->member = NZALLOC (char, strlen (add->member) + 1); 101 strcpy (new->member, add->member); 102 new->next = *set; 103 *set = new; 104 add = add->next; 105 } 106 else if (cmp == 0) 107 { 108 /* already in set */ 109 add = add->next; 110 } 111 else /* cmp < 0 */ 112 { 113 /* not reached insertion point */ 114 set = &(*set)->next; 115 } 116 } 117} 118 119 120int 121filter_is_subset (filter *superset, filter *subset) 122{ 123 while (1) 124 { 125 int cmp; 126 if (subset == NULL) 127 return 1; 128 if (superset == NULL) 129 return 0; /* subset isn't finished */ 130 cmp = strcmp (subset->member, superset->member); 131 if (cmp < 0) 132 return 0; /* not found */ 133 else if (cmp == 0) 134 subset = subset->next; /* found */ 135 else if (cmp > 0) 136 superset = superset->next; /* later in list? */ 137 } 138} 139 140 141int 142filter_is_common (filter *l, filter *r) 143{ 144 while (1) 145 { 146 int cmp; 147 if (l == NULL) 148 return 0; 149 if (r == NULL) 150 return 0; 151 cmp = strcmp (l->member, r->member); 152 if (cmp < 0) 153 l = l->next; 154 else if (cmp == 0) 155 return 1; /* common member */ 156 else if (cmp > 0) 157 r = r->next; 158 } 159} 160 161 162int 163filter_is_member (filter *filt, const char *flag) 164{ 165 int index = 1; 166 while (filt != NULL) 167 { 168 if (strcmp (flag, filt->member) == 0) 169 return index; 170 filt = filt->next; 171 index++; 172 } 173 return 0; 174} 175 176 177int 178is_filtered_out (filter *filters, const char *flags) 179{ 180 while (strlen (flags) > 0) 181 { 182 int present; 183 filter *filt = filters; 184 /* break the string up */ 185 char *end = strchr (flags, ','); 186 char *next; 187 unsigned /*size_t */ len; 188 if (end == NULL) 189 { 190 end = strchr (flags, '\0'); 191 next = end; 192 } 193 else 194 { 195 next = end + 1; 196 } 197 len = end - flags; 198 /* check that it is present */ 199 present = 0; 200 filt = filters; 201 while (filt != NULL) 202 { 203 if (strncmp (flags, filt->member, len) == 0 204 && strlen (filt->member) == len) 205 { 206 present = 1; 207 break; 208 } 209 filt = filt->next; 210 } 211 if (!present) 212 return 1; 213 flags = next; 214 } 215 return 0; 216} 217 218 219#if 0 220int 221it_is (const char *flag, const char *flags) 222{ 223 int flag_len = strlen (flag); 224 while (*flags != '\0') 225 { 226 if (!strncmp (flags, flag, flag_len) 227 && (flags[flag_len] == ',' || flags[flag_len] == '\0')) 228 return 1; 229 while (*flags != ',') 230 { 231 if (*flags == '\0') 232 return 0; 233 flags++; 234 } 235 flags++; 236 } 237 return 0; 238} 239#endif 240 241 242char * 243filter_next (filter *set, char *member) 244{ 245 while (set != NULL) 246 { 247 if (strcmp (set->member, member) > 0) 248 return set->member; 249 set = set->next; 250 } 251 return NULL; 252} 253 254 255void 256dump_filter (lf *file, char *prefix, filter *set, char *suffix) 257{ 258 char *member; 259 lf_printf (file, "%s", prefix); 260 member = filter_next (set, ""); 261 if (member != NULL) 262 { 263 while (1) 264 { 265 lf_printf (file, "%s", member); 266 member = filter_next (set, member); 267 if (member == NULL) 268 break; 269 lf_printf (file, ","); 270 } 271 } 272 lf_printf (file, "%s", suffix); 273} 274 275 276#ifdef MAIN 277int 278main (int argc, char **argv) 279{ 280 filter *subset = NULL; 281 filter *superset = NULL; 282 lf *l; 283 int i; 284 if (argc < 2) 285 { 286 printf ("Usage: filter <subset> <filter> ...\n"); 287 exit (1); 288 } 289 290 /* load the filter up */ 291 filter_parse (&subset, argv[1]); 292 for (i = 2; i < argc; i++) 293 filter_parse (&superset, argv[i]); 294 295 /* dump various info */ 296 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter"); 297#if 0 298 if (is_filtered_out (argv[1], superset)) 299 lf_printf (l, "excluded\n"); 300 else 301 lf_printf (l, "included\n"); 302#endif 303 /* subset */ 304 { 305 dump_filter (l, "{", subset, " }"); 306 if (filter_is_subset (superset, subset)) 307 lf_printf (l, " subset of "); 308 else 309 lf_printf (l, " !subset of "); 310 dump_filter (l, "{", superset, " }"); 311 lf_printf (l, "\n"); 312 } 313 /* intersection */ 314 { 315 dump_filter (l, "{", subset, " }"); 316 if (filter_is_common (subset, superset)) 317 lf_printf (l, " intersects "); 318 else 319 lf_printf (l, " !intersects "); 320 dump_filter (l, "{", superset, " }"); 321 lf_printf (l, "\n"); 322 } 323 /* membership */ 324 { 325 filter *memb = subset; 326 while (memb != NULL) 327 { 328 lf_printf (l, "%s", memb->member); 329 if (filter_is_member (superset, memb->member)) 330 lf_printf (l, " in "); 331 else 332 lf_printf (l, " !in "); 333 dump_filter (l, "{", superset, " }"); 334 lf_printf (l, "\n"); 335 memb = memb->next; 336 } 337 } 338 /* addition */ 339 { 340 filter *add = NULL; 341 filter_add (&add, superset); 342 filter_add (&add, subset); 343 dump_filter (l, "{", add, " }"); 344 lf_printf (l, " = "); 345 dump_filter (l, "{", subset, " }"); 346 lf_printf (l, " + "); 347 dump_filter (l, "{", superset, " }"); 348 lf_printf (l, "\n"); 349 } 350 351 return 0; 352} 353#endif 354