| 1 | #ifndef lint |
| 2 | static char sccsid[] = "@(#)strings.c 2.2 (Berkeley) %G%"; |
| 3 | #endif |
| 4 | |
| 5 | /* |
| 6 | * Mail -- a mail program |
| 7 | * |
| 8 | * String allocation routines. |
| 9 | * Strings handed out here are reclaimed at the top of the command |
| 10 | * loop each time, so they need not be freed. |
| 11 | */ |
| 12 | |
| 13 | #include "rcv.h" |
| 14 | |
| 15 | /* |
| 16 | * Allocate size more bytes of space and return the address of the |
| 17 | * first byte to the caller. An even number of bytes are always |
| 18 | * allocated so that the space will always be on a word boundary. |
| 19 | * The string spaces are of exponentially increasing size, to satisfy |
| 20 | * the occasional user with enormous string size requests. |
| 21 | */ |
| 22 | |
| 23 | char * |
| 24 | salloc(size) |
| 25 | { |
| 26 | register char *t; |
| 27 | register int s; |
| 28 | register struct strings *sp; |
| 29 | int index; |
| 30 | |
| 31 | s = size; |
| 32 | s++; |
| 33 | s &= ~01; |
| 34 | index = 0; |
| 35 | for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { |
| 36 | if (sp->s_topFree == NOSTR && (STRINGSIZE << index) >= s) |
| 37 | break; |
| 38 | if (sp->s_nleft >= s) |
| 39 | break; |
| 40 | index++; |
| 41 | } |
| 42 | if (sp >= &stringdope[NSPACE]) |
| 43 | panic("String too large"); |
| 44 | if (sp->s_topFree == NOSTR) { |
| 45 | index = sp - &stringdope[0]; |
| 46 | sp->s_topFree = (char *) calloc(STRINGSIZE << index, |
| 47 | (unsigned) 1); |
| 48 | if (sp->s_topFree == NOSTR) { |
| 49 | fprintf(stderr, "No room for space %d\n", index); |
| 50 | panic("Internal error"); |
| 51 | } |
| 52 | sp->s_nextFree = sp->s_topFree; |
| 53 | sp->s_nleft = STRINGSIZE << index; |
| 54 | } |
| 55 | sp->s_nleft -= s; |
| 56 | t = sp->s_nextFree; |
| 57 | sp->s_nextFree += s; |
| 58 | return(t); |
| 59 | } |
| 60 | |
| 61 | /* |
| 62 | * Reset the string area to be empty. |
| 63 | * Called to free all strings allocated |
| 64 | * since last reset. |
| 65 | */ |
| 66 | |
| 67 | sreset() |
| 68 | { |
| 69 | register struct strings *sp; |
| 70 | register int index; |
| 71 | |
| 72 | if (noreset) |
| 73 | return; |
| 74 | minit(); |
| 75 | index = 0; |
| 76 | for (sp = &stringdope[0]; sp < &stringdope[NSPACE]; sp++) { |
| 77 | if (sp->s_topFree == NOSTR) |
| 78 | continue; |
| 79 | sp->s_nextFree = sp->s_topFree; |
| 80 | sp->s_nleft = STRINGSIZE << index; |
| 81 | index++; |
| 82 | } |
| 83 | } |