--- rc_script.c 2002/07/02 18:03:17 1.4
+++ rc_script.c 2002/07/04 16:49:58 1.5
@@ -103,12 +103,17 @@
char *scriptSection(rc_script_t *pScript, const char *kszSecname)
{
char *szTempout = NULL;
- char *szTmpsec = NULL;
+ char *piLabstart = NULL;
+ char *piLabend = NULL;
char *piStart = NULL;
char *piEnd = NULL;
int nOffset = 0;
+ int nFound = 0;
+ int nVecsize = 0;
+ int nSubstrings = 0;
+ int *pnVec = NULL;
const int kiRegopt = 0;
- const char *szErr = NULL;
+ const char *kszErr = NULL;
pcre *pRegex = NULL; /* Perl Compatible Regular Expression */
pcre_extra *pExtra = NULL; /* Used for studying an expression */
@@ -119,29 +124,61 @@
if (!kszSecname) /* If we get a NULL section label, give a NULL result */
return (NULL); /* This might be useful in some loop constructs */
- if ((pRegex = pcre_compile(configGetval(RC_DEF_VAL), kiRegopt, &szErr, &nOffset, NULL)) == NULL) {
+ if ((pRegex = pcre_compile(configGetval(RC_DEF_VAL), kiRegopt, &kszErr, &nOffset, NULL)) == NULL) {
RC_THROW(RC_ERR_SYS);
}
- szTmpsec = malloc(strlen(kszSecname) + sizeof(char));
- strcpy(szTmpsec, "%");
- strcat(szTmpsec, kszSecname);
-
- piStart = strstr(*pScript, szTmpsec); /* Find start of section */
- if (!piStart) /* Short circuit if the */
- return(NULL); /* section was not found */
-
- piStart = strstr(piStart, "\n") + sizeof(char); /* Wrap to next line */
- piEnd = strstr(piStart + sizeof(char), "%"); /* FIXME: Remove hardcoded */
- if (piEnd) {
- szTempout = malloc(piEnd - piStart + sizeof(char));
- strncpy(szTempout, piStart, piEnd - piStart);
- *(szTempout + (piEnd - piStart)) = NULL; /* Terminate outgoing string */
+ pExtra = pcre_study(pRegex, 0, &kszErr); /* Study the FSM */
+ if (kszErr) { /* Variable contains a string reference in case of errors */
+ free(pRegex);
+ RC_THROW(RC_ERR_SYS);
}
- else /* We are operating on the last section of the file */
- szTempout = strdup(piStart); /* FIXME: Can we assume '\0' at EOF? */
- return(szTempout);
+ if (pcre_fullinfo(pRegex, pExtra, PCRE_INFO_CAPTURECOUNT, &nSubstrings))
+ RC_THROW(RC_ERR_SYS);
+
+ /* Use multiples of six, because PCRE needs 2x multiples of three */
+ nVecsize = 6 * (nSubstrings > 0 ? nSubstrings : 1);
+ nVecsize *= RC_GOOD_MEASURE; /* Add redundancy factor for error margin */
+
+ /* Filter the rc file for the section label, do it here the first time */
+ pnVec = calloc(nVecsize, sizeof(int)); /* 2/3 vec 1/3 scrapinfo */
+ nFound = pcre_exec(pRegex, pExtra, *pScript,\
+ strlen(*pScript), 0, 0, pnVec, nVecsize);
+
+ piLabend = *pScript; /* Start piLabstart pointing to the script object */
+ while (nFound > 1) { /* Loop as long as we have more sections */
+ piLabstart = piLabend + *(pnVec + 2 * RC_SEC_SUB); /* Seclabel start */
+ piLabend += *(pnVec + 1); /* Find end of section label */
+
+ /* Test the substring. If it matches our label, generate a subscript */
+ if (!strncmp(piLabstart , kszSecname, sizeof(kszSecname))) {
+ piStart = strstr(piLabend, "\n") + sizeof(char); /* Wrap to start */
+
+ /* See if more sections follow or if this is the last one */
+ if (pcre_exec(pRegex, pExtra, piLabend, strlen(*pScript), 0, 0, pnVec, nVecsize) > 0)
+ piEnd = piLabend + *pnVec;
+ else /* Doch, last section in file */
+ piEnd = piLabend + strlen(*pScript);
+
+ szTempout = malloc(piEnd - piStart + sizeof(char));
+ strncpy(szTempout, piStart, piEnd - piStart);
+ *(szTempout + (piEnd - piStart)) = NULL; /* Terminate outgoing */
+ return(szTempout); /* Section found, so return the text */
+ }
+
+ /* Get ready for the next round of matching */
+ nFound = pcre_exec(pRegex, pExtra, piLabend,\
+ strlen(piLabend), 0, 0, pnVec, nVecsize);
+ }
+
+ /* Under correct conditions, the section subscript was returned in loop */
+ if (nFound == 1) /* User gave no klammern */
+ RC_THROW(RC_ERR_USE); /* so complain about it */
+ else if (nFound < PCRE_ERROR_NOMATCH) /* Generic problem so */
+ RC_THROW(RC_ERR_SYS); /* return an error */
+
+ return(NULL); /* Probably not found */
}
/************************************************
@@ -173,3 +210,4 @@
return(RC_THROW(RC_OK));
}
+
|