amathc.h(3) Library Functions Manual amathc.h(3) NAME amathc.h - C functions for manipulating strings and memory SYNOPSIS #include "amathc.h" Data Structures struct texttag Functions void * 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) DESCRIPTION unsigned 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 } HOMEPAGE https://amath.innolan.net/ AUTHORS Written 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. COPYRIGHT Copyright (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 ALSO amath(1), amathr(3), amathi(3) August 07 2018 Version 1.8.5 amathc.h(3)
Want to link to this manual page? Use this URL:
<https://man.FreeBSD.org/cgi/man.cgi?query=amathc&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>