|
NAMEamathc.h - C functions for manipulating strings and memorySYNOPSIS#include "amathc.h" Data Structuresstruct texttag Functionsvoid * AllocMemSafe (size_t) Allocate memory and add it to the global memory list. void FreeMemSafe (void *) Deallocate memory from the global memory list. void DetachMemSafe (void *) Detach an allocated memory from the global memory list. void FreeAllSafe () Deallocate all memory in the global memory list. void MemUsage (long *, long *, long *) Get memory usage in the global memory list. int StrLen (const char *string) Get the length of a null terminated string. bool StrIsEqual (const char *s1, const char *s2) Compare two null terminated strings to each other. void MemSet (void *destination, int c0, unsigned int length) Fill block of memory with a constant value. void MemCopy (void *destination, const void *source, unsigned int length) Copy a block of memory, handling overlap. unsigned int AllocAndCopy (char **destination, const char *source) Allocate memory and copy a string into the array. void Untag (char *destination, const char *source, texttag tags[], unsigned int tagcount) DESCRIPTIONunsigned int AllocAndCopy (char ** destination, const char * source)Allocate memory and copy a string into the array.Definition at line 40 of file alloccpy.c. 41 { 42 char *i, *s, *d; 43 unsigned int n, size; 44 45 if (source == nullptr) 46 { 47 *destination = nullptr; 48 return 0; 49 } 50 51 i = (char*)source; 52 s = (char*)source; 53 while (*i) 54 i++; 55 56 n = (unsigned int)(i - s + 1); 57 size = n; 58 *destination = AllocMemSafe(size); 59 d = *destination; 60 64 while (n--) 65 *d++ = *s++; 67 68 return size; 69 } void* AllocMemSafe (size_t)Allocate memory and add it to the global memory list.Definition at line 86 of file mem.c. 87 { 88 struct MemoryBlock* newblock; 89 size_t allocsize; 90 91 if (list == nullptr) 92 { 93 list = (struct MemoryList*)ALLOC_MEM(sizeof(struct MemoryList)); 94 if (!list) 95 { 96 alloc_error("list", sizeof(struct MemoryList)); 97 return 0; 98 } 99 100 list->first = nullptr; 101 list->peak = 0; 102 list->size = 0; 103 list->count = 0; 104 } 105 106 #ifdef P64BIT 107 // Align to bytes of 8 108 allocsize = (size + 7) & ~0x07; 109 #else 110 // Align to bytes of 4 111 allocsize = (size + 3) & ~0x03; 112 #endif 113 114 newblock = (struct MemoryBlock*)ALLOC_MEM(sizeof(struct MemoryBlock)); 115 if (!newblock) 116 { 117 alloc_error("block", sizeof(struct MemoryBlock)); 118 return 0; 119 } 120 121 newblock->address = (struct MemoryBlock*)ALLOC_MEM(allocsize); 122 if (!newblock->address) 123 { 124 FREE_MEM(newblock); 125 alloc_error("memory", allocsize); 126 return 0; 127 } 128 129 newblock->size = allocsize; 130 newblock->next = list->first; 131 list->first = newblock; 132 list->size += allocsize; 133 list->count++; 134 135 if (list->size > list->peak) 136 { 137 list->peak = list->size; 138 } 139 140 // Memory allocated 141 return newblock->address; 142 } void DetachMemSafe (void * block)Detach an allocated memory from the global memory list. The memory block is only detached, not deallocated.Definition at line 209 of file mem.c. 210 { 211 RemoveMemSafe(block, false); 212 } void FreeAllSafe ()Deallocate all memory in the global memory list.Definition at line 217 of file mem.c. 218 { 219 struct MemoryBlock *current, *next; 220 221 if (list == nullptr) 222 { 223 return; 224 } 225 226 current = list->first; 227 while (current != nullptr) 228 { 229 next = current->next; 230 FREE_MEM(current->address); 231 FREE_MEM(current); 232 current = next; 233 } 234 235 FREE_MEM(list); 236 list = nullptr; 237 } void FreeMemSafe (void *)Deallocate memory from the global memory list.Definition at line 200 of file mem.c. 201 { 202 RemoveMemSafe(block, true); 203 } void MemCopy (void * destination, const void * source, unsigned int length)Copy a block of memory, handling overlap.Definition at line 75 of file memcpy.c. 76 { 77 char* dst = (char*) destination; 78 const char* src = (const char*) source; 79 unsigned int t; 80 81 if (length == 0 || dst == src) // nothing to do 82 return; 83 84 if ((mem_ptr)dst < (mem_ptr)src) 85 { 86 // Copy forward 90 t = (mem_ptr)src; // only need low bits 91 if ((t | (mem_ptr)dst) & wmask) 92 { 93 // Try to align operands. This cannot be done unless the low bits match. 94 if ((t ^ (mem_ptr)dst) & wmask || length < wsize) 95 t = length; 96 else 97 t = wsize - (t & wmask); 98 length -= t; 99 100 TLOOP1(*dst++ = *src++); 101 } 102 103 // Copy whole words, then mop up any trailing bytes. 104 t = length / wsize; 105 TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); 106 107 t = length & wmask; 108 TLOOP(*dst++ = *src++); 110 } 111 else 112 { 113 // Copy backwards. Otherwise essentially the same. 114 // Alignment works as before, except that it takes 115 // (t&wmask) bytes to align, not wsize-(t&wmask). 116 src += length; 117 dst += length; 118 t = (mem_ptr)src; 119 if ((t | (mem_ptr)dst) & wmask) 120 { 121 if ((t ^ (mem_ptr)dst) & wmask || length <= wsize) 122 t = length; 123 else 124 t &= wmask; 125 length -= t; 126 127 TLOOP1(*--dst = *--src); 128 } 129 130 t = length / wsize; 131 TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); 132 133 t = length & wmask; 134 TLOOP(*--dst = *--src); 135 } 136 } void MemSet (void * destination, int c0, unsigned int length)Fill block of memory with a constant value.Definition at line 56 of file memset.c. 57 { 58 unsigned char* dst = (unsigned char*) dst0; 59 unsigned int t; 60 unsigned int c; 61 62 /* 63 * If not enough words, just fill bytes. A length >= 2 words 64 * guarantees that at least one of them is `complete' after 65 * any necessary alignment. For instance: 66 * 67 * |-----------|-----------|-----------| 68 * |00|01|02|03|04|05|06|07|08|09|0A|00| 69 * ^---------------------^ 70 * dst dst+length-1 71 * 72 * but we use a minimum of 3 here since the overhead of the code 73 * to do word writes is substantial. 74 */ 75 if (length < 3 * wsize) 76 { 77 while (length != 0) 78 { 79 *dst++ = c0; 80 --length; 81 } 82 } 83 84 if ((c = (unsigned char)c0) != 0) 85 { /* Fill the word. */ 86 c = (c << 8) | c; /* u_int is 16 bits. */ 87 #if UINT_MAX > 0xffff 88 c = (c << 16) | c; /* u_int is 32 bits. */ 89 #endif 90 #if UINT_MAX > 0xffffffff 91 c = (c << 32) | c; /* u_int is 64 bits. */ 92 #endif 93 } 94 95 /* Align destination by filling in bytes. */ 96 if ((t = (mem_ptr)dst & wmask) != 0) 97 { 98 t = wsize - t; 99 length -= t; 100 do 101 { 102 *dst++ = c0; 103 } 104 while (--t != 0); 105 } 106 107 /* Fill words. Length was >= 2*words so we know t >= 1 here. */ 108 t = length / wsize; 109 do 110 { 111 *(unsigned int*)dst = c; 112 dst += wsize; 113 } 114 while (--t != 0); 115 116 /* Mop up trailing bytes, if any. */ 117 t = length & wmask; 118 if (t != 0) 119 do 120 { 121 *dst++ = c0; 122 } 123 while (--t != 0); 124 } void MemUsage (long *, long *, long *)Get memory usage in the global memory list.Definition at line 242 of file mem.c. 243 { 244 *blocks = list->count; 245 *size = (long)list->size; 246 *peak = (long)list->peak;; 247 } bool StrIsEqual (const char * s1, const char * s2)Compare two null terminated strings to each other.Definition at line 50 of file strcmp.c. 51 { 52 int r; 53 54 while (*s1 == *s2++) 55 if (*s1++ == ' ') 56 return true; 57 58 r = (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); 59 60 return r == 0; 61 } int StrLen (const char * string)Get the length of a null terminated string.Definition at line 34 of file strlen.c. 35 { 36 char* i = (char*)string; 37 char* s = i; 38 while (*i) 39 i++; 40 return (int)(i - s); 41 } void Untag (char * destination, const char * source, texttag tags[], unsigned int tagcount)Definition at line 32 of file untag.c.33 { 34 const char *pos, *tmp, *tag; 35 char* dest; 36 int unsigned i, j, found; 37 38 pos = source; 39 dest = destination; 40 41 while (*pos != ' ') 42 { 43 if (*pos != '#') 44 { 45 (*dest++ = *pos++); 46 } 47 else 48 { 49 // Try to replace tag 50 found = 0; 51 for (i = 0; i < tagcount; i++) 52 { 53 tag = tags[i].tag; 54 tmp = pos; 55 j = 0; 56 while (*tmp != ' ' && *tag != ' ' && *tmp == *tag) 57 { 58 tmp++; 59 tag++; 60 j++; 61 } 62 63 if (j > 1 && *(--tag) == '#') 64 { 65 // Tag found. Now replace. 66 tag = tags[i].text; 67 while ((*dest++ = *tag++)); 68 dest--; 69 pos = tmp; 70 found = 1; 71 break; 72 } 73 } 74 75 if (!found) 76 { 77 (*dest++ = *pos++); 78 } 79 } 80 } 81 *dest = ' '; 82 } HOMEPAGEhttps://amath.innolan.net/AUTHORSWritten by Carsten Sonne Larsen <cs@innolan.net>. The code in MemSet and MemCopy is derived from software contributed to Berkeley by Mike Hibler and Chris Torek.COPYRIGHTCopyright (c) 2014-2018 Carsten Sonne Larsen <cs@innolan.net>Copyright (c) 2007 The NetBSD Foundation, Inc. Copyright (c) 1990, 1993 The Regents of the University of California SEE ALSOamath(1), amathr(3), amathi(3)
Visit the GSP FreeBSD Man Page Interface. |