/************************************************************************* * This function is the GKlib implementation of glibc's getline() * function. **************************************************************************/ gk_loop_t gk_getline(char **lineptr, size_t *n, FILE *stream) { size_t i; int ch; if (feof(stream)) return -1; /* Initial memory allocation if *lineptr is NULL */ if (*lineptr == NULL || *n == 0) { *n = 1024; *lineptr = gk_malloc((*n)*sizeof(char), "gk_getline: lineptr"); } /* get into the main loop */ for (i = 0; (ch = getc(stream)) != EOF; i++) { (*lineptr)[i] = (char)ch; /* reallocate memory if reached at the end of the buffer. The +2 is for '\0' */ if (i+2 == *n) { *n = 2* (*n); *lineptr = gk_realloc(*lineptr, (*n)*sizeof(char), "gk_getline: lineptr"); } if (ch == '\n') break; } (*lineptr)[i+1] = '\0'; return i; }
idx_t vnbrpoolGetNext(ctrl_t *ctrl, idx_t nnbrs) { ctrl->nbrpoolcpos += nnbrs; if (ctrl->nbrpoolcpos > ctrl->nbrpoolsize) { ctrl->nbrpoolsize += gk_max(10 * nnbrs, ctrl->nbrpoolsize / 2); ctrl->vnbrpool = (vnbr_t *) gk_realloc(ctrl->vnbrpool, ctrl->nbrpoolsize * sizeof(vnbr_t), "vnbrpoolGet: vnbrpool"); ctrl->nbrpoolreallocs++; } return ctrl->nbrpoolcpos - nnbrs; }
gk_idx_t gk_getline(char **lineptr, size_t *n, FILE *stream) { #ifdef HAVE_GETLINE return getline(lineptr, n, stream); #else size_t i; int ch; if (feof(stream)) return -1; /* Initial memory allocation if *lineptr is NULL */ if (*lineptr == NULL || *n == 0) { *n = 1024; *lineptr = gk_malloc((*n)*sizeof(char), "gk_getline: lineptr"); } /* get into the main loop */ i = 0; while ((ch = getc(stream)) != EOF) { (*lineptr)[i++] = (char)ch; /* reallocate memory if reached at the end of the buffer. The +1 is for '\0' */ if (i+1 == *n) { *n = 2*(*n); *lineptr = gk_realloc(*lineptr, (*n)*sizeof(char), "gk_getline: lineptr"); } if (ch == '\n') break; } (*lineptr)[i] = '\0'; return (i == 0 ? -1 : i); #endif }
int gk_strstr_replace(char *str, char *pattern, char *replacement, char *options, char **new_str) { gk_idx_t i; int j, rc, flags, global, nmatches; size_t len, rlen, nlen, offset, noffset; regex_t re; regmatch_t matches[10]; /* Parse the options */ flags = REG_EXTENDED; if (strchr(options, 'i') != NULL) flags = flags | REG_ICASE; global = (strchr(options, 'g') != NULL ? 1 : 0); /* Compile the regex */ if ((rc = regcomp(&re, pattern, flags)) != 0) { len = regerror(rc, &re, NULL, 0); *new_str = gk_cmalloc(len, "gk_strstr_replace: new_str"); regerror(rc, &re, *new_str, len); return 0; } /* Prepare the output string */ len = strlen(str); nlen = 2*len; noffset = 0; *new_str = gk_cmalloc(nlen+1, "gk_strstr_replace: new_str"); /* Get into the matching-replacing loop */ rlen = strlen(replacement); offset = 0; nmatches = 0; do { rc = regexec(&re, str+offset, 10, matches, 0); if (rc == REG_ESPACE) { gk_free((void **)new_str, LTERM); *new_str = gk_strdup("regexec ran out of memory."); regfree(&re); return 0; } else if (rc == REG_NOMATCH) { if (nlen-noffset < len-offset) { nlen += (len-offset) - (nlen-noffset); *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } strcpy(*new_str+noffset, str+offset); noffset += (len-offset); break; } else { /* A match was found! */ nmatches++; /* Copy the left unmatched portion of the string */ if (matches[0].rm_so > 0) { if (nlen-noffset < matches[0].rm_so) { nlen += matches[0].rm_so - (nlen-noffset); *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } strncpy(*new_str+noffset, str+offset, matches[0].rm_so); noffset += matches[0].rm_so; } /* Go and append the replacement string */ for (i=0; i<rlen; i++) { switch (replacement[i]) { case '\\': if (i+1 < rlen) { if (nlen-noffset < 1) { nlen += nlen + 1; *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } *new_str[noffset++] = replacement[++i]; } else { gk_free((void **)new_str, LTERM); *new_str = gk_strdup("Error in replacement string. Missing character following '\'."); regfree(&re); return 0; } break; case '$': if (i+1 < rlen) { j = (int)(replacement[++i] - '0'); if (j < 0 || j > 9) { gk_free((void **)new_str, LTERM); *new_str = gk_strdup("Error in captured subexpression specification."); regfree(&re); return 0; } if (nlen-noffset < matches[j].rm_eo-matches[j].rm_so) { nlen += nlen + (matches[j].rm_eo-matches[j].rm_so); *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } strncpy(*new_str+noffset, str+offset+matches[j].rm_so, matches[j].rm_eo); noffset += matches[j].rm_eo-matches[j].rm_so; } else { gk_free((void **)new_str, LTERM); *new_str = gk_strdup("Error in replacement string. Missing subexpression number folloing '$'."); regfree(&re); return 0; } break; default: if (nlen-noffset < 1) { nlen += nlen + 1; *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } (*new_str)[noffset++] = replacement[i]; } } /* Update the offset of str for the next match */ offset += matches[0].rm_eo; if (!global) { /* Copy the right portion of the string if no 'g' option */ if (nlen-noffset < len-offset) { nlen += (len-offset) - (nlen-noffset); *new_str = (char *)gk_realloc(*new_str, (nlen+1)*sizeof(char), "gk_strstr_replace: new_str"); } strcpy(*new_str+noffset, str+offset); noffset += (len-offset); } } } while (global); (*new_str)[noffset] = '\0'; regfree(&re); return nmatches + 1; }