/* Parse the color string in the line at ptr, and add it to the current * file's associated colors. If icase is TRUE, treat the color string * as case insensitive. */ void parse_colors(char *ptr, bool icase) { short fg, bg; bool bright = FALSE; char *fgstr; assert(ptr != NULL); if (syntaxes == NULL) { rcfile_error( N_("Cannot add a color command without a syntax command")); return; } if (*ptr == '\0') { rcfile_error(N_("Missing color name")); return; } fgstr = ptr; ptr = parse_next_word(ptr); if (!parse_color_names(fgstr, &fg, &bg, &bright)) return; if (*ptr == '\0') { rcfile_error(N_("Missing regex string")); return; } /* Now for the fun part. Start adding regexes to individual strings * in the colorstrings array, woo! */ while (ptr != NULL && *ptr != '\0') { colortype *newcolor; /* The container for a color plus its regexes. */ bool cancelled = FALSE; /* The start expression was bad. */ bool expectend = FALSE; /* Do we expect an end= line? */ if (strncasecmp(ptr, "start=", 6) == 0) { ptr += 6; expectend = TRUE; } if (*ptr != '"') { rcfile_error( N_("Regex strings must begin and end with a \" character")); ptr = parse_next_regex(ptr); continue; } ptr++; fgstr = ptr; ptr = parse_next_regex(ptr); if (ptr == NULL) break; newcolor = (colortype *)nmalloc(sizeof(colortype)); /* Save the starting regex string if it's valid, and set up the * color information. */ if (nregcomp(fgstr, icase ? REG_ICASE : 0)) { newcolor->fg = fg; newcolor->bg = bg; newcolor->bright = bright; newcolor->icase = icase; newcolor->start_regex = mallocstrcpy(NULL, fgstr); newcolor->start = NULL; newcolor->end_regex = NULL; newcolor->end = NULL; newcolor->next = NULL; if (endcolor == NULL) { endsyntax->color = newcolor; #ifdef DEBUG fprintf(stderr, "Starting a new colorstring for fg %hd, bg %hd\n", fg, bg); #endif } else { #ifdef DEBUG fprintf(stderr, "Adding new entry for fg %hd, bg %hd\n", fg, bg); #endif /* Need to recompute endcolor now so we can extend * colors to syntaxes. */ for (endcolor = endsyntax->color; endcolor->next != NULL; endcolor = endcolor->next) ; endcolor->next = newcolor; } endcolor = newcolor; } else { free(newcolor); cancelled = TRUE; } if (expectend) { if (ptr == NULL || strncasecmp(ptr, "end=", 4) != 0) { rcfile_error( N_("\"start=\" requires a corresponding \"end=\"")); return; } ptr += 4; if (*ptr != '"') { rcfile_error( N_("Regex strings must begin and end with a \" character")); continue; } ptr++; fgstr = ptr; ptr = parse_next_regex(ptr); if (ptr == NULL) break; /* If the start regex was invalid, skip past the end regex * to stay in sync. */ if (cancelled) continue; /* Save the ending regex string if it's valid. */ newcolor->end_regex = (nregcomp(fgstr, icase ? REG_ICASE : 0)) ? mallocstrcpy(NULL, fgstr) : NULL; /* Lame way to skip another static counter. */ newcolor->id = endsyntax->nmultis; endsyntax->nmultis++; } } }
/* Parse the color string in the line at ptr, and add it to the current * file's associated colors. rex_flags are the regex compilation flags * to use, excluding or including REG_ICASE for case (in)sensitivity. */ void parse_colors(char *ptr, int rex_flags) { short fg, bg; bool bright = FALSE; char *fgstr; assert(ptr != NULL); if (!opensyntax) { rcfile_error( N_("A '%s' command requires a preceding 'syntax' command"), "color"); return; } if (*ptr == '\0') { rcfile_error(N_("Missing color name")); return; } fgstr = ptr; ptr = parse_next_word(ptr); if (!parse_color_names(fgstr, &fg, &bg, &bright)) return; if (*ptr == '\0') { rcfile_error(N_("Missing regex string after '%s' command"), "color"); return; } /* Now for the fun part. Start adding regexes to individual strings * in the colorstrings array, woo! */ while (ptr != NULL && *ptr != '\0') { colortype *newcolor = NULL; /* The container for a color plus its regexes. */ bool goodstart; /* Whether the start expression was valid. */ bool expectend = FALSE; /* Whether to expect an end= line. */ if (strncasecmp(ptr, "start=", 6) == 0) { ptr += 6; expectend = TRUE; } if (*ptr != '"') { rcfile_error( N_("Regex strings must begin and end with a \" character")); ptr = parse_next_regex(ptr); continue; } fgstr = ++ptr; ptr = parse_next_regex(ptr); if (ptr == NULL) break; goodstart = nregcomp(fgstr, rex_flags); /* If the starting regex is valid, initialize a new color struct, * and hook it in at the tail of the linked list. */ if (goodstart) { newcolor = (colortype *)nmalloc(sizeof(colortype)); newcolor->fg = fg; newcolor->bg = bg; newcolor->bright = bright; newcolor->rex_flags = rex_flags; newcolor->start_regex = mallocstrcpy(NULL, fgstr); newcolor->start = NULL; newcolor->end_regex = NULL; newcolor->end = NULL; newcolor->next = NULL; #ifdef DEBUG fprintf(stderr, "Adding an entry for fg %hd, bg %hd\n", fg, bg); #endif if (lastcolor == NULL) live_syntax->color = newcolor; else lastcolor->next = newcolor; lastcolor = newcolor; } if (!expectend) continue; if (ptr == NULL || strncasecmp(ptr, "end=", 4) != 0) { rcfile_error(N_("\"start=\" requires a corresponding \"end=\"")); return; } ptr += 4; if (*ptr != '"') { rcfile_error(N_("Regex strings must begin and end with a \" character")); continue; } fgstr = ++ptr; ptr = parse_next_regex(ptr); if (ptr == NULL) break; /* If the start regex was invalid, skip past the end regex * to stay in sync. */ if (!goodstart) continue; /* If it's valid, save the ending regex string. */ if (nregcomp(fgstr, rex_flags)) newcolor->end_regex = mallocstrcpy(NULL, fgstr); /* Lame way to skip another static counter. */ newcolor->id = live_syntax->nmultis; live_syntax->nmultis++; } }