|
NAMEamathc.h - C functions for manipulating strings and memory SYNOPSIS#include "amathc.h" Data Structuresstruct texttag
Functionsvoid * AllocMemSafe (size_t)
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>
SEE ALSOamath(1), amathr(3), amathi(3)
|