157700Sbostic /*-
2*60663Sbostic * Copyright (c) 1992, 1993
3*60663Sbostic * The Regents of the University of California. All rights reserved.
457700Sbostic *
557700Sbostic * This code is derived from software contributed to Berkeley by
657700Sbostic * Rodney Ruddock of the University of Guelph.
757700Sbostic *
857700Sbostic * %sccs.include.redist.c%
957700Sbostic */
1057700Sbostic
1157700Sbostic #ifndef lint
12*60663Sbostic static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 05/31/93";
1357700Sbostic #endif /* not lint */
1457700Sbostic
1557710Sbostic #include <sys/types.h>
1657710Sbostic
1757710Sbostic #include <regex.h>
1857710Sbostic #include <setjmp.h>
1957710Sbostic #include <stdio.h>
2057710Sbostic #include <stdlib.h>
2157710Sbostic #include <string.h>
2257710Sbostic
2358315Sbostic #ifdef DBI
2458315Sbostic #include <db.h>
2558315Sbostic #endif
2658315Sbostic
2757700Sbostic #include "ed.h"
2857710Sbostic #include "extern.h"
2957700Sbostic
3057700Sbostic /*
3157700Sbostic * searches forward through the buffer (wrapping if necessary) for a
3257700Sbostic * line that contains a match to the RE.
3357700Sbostic */
3457700Sbostic
3557710Sbostic LINE *
search(inputt,errnum)3657710Sbostic search(inputt, errnum)
3757710Sbostic FILE *inputt;
3857710Sbostic int *errnum;
3957710Sbostic {
4057710Sbostic LINE *l_temp;
4157710Sbostic int l_err;
4257710Sbostic char *l_patt;
4357700Sbostic
4458315Sbostic if (current)
4558315Sbostic l_temp = current->below;
4658315Sbostic else {
4758315Sbostic *errnum = -1;
4858315Sbostic ungetc(ss, inputt);
4958315Sbostic strcpy(help_msg, "buffer empty");
5058315Sbostic return(NULL);
5158315Sbostic }
5257710Sbostic /* Get the RE. */
5357710Sbostic l_patt = get_pattern(ss, inputt, errnum, 0);
5457710Sbostic if (*errnum < -1)
5557710Sbostic return (NULL);
5657710Sbostic *errnum = 0;
5757710Sbostic if ((RE_flag == 0) && (l_patt[1] == '\0')) {
5857710Sbostic *errnum = -1;
5957710Sbostic ungetc(ss, inputt);
6057710Sbostic return (NULL);
6157710Sbostic } else
6257710Sbostic if (l_patt[1] || (RE_patt == NULL)) {
6358315Sbostic sigspecial++;
6457710Sbostic free(RE_patt);
6557710Sbostic RE_patt = l_patt;
6658315Sbostic sigspecial--;
6758315Sbostic if (sigint_flag && (!sigspecial))
6858315Sbostic SIGINT_ACTION;
6957710Sbostic }
7057710Sbostic RE_sol = (RE_patt[1] == '^') ? 1 : 0;
7157700Sbostic
7257710Sbostic /* Compile it up. */
7357710Sbostic if ((l_patt[1]) &&
7457710Sbostic (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) {
7557710Sbostic regerror(l_err, &RE_comp, help_msg, 128);
7657710Sbostic *errnum = -1;
7757710Sbostic RE_flag = 0;
7857710Sbostic ungetc(ss, inputt);
7957710Sbostic return (NULL);
8057710Sbostic }
8157710Sbostic RE_flag = 1;
8257700Sbostic
8357710Sbostic /* Find a line that has the RE in it. */
8457710Sbostic for (;;) { /* (l_temp != current) */
8557710Sbostic if (l_temp == NULL) {
8657710Sbostic if (top != NULL)
8757710Sbostic l_temp = top;
8857710Sbostic else
8957710Sbostic break;
9057710Sbostic }
9157710Sbostic get_line(l_temp->handle, l_temp->len);
9258315Sbostic if (sigint_flag && (!sigspecial))
9358315Sbostic SIGINT_ACTION;
9457710Sbostic if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) {
9557710Sbostic l_temp = l_temp->below;
9657710Sbostic if (l_temp == (current->below))
9757710Sbostic break;
9857710Sbostic } else {
9957710Sbostic *errnum = 0;
10057710Sbostic return (l_temp);
10157710Sbostic }
10257710Sbostic }
10357710Sbostic strcpy(help_msg, "RE not found");
10457710Sbostic *errnum = -1;
10557710Sbostic return (NULL);
10657710Sbostic }
10757700Sbostic
10857700Sbostic /*
10957700Sbostic * Searches backward through the buffer (wrapping if necessary) to find
11057700Sbostic * a line that contains a match to the RE.
11157700Sbostic */
11257710Sbostic LINE *
search_r(inputt,errnum)11357710Sbostic search_r(inputt, errnum)
11457710Sbostic FILE *inputt;
11557710Sbostic int *errnum;
11657710Sbostic {
11757710Sbostic LINE *l_temp;
11857710Sbostic int l_err;
11957710Sbostic char *l_patt;
12057700Sbostic
12158315Sbostic if (current)
12258315Sbostic l_temp = current->above;
12358315Sbostic else {
12458315Sbostic *errnum = -1;
12558315Sbostic ungetc(ss, inputt);
12658315Sbostic strcpy(help_msg, "buffer empty");
12758315Sbostic return(NULL);
12858315Sbostic }
12957700Sbostic
13057710Sbostic /* Get the RE. */
13157710Sbostic l_patt = get_pattern(ss, inputt, errnum, 0);
13257710Sbostic if (*errnum < -1)
13357710Sbostic return (NULL);
13457710Sbostic *errnum = 0;
13557710Sbostic if ((RE_flag == 0) && (l_patt[1] == '\0')) {
13657710Sbostic *errnum = -1;
13757710Sbostic ungetc(ss, inputt);
13857710Sbostic return (NULL);
13957710Sbostic } else
14057710Sbostic if (l_patt[1] || (RE_patt == NULL)) {
14158315Sbostic sigspecial++;
14257710Sbostic free(RE_patt);
14357710Sbostic RE_patt = l_patt;
14458315Sbostic sigspecial--;
14558315Sbostic if (sigint_flag && (!sigspecial))
14658315Sbostic SIGINT_ACTION;
14757710Sbostic }
14857710Sbostic RE_sol = (RE_patt[1] == '^') ? 1 : 0;
14957700Sbostic
15057710Sbostic /* Compile up the RE. */
15157710Sbostic if ((l_patt[1]) &&
15257710Sbostic (regfree(&RE_comp), l_err = regcomp(&RE_comp, &RE_patt[1], 0))) {
15357710Sbostic regerror(l_err, &RE_comp, help_msg, 128);
15457710Sbostic *errnum = -1;
15557710Sbostic RE_flag = 0;
15657710Sbostic ungetc(ss, inputt);
15757710Sbostic return (NULL);
15857710Sbostic }
15957710Sbostic RE_flag = 1;
16057700Sbostic
16157710Sbostic /* Search for a line that has the RE in it. */
16257710Sbostic for (;;) { /* (l_temp != (current->above)) */
16357710Sbostic if (l_temp == NULL) {
16457710Sbostic if (bottom != NULL)
16557710Sbostic l_temp = bottom;
16657710Sbostic else
16757710Sbostic break;
16857710Sbostic }
16957710Sbostic get_line(l_temp->handle, l_temp->len);
17058315Sbostic if (sigint_flag && (!sigspecial))
17158315Sbostic SIGINT_ACTION;
17257710Sbostic if (regexec(&RE_comp, text, (size_t) RE_SEC, RE_match, 0)) {
17357710Sbostic l_temp = l_temp->above;
17457710Sbostic if (l_temp == (current->above))
17557710Sbostic break;
17657710Sbostic } else {
17757710Sbostic *errnum = 0;
17857710Sbostic return (l_temp);
17957710Sbostic }
18057710Sbostic }
18157710Sbostic strcpy(help_msg, "RE not found");
18257710Sbostic *errnum = -1;
18357710Sbostic return (NULL);
18457710Sbostic }
185