|
|
1.1 ! root 1: # include "buf.h" ! 2: # include <sccs.h> ! 3: ! 4: SCCSID(@(#)buf.c 7.1 2/5/81) ! 5: ! 6: ! 7: /* ! 8: ** BUFFER MANIPULATION ROUTINES ! 9: */ ! 10: ! 11: ! 12: ! 13: /* ! 14: ** BUFPUT -- put character onto buffer ! 15: ** ! 16: ** The character 'c' is put onto the buffer 'bp'. If the buffer ! 17: ** need be extended it is. ! 18: */ ! 19: ! 20: bufput(c, buffer) ! 21: char c; ! 22: struct buf **buffer; ! 23: { ! 24: register struct buf *b; ! 25: register struct buf *a; ! 26: register struct buf **bp; ! 27: char *bufalloc(); ! 28: ! 29: bp = buffer; ! 30: b = *bp; ! 31: if (b == 0 || b->ptr >= &b->buffer[BUFSIZE]) ! 32: { ! 33: /* allocate new buffer segment */ ! 34: a = (struct buf *) bufalloc(sizeof *a); ! 35: a->nextb = b; ! 36: a->ptr = a->buffer; ! 37: *bp = b = a; ! 38: } ! 39: ! 40: *b->ptr++ = c; ! 41: } ! 42: /* ! 43: ** BUFGET -- get character off of buffer ! 44: ** ! 45: ** The buffer is popped and the character is returned. If the ! 46: ** segment is then empty, it is returned to the free list. ! 47: */ ! 48: ! 49: bufget(buffer) ! 50: struct buf **buffer; ! 51: { ! 52: register struct buf *b; ! 53: register char c; ! 54: register struct buf **bp; ! 55: ! 56: bp = buffer; ! 57: b = *bp; ! 58: ! 59: if (b == 0 || b->ptr == b->buffer) ! 60: { ! 61: /* buffer is empty -- return end of file */ ! 62: return (0); ! 63: } ! 64: ! 65: c = *--(b->ptr); ! 66: ! 67: /* check to see if we have emptied the (non-initial) segment */ ! 68: if (b->ptr == b->buffer && b->nextb != 0) ! 69: { ! 70: /* deallocate segment */ ! 71: *bp = b->nextb; ! 72: buffree(b); ! 73: } ! 74: ! 75: return (c); ! 76: } ! 77: /* ! 78: ** BUFPURGE -- return an entire buffer to the free list ! 79: ** ! 80: ** The buffer is emptied and returned to the free list. This ! 81: ** routine should be called when the buffer is to no longer ! 82: ** be used. ! 83: */ ! 84: ! 85: bufpurge(buffer) ! 86: struct buf **buffer; ! 87: { ! 88: register struct buf **bp; ! 89: register struct buf *a; ! 90: register struct buf *b; ! 91: ! 92: bp = buffer; ! 93: b = *bp; ! 94: *bp = 0; ! 95: ! 96: /* return the segments to the free list */ ! 97: while (b != 0) ! 98: { ! 99: a = b->nextb; ! 100: buffree(b); ! 101: b = a; ! 102: } ! 103: } ! 104: /* ! 105: ** BUFFLUSH -- flush a buffer ! 106: ** ! 107: ** The named buffer is truncated to zero length. However, the ! 108: ** segments of the buffer are not returned to the system. ! 109: */ ! 110: ! 111: bufflush(buffer) ! 112: struct buf **buffer; ! 113: { ! 114: register struct buf *b; ! 115: register struct buf **bp; ! 116: ! 117: bp = buffer; ! 118: b = *bp; ! 119: if (b == 0) ! 120: return; ! 121: ! 122: /* return second and subsequent segments to the system */ ! 123: bufpurge(&b->nextb); ! 124: ! 125: /* truncate this buffer to zero length */ ! 126: b->ptr = b->buffer; ! 127: } ! 128: /* ! 129: ** BUFCRUNCH -- flatten a series of buffers to a string ! 130: ** ! 131: ** The named buffer is flattenned to a conventional C string, ! 132: ** null terminated. The buffer is deallocated. The string is ! 133: ** allocated "somewhere" off in memory, and a pointer to it ! 134: ** is returned. ! 135: */ ! 136: ! 137: char *Buf_flat; ! 138: ! 139: char * ! 140: bufcrunch(buffer) ! 141: struct buf **buffer; ! 142: { ! 143: register char *p; ! 144: char *bufflatten(); ! 145: ! 146: p = bufflatten(*buffer, 1); ! 147: *p = 0; ! 148: *buffer = 0; ! 149: return (Buf_flat); ! 150: } ! 151: ! 152: char * ! 153: bufflatten(buf, length) ! 154: struct buf *buf; ! 155: int length; ! 156: { ! 157: register struct buf *b; ! 158: register char *p; ! 159: register char *q; ! 160: char *bufalloc(); ! 161: ! 162: b = buf; ! 163: ! 164: /* see if we have advanced to beginning of buffer */ ! 165: if (b != 0) ! 166: { ! 167: /* no, keep moving back */ ! 168: p = bufflatten(b->nextb, length + (b->ptr - b->buffer)); ! 169: } ! 170: else ! 171: { ! 172: /* yes, allocate the string */ ! 173: Buf_flat = p = bufalloc(length); ! 174: return (p); ! 175: } ! 176: ! 177: /* copy buffer into string */ ! 178: for (q = b->buffer; q < b->ptr; ) ! 179: *p++ = *q++; ! 180: ! 181: /* deallocate the segment */ ! 182: buffree(b); ! 183: ! 184: /* process next segment */ ! 185: return (p); ! 186: } ! 187: /* ! 188: ** BUFALLOC -- allocate clear memory ! 189: ** ! 190: ** This is similar to the system malloc routine except that ! 191: ** it has no error return, and memory is guaranteed to be clear ! 192: ** when you return. ! 193: ** ! 194: ** It might be nice to rewrite this later to avoid the nasty ! 195: ** memory fragmentation that malloc() tends toward. ! 196: ** ! 197: ** The error processing might have to be modified if used anywhere ! 198: ** other than INGRES. ! 199: */ ! 200: ! 201: char * ! 202: bufalloc(size) ! 203: int size; ! 204: { ! 205: register char *p; ! 206: extern int (*ExitFn)(); /* defined in syserr.c */ ! 207: extern char *malloc(); ! 208: ! 209: p = malloc(size); ! 210: if (p == NULL) ! 211: { ! 212: printf("Out of memory in macro processor\n"); ! 213: (*ExitFn)(-1); ! 214: } ! 215: ! 216: clrmem(p, size); ! 217: ! 218: return (p); ! 219: } ! 220: /* ! 221: ** BUFFREE -- free memory ! 222: */ ! 223: ! 224: buffree(ptr) ! 225: char *ptr; ! 226: { ! 227: register char *p; ! 228: ! 229: p = ptr; ! 230: ! 231: if (p == 0) ! 232: syserr("buffree: 0 ptr"); ! 233: ! 234: free(p); ! 235: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.