* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Rodney Ruddock of the University of Guelph.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)re.c 5.3 (Berkeley) %G%";
* This finds the n-th occurrence of an RE in a line. If '^' was at the start
* of the RE then look once (in case n=1). There is no standard RE interface
* to do this. Returns 0 for success. NOTE: the #ifdef REG_STARTEND is if
* the regex package has the BSD extensions to it.
regexec_n(reprecomp
, strg
, num_subexp
, reprematch
, flags
, n
, len
, pass
)
regexec_n(reprecomp
, strg
, num_subexp
, reprematch
, flags
, n
, offset
, pass
)
int pass
; /* if pass == 0 .rm_so user set, else set default */
flags
= (flags
| REG_STARTEND
);
reprematch
[0].rm_eo
= len
;
strg
, num_subexp
, reprematch
, flags
) == 0)
reprematch
[0].rm_so
= reprematch
[0].rm_eo
;
reprematch
[0].rm_eo
= len
;
strg
= &strg
[reprematch
[0].rm_eo
];
/* if a "^" started the current RE we only loop once */
*offset
= (size_t) (strg
- l_offset
);
return (0); /* success */
* Replace in the line specified at the found locations with the
* specified replacement. There is no standard RE interface to do
re_replace(line
, num_subexp
, repmatch
, replacer
)
re_replace(line
, num_subexp
, repmatch
, replacer
, offset
)
static char *l_prev_r
= NULL
;
static int l_prev_r_flag
= 0;
regoff_t l_len_before
, l_len_whole
, l_slen
[RE_SEC
];
int l_cnt
, l_len_new
= 0, l_new_rm_eo
= 0;
if (l_prev_r_flag
== 0) {
/* Length of what stays the same before. */
l_len_before
= (repmatch
[0].rm_so
);
l_len_whole
= strlen(line
);
if (num_subexp
> RE_SEC
- 1)
for (l_cnt
= 0; l_cnt
<= num_subexp
; l_cnt
++)
(repmatch
[l_cnt
].rm_eo
) - (repmatch
[l_cnt
].rm_so
);
* l_slen[0] == len of what is to be replaced.
* l_slen[1-9] == len of each backref.
if ((*replacer
== '%') && (replacer
[1] == 1)) {
l_string
= calloc(l_len_whole
- l_slen
[0] +
(strlen(l_prev_r
)) + 2, sizeof(char));
strcpy(help_msg
, "out of memory error");
bcopy(line
, l_string
, (int) l_len_before
);
bcopy(line
, l_string
, (int) l_len_before
+ offset
);
l_string
[l_len_before
] = '\0';
l_string
[l_len_before
+ offset
] = '\0';
strcat(l_string
, l_prev_r
);
strcat(l_string
, &line
[repmatch
[0].rm_eo
]);
strcat(l_string
, &line
[repmatch
[0].rm_eo
+ offset
]);
/* Figure out length of new line first. */
while (*replacer
!= '\0') {
/* Add in the length of the RE match. */
l_len_new
= l_len_new
+ l_slen
[0];
/* Add in the length of a backref. */
else if (*replacer
== '\\') {
(*replacer
< ('9' + 1)) &&
(repmatch
[*replacer
- '0'].rm_so
> -1))
l_len_new
= l_len_new
+ l_slen
[*replacer
- '0'];
/* Create the line of an appropriate length. */
calloc(l_len_whole
- l_slen
[0] + l_len_new
+ 2, sizeof(char));
strcpy(help_msg
, "out of memory error");
l_prev_r
= calloc(l_len_new
+ 2, sizeof(char));
strcpy(help_msg
, "out of memory error");
/* Copy over what doesn't change before the chars to be replaced. */
bcopy(line
, l_string
, (int) l_len_before
);
bcopy(line
, l_string
, l_len_before
+ offset
);
l_string
[l_len_before
] = '\0';
l_string
[l_len_before
+ offset
] = '\0';
/* Make the replacement. */
while (*replacer
!= '\0') {
/* Put what matched the RE into the replacement. */
&line
[repmatch
[0].rm_so
], (int)l_slen
[0]);
&line
[repmatch
[0].rm_so
], (int) l_slen
[0]);
&line
[repmatch
[0].rm_so
+ offset
], (int) l_slen
[0]);
&line
[repmatch
[0].rm_so
+ offset
], (int) l_slen
[0]);
} else if (*replacer
== '\\') {
/* Likely a backref to be included. */
if ((*replacer
> '0') && (*replacer
< ('9' + 1)) &&
(repmatch
[*replacer
- '0'].rm_so
> -1)) {
&line
[repmatch
[*replacer
- '0'].rm_so
],
(int) l_slen
[*replacer
- '0']);
&line
[repmatch
[*replacer
- '0'].rm_so
],
(int) l_slen
[*replacer
- '0']);
&line
[repmatch
[*replacer
- '0'].rm_so
+
offset
], (int) l_slen
[*replacer
- '0']);
&line
[repmatch
[*replacer
- '0'].rm_so
+
offset
], (int) l_slen
[*replacer
- '0']);
/* Put the replacement in. */
strncat(l_string
, replacer
, 1);
strncat(l_prev_r
, replacer
, 1);
/* Put the replacement in. */
strncat(l_string
, replacer
, 1);
strncat(l_prev_r
, replacer
, 1);
l_new_rm_eo
= strlen(l_string
);
/* Copy over what was after the chars to be replaced to the new line. */
strcat(l_string
, &line
[repmatch
[0].rm_eo
]);
strcat(l_string
, &line
[repmatch
[0].rm_eo
+ offset
]);
repmatch
[0].rm_eo
= l_new_rm_eo
; /* Update rm_eo. */
offset
+= l_new_rm_eo
; /* Update offset. */
return (l_string
); /* Return the new line. */