- char *cstring;
- char buffer[CSTRING_BUFFER_LENGTH];
- int target = CSTRING_BUFFER_LENGTH * depth;
- int i, len;
- int size;
-
- /* fill buffer */
- i = 0;
- while ((buffer[i] = fgetc(f)) != EOF) {
- if (buffer[i++] == 0x0a) { break; }
- if (i == CSTRING_BUFFER_LENGTH) { break; }
- }
- len = i;
-
- /* recurse or malloc? */
- if (len == CSTRING_BUFFER_LENGTH) {
- cstring = cstring_alloc(f, (depth + 1));
- } else {
- /* [special case] EOF */
- if ((depth | len) == 0) { return NULL; }
-
- /* malloc */
- size = target + len + 1;
- cstring = malloc(size);
- if (!cstring) { return NULL; }
- cstring[size - 1] = 0;
- }
-
- /* copy buffer */
- if (cstring) {
- memcpy(&cstring[target], buffer, len);
- }
- return cstring;
+ static const int GROWBY = 80; /* how large we will grow strings by */
+
+ int ch;
+ int idx = 0;
+ char *linebuf = NULL;
+ int linebufsz = 0;
+
+ while (1) {
+ ch = fgetc(file);
+ if (ch == EOF)
+ break;
+ /* grow the line buffer as necessary */
+ if (idx > linebufsz-2)
+ linebuf = realloc(linebuf, linebufsz += GROWBY);
+ linebuf[idx++] = (char)ch;
+ if ((char)ch == '\n')
+ break;
+ }
+
+ if (idx == 0)
+ return NULL;
+
+ linebuf[idx] = 0;
+ return linebuf;
+}
+
+#if defined BB_ECHO || defined BB_TR
+char process_escape_sequence(char **ptr)
+{
+ char c;
+
+ switch (c = *(*ptr)++) {
+ case 'a':
+ c = '\a';
+ break;
+ case 'b':
+ c = '\b';
+ break;
+ case 'f':
+ c = '\f';
+ break;
+ case 'n':
+ c = '\n';
+ break;
+ case 't':
+ c = '\t';
+ break;
+ case 'v':
+ c = '\v';
+ break;
+ case '\\':
+ c = '\\';
+ break;
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ c -= '0';
+ if ('0' <= **ptr && **ptr <= '7') {
+ c = c * 8 + (*(*ptr)++ - '0');
+ if ('0' <= **ptr && **ptr <= '7')
+ c = c * 8 + (*(*ptr)++ - '0');
+ }
+ break;
+ default:
+ (*ptr)--;
+ c = '\\';
+ break;
+ }
+ return c;
+}
+#endif
+
+#if defined BB_BASENAME || defined BB_LN
+char *get_last_path_component(char *path)
+{
+ char *s=path+strlen(path)-1;
+
+ /* strip trailing slashes */
+ while (s && *s == '/') {
+ *s-- = '\0';
+ }
+
+ /* find last component */
+ s = strrchr(path, '/');
+ if (s==NULL) return path;
+ else return s+1;