1/* The IGEN simulator generator for GDB, the GNU Debugger. 2 3 Copyright 2002-2023 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#include <string.h> 25 26#include "misc.h" 27#include "lf.h" 28#include "filter.h" 29 30struct _filter 31{ 32 char *member; 33 filter *next; 34}; 35 36 37void 38filter_parse (filter **filters, const char *filt) 39{ 40 while (strlen (filt) > 0) 41 { 42 filter *new_filter; 43 filter **last; 44 /* break out a member of the filter list */ 45 const char *flag = filt; 46 unsigned /*size_t */ len; 47 filt = strchr (filt, ','); 48 if (filt == NULL) 49 { 50 filt = strchr (flag, '\0'); 51 len = strlen (flag); 52 } 53 else 54 { 55 len = filt - flag; 56 filt = filt + 1; 57 } 58 /* find an insertion point - sorted order */ 59 last = filters; 60 while (*last != NULL && strncmp (flag, (*last)->member, len) > 0) 61 last = &(*last)->next; 62 if (*last != NULL 63 && strncmp (flag, (*last)->member, len) == 0 64 && strlen ((*last)->member) == len) 65 continue; /* duplicate */ 66 /* create an entry for that member */ 67 new_filter = ZALLOC (filter); 68 new_filter->member = NZALLOC (char, len + 1); 69 strncpy (new_filter->member, flag, len); 70 /* insert it */ 71 new_filter->next = *last; 72 *last = new_filter; 73 } 74} 75 76 77void 78filter_add (filter **set, const filter *add) 79{ 80 while (add != NULL) 81 { 82 int cmp; 83 if (*set == NULL) 84 cmp = 1; /* set->member > add->member */ 85 else 86 cmp = strcmp ((*set)->member, add->member); 87 if (cmp > 0) 88 { 89 /* insert it here */ 90 filter *new = ZALLOC (filter); 91 new->member = NZALLOC (char, strlen (add->member) + 1); 92 strcpy (new->member, add->member); 93 new->next = *set; 94 *set = new; 95 add = add->next; 96 } 97 else if (cmp == 0) 98 { 99 /* already in set */ 100 add = add->next; 101 } 102 else /* cmp < 0 */ 103 { 104 /* not reached insertion point */ 105 set = &(*set)->next; 106 } 107 } 108} 109 110 111int 112filter_is_subset (const filter *superset, const filter *subset) 113{ 114 while (1) 115 { 116 int cmp; 117 if (subset == NULL) 118 return 1; 119 if (superset == NULL) 120 return 0; /* subset isn't finished */ 121 cmp = strcmp (subset->member, superset->member); 122 if (cmp < 0) 123 return 0; /* not found */ 124 else if (cmp == 0) 125 subset = subset->next; /* found */ 126 else if (cmp > 0) 127 superset = superset->next; /* later in list? */ 128 } 129} 130 131 132int 133filter_is_common (const filter *l, const filter *r) 134{ 135 while (1) 136 { 137 int cmp; 138 if (l == NULL) 139 return 0; 140 if (r == NULL) 141 return 0; 142 cmp = strcmp (l->member, r->member); 143 if (cmp < 0) 144 l = l->next; 145 else if (cmp == 0) 146 return 1; /* common member */ 147 else if (cmp > 0) 148 r = r->next; 149 } 150} 151 152 153int 154filter_is_member (const filter *filt, const char *flag) 155{ 156 int index = 1; 157 while (filt != NULL) 158 { 159 if (strcmp (flag, filt->member) == 0) 160 return index; 161 filt = filt->next; 162 index++; 163 } 164 return 0; 165} 166 167 168int 169is_filtered_out (const filter *filters, const char *flags) 170{ 171 while (strlen (flags) > 0) 172 { 173 int present; 174 const filter *filt = filters; 175 /* break the string up */ 176 const char *end = strchr (flags, ','); 177 const char *next; 178 unsigned /*size_t */ len; 179 if (end == NULL) 180 { 181 end = strchr (flags, '\0'); 182 next = end; 183 } 184 else 185 { 186 next = end + 1; 187 } 188 len = end - flags; 189 /* check that it is present */ 190 present = 0; 191 filt = filters; 192 while (filt != NULL) 193 { 194 if (strncmp (flags, filt->member, len) == 0 195 && strlen (filt->member) == len) 196 { 197 present = 1; 198 break; 199 } 200 filt = filt->next; 201 } 202 if (!present) 203 return 1; 204 flags = next; 205 } 206 return 0; 207} 208 209 210const char * 211filter_next (const filter *set, const char *member) 212{ 213 while (set != NULL) 214 { 215 if (strcmp (set->member, member) > 0) 216 return set->member; 217 set = set->next; 218 } 219 return NULL; 220} 221 222 223void 224dump_filter (lf *file, 225 const char *prefix, 226 const filter *set, 227 const char *suffix) 228{ 229 const char *member; 230 lf_printf (file, "%s", prefix); 231 member = filter_next (set, ""); 232 if (member != NULL) 233 { 234 while (1) 235 { 236 lf_printf (file, "%s", member); 237 member = filter_next (set, member); 238 if (member == NULL) 239 break; 240 lf_printf (file, ","); 241 } 242 } 243 lf_printf (file, "%s", suffix); 244} 245 246 247#ifdef MAIN 248int 249main (int argc, char **argv) 250{ 251 filter *subset = NULL; 252 filter *superset = NULL; 253 lf *l; 254 int i; 255 if (argc < 2) 256 { 257 printf ("Usage: filter <subset> <filter> ...\n"); 258 exit (1); 259 } 260 261 /* load the filter up */ 262 filter_parse (&subset, argv[1]); 263 for (i = 2; i < argc; i++) 264 filter_parse (&superset, argv[i]); 265 266 /* dump various info */ 267 l = lf_open ("-", "stdout", lf_omit_references, lf_is_text, "tmp-filter"); 268 269 /* subset */ 270 { 271 dump_filter (l, "{", subset, " }"); 272 if (filter_is_subset (superset, subset)) 273 lf_printf (l, " subset of "); 274 else 275 lf_printf (l, " !subset of "); 276 dump_filter (l, "{", superset, " }"); 277 lf_printf (l, "\n"); 278 } 279 /* intersection */ 280 { 281 dump_filter (l, "{", subset, " }"); 282 if (filter_is_common (subset, superset)) 283 lf_printf (l, " intersects "); 284 else 285 lf_printf (l, " !intersects "); 286 dump_filter (l, "{", superset, " }"); 287 lf_printf (l, "\n"); 288 } 289 /* membership */ 290 { 291 filter *memb = subset; 292 while (memb != NULL) 293 { 294 lf_printf (l, "%s", memb->member); 295 if (filter_is_member (superset, memb->member)) 296 lf_printf (l, " in "); 297 else 298 lf_printf (l, " !in "); 299 dump_filter (l, "{", superset, " }"); 300 lf_printf (l, "\n"); 301 memb = memb->next; 302 } 303 } 304 /* addition */ 305 { 306 filter *add = NULL; 307 filter_add (&add, superset); 308 filter_add (&add, subset); 309 dump_filter (l, "{", add, " }"); 310 lf_printf (l, " = "); 311 dump_filter (l, "{", subset, " }"); 312 lf_printf (l, " + "); 313 dump_filter (l, "{", superset, " }"); 314 lf_printf (l, "\n"); 315 } 316 317 return 0; 318} 319#endif 320