Example #1
0
File: rcfile.c Project: ris21/yoda
/* Parse the header-line regexes that may influence the choice of syntax. */
void parse_header_exp(char *ptr)
{
    regexlisttype *endheader = NULL;

    assert(ptr != NULL);

    if (syntaxes == NULL) {
	rcfile_error(
		N_("Cannot add a header regex without a syntax command"));
	return;
    }

    if (*ptr == '\0') {
	rcfile_error(N_("Missing regex string"));
	return;
    }

    while (*ptr != '\0') {
	const char *regexstring;
	regexlisttype *newheader;

	if (*ptr != '"') {
	    rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	    ptr = parse_next_regex(ptr);
	    continue;
	}

	ptr++;

	regexstring = ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    break;

	newheader = (regexlisttype *)nmalloc(sizeof(regexlisttype));

	/* Save the regex string if it's valid. */
	if (nregcomp(regexstring, 0)) {
	    newheader->ext_regex = mallocstrcpy(NULL, regexstring);
	    newheader->ext = NULL;

	    if (endheader == NULL)
		endsyntax->headers = newheader;
	    else
		endheader->next = newheader;
	    endheader = newheader;
	    endheader->next = NULL;
	} else
	    free(newheader);
    }
}
Example #2
0
/* Parse the headers (1st line) of the file which may influence the regex used. */
void parse_headers(char *ptr)
{
    char *regstr;

    assert(ptr != NULL);

    if (syntaxes == NULL) {
	rcfile_error(
		N_("Cannot add a header regex without a syntax command"));
	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') {
	exttype *newheader;
	    /* The new color structure. */

	if (*ptr != '"') {
	    rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	    ptr = parse_next_regex(ptr);
	    continue;
	}

	ptr++;

	regstr = ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    break;

	newheader = (exttype *)nmalloc(sizeof(exttype));

	/* Save the regex string if it's valid */
	if (nregcomp(regstr, 0)) {
	    newheader->ext_regex = mallocstrcpy(NULL, regstr);
	    newheader->ext = NULL;
	    newheader->next = NULL;

#ifdef DEBUG
	     fprintf(stderr, "Starting a new header entry: %s\n", newheader->ext_regex);
#endif

	    if (endheader == NULL) {
		endsyntax->headers = newheader;
	    } else {
		endheader->next = newheader;
	    }

	    endheader = newheader;
	} else
	    free(newheader);

    }
}
Example #3
0
/* 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, no_fgcolor = 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 (strchr(fgstr, ',') != NULL) {
	char *bgcolorname;

	strtok(fgstr, ",");
	bgcolorname = strtok(NULL, ",");
	if (bgcolorname == NULL) {
	    /* If we have a background color without a foreground color,
	     * parse it properly. */
	    bgcolorname = fgstr + 1;
	    no_fgcolor = TRUE;
	}
	if (strncasecmp(bgcolorname, "bright", 6) == 0) {
	    rcfile_error(
		N_("Background color \"%s\" cannot be bright"),
		bgcolorname);
	    return;
	}
	bg = color_to_short(bgcolorname, &bright);
    } else
	bg = -1;

    if (!no_fgcolor) {
	fg = color_to_short(fgstr, &bright);

	/* Don't try to parse screwed-up foreground colors. */
	if (fg == -1)
	    return;
    } else
	fg = -1;

    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 new color structure. */
	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
		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++;
	}
    }
}
Example #4
0
/* Parse the next syntax string from the line at ptr, and add it to the
 * global list of color syntaxes. */
void parse_syntax(char *ptr)
{
    const char *fileregptr = NULL, *nameptr = NULL;
    syntaxtype *tmpsyntax;
    exttype *endext = NULL;
	/* The end of the extensions list for this syntax. */

    assert(ptr != NULL);

    if (*ptr == '\0') {
	rcfile_error(N_("Missing syntax name"));
	return;
    }

    if (*ptr != '"') {
	rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	return;
    }

    ptr++;

    nameptr = ptr;
    ptr = parse_next_regex(ptr);

    if (ptr == NULL)
	return;

    /* Search for a duplicate syntax name.  If we find one, free it, so
     * that we always use the last syntax with a given name. */
    for (tmpsyntax = syntaxes; tmpsyntax != NULL;
	tmpsyntax = tmpsyntax->next) {
	if (strcmp(nameptr, tmpsyntax->desc) == 0) {
	    syntaxtype *prev_syntax = tmpsyntax;

	    tmpsyntax = tmpsyntax->next;
	    free(prev_syntax);
	    break;
	}
    }

    if (syntaxes == NULL) {
	syntaxes = (syntaxtype *)nmalloc(sizeof(syntaxtype));
	endsyntax = syntaxes;
    } else {
	endsyntax->next = (syntaxtype *)nmalloc(sizeof(syntaxtype));
	endsyntax = endsyntax->next;
#ifdef DEBUG
	fprintf(stderr, "Adding new syntax after first one\n");
#endif
    }

    endsyntax->desc = mallocstrcpy(NULL, nameptr);
    endsyntax->color = NULL;
    endcolor = NULL;
    endheader = NULL;
    endsyntax->extensions = NULL;
    endsyntax->headers = NULL;
    endsyntax->next = NULL;
    endsyntax->nmultis = 0;

#ifdef DEBUG
    fprintf(stderr, "Starting a new syntax type: \"%s\"\n", nameptr);
#endif

    /* The "none" syntax is the same as not having a syntax at all, so
     * we can't assign any extensions or colors to it. */
    if (strcmp(endsyntax->desc, "none") == 0) {
	rcfile_error(N_("The \"none\" syntax is reserved"));
	return;
    }

    /* The default syntax should have no associated extensions. */
    if (strcmp(endsyntax->desc, "default") == 0 && *ptr != '\0') {
	rcfile_error(
		N_("The \"default\" syntax must take no extensions"));
	return;
    }

    /* Now load the extensions into their part of the struct. */
    while (*ptr != '\0') {
	exttype *newext;
	    /* The new extension structure. */

	while (*ptr != '"' && *ptr != '\0')
	    ptr++;

	if (*ptr == '\0')
	    return;

	ptr++;

	fileregptr = ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    break;

	newext = (exttype *)nmalloc(sizeof(exttype));

	/* Save the extension regex if it's valid. */
	if (nregcomp(fileregptr, REG_NOSUB)) {
	    newext->ext_regex = mallocstrcpy(NULL, fileregptr);
	    newext->ext = NULL;

	    if (endext == NULL)
		endsyntax->extensions = newext;
	    else
		endext->next = newext;
	    endext = newext;
	    endext->next = NULL;
	} else
	    free(newext);
    }
}
Example #5
0
File: rcfile.c Project: rofl0r/nano
/* Parse the next syntax string from the line at ptr, and add it to the
 * global list of color syntaxes. */
void parse_magictype(char *ptr)
{
#ifdef HAVE_LIBMAGIC
    const char *fileregptr = NULL;
    exttype *endext = NULL;

    assert(ptr != NULL);

    if (syntaxes == NULL) {
	rcfile_error(
		N_("Cannot add a magic string regex without a syntax command"));
	return;
    }

    if (*ptr == '\0') {
	rcfile_error(N_("Missing magic string name"));
	return;
    }

    if (*ptr != '"') {
	rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	return;
    }

#ifdef DEBUG
    fprintf(stderr, "Starting a magic type: \"%s\"\n", ptr);
#endif

    /* Now load the extensions into their part of the struct. */
    while (*ptr != '\0') {
	exttype *newext;
	    /* The new extension structure. */

	while (*ptr != '"' && *ptr != '\0')
	    ptr++;

	if (*ptr == '\0')
	    return;

	ptr++;

	fileregptr = ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    break;

	newext = (exttype *)nmalloc(sizeof(exttype));

	/* Save the regex if it's valid. */
	if (nregcomp(fileregptr, REG_NOSUB)) {
	    newext->ext_regex = mallocstrcpy(NULL, fileregptr);
	    newext->ext = NULL;

	    if (endext == NULL)
		endsyntax->magics = newext;
	    else
		endext->next = newext;
	    endext = newext;
	    endext->next = NULL;
	} else
	    free(newext);
    }
#endif /* HAVE_LIBMAGIC */
}
Example #6
0
File: rcfile.c Project: ris21/yoda
/* Parse the magic regexes that may influence the choice of syntax. */
void parse_magic_exp(char *ptr)
{
    regexlisttype *endmagic = NULL;

    assert(ptr != NULL);

    if (syntaxes == NULL) {
	rcfile_error(
		N_("Cannot add a magic string regex without a syntax command"));
	return;
    }

    if (*ptr == '\0') {
	rcfile_error(N_("Missing magic string name"));
	return;
    }

    if (*ptr != '"') {
	rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	return;
    }

#ifdef DEBUG
    fprintf(stderr, "Starting a magic type: \"%s\"\n", ptr);
#endif

    /* Now load the magic regexes into their part of the struct. */
    while (*ptr != '\0') {
	const char *regexstring;
	regexlisttype *newmagic;

	while (*ptr != '"' && *ptr != '\0')
	    ptr++;

	if (*ptr == '\0')
	    return;

	ptr++;

	regexstring = ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    break;

	newmagic = (regexlisttype *)nmalloc(sizeof(regexlisttype));

	/* Save the regex string if it's valid. */
	if (nregcomp(regexstring, REG_NOSUB)) {
	    newmagic->ext_regex = mallocstrcpy(NULL, regexstring);
	    newmagic->ext = NULL;

	    if (endmagic == NULL)
		endsyntax->magics = newmagic;
	    else
		endmagic->next = newmagic;
	    endmagic = newmagic;
	    endmagic->next = NULL;
	} else
	    free(newmagic);
    }
}
Example #7
0
File: rcfile.c Project: ris21/yoda
/* 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++;
	}
    }
}
Example #8
0
/* Read regex strings enclosed in double quotes from the line pointed at
 * by ptr, and store them quoteless in the passed storage place. */
void grab_and_store(const char *kind, char *ptr, regexlisttype **storage)
{
    regexlisttype *lastthing;

    if (!opensyntax) {
	rcfile_error(
		N_("A '%s' command requires a preceding 'syntax' command"), kind);
	return;
    }

    /* The default syntax doesn't take any file matching stuff. */
    if (strcmp(live_syntax->name, "default") == 0 && *ptr != '\0') {
	rcfile_error(
		N_("The \"default\" syntax does not accept '%s' regexes"), kind);
	return;
    }

    if (*ptr == '\0') {
	rcfile_error(N_("Missing regex string after '%s' command"), kind);
	return;
    }

    lastthing = *storage;

    /* If there was an earlier command, go to the last of those regexes. */
    while (lastthing != NULL && lastthing->next != NULL)
	lastthing = lastthing->next;

    /* Now gather any valid regexes and add them to the linked list. */
    while (*ptr != '\0') {
	const char *regexstring;
	regexlisttype *newthing;

	if (*ptr != '"') {
	    rcfile_error(
		N_("Regex strings must begin and end with a \" character"));
	    return;
	}

	regexstring = ++ptr;
	ptr = parse_next_regex(ptr);
	if (ptr == NULL)
	    return;

	/* If the regex string is malformed, skip it. */
	if (!nregcomp(regexstring, NANO_REG_EXTENDED | REG_NOSUB))
	    continue;

	/* Copy the regex into a struct, and hook this in at the end. */
	newthing = (regexlisttype *)nmalloc(sizeof(regexlisttype));
	newthing->full_regex = mallocstrcpy(NULL, regexstring);
	newthing->next = NULL;

	if (lastthing == NULL)
	    *storage = newthing;
	else
	    lastthing->next = newthing;

	lastthing = newthing;
    }
}
Example #9
0
/* 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++;
    }
}