amath  1.8.5
Simple command line calculator
amathc.h File Reference

C functions for manipulating strings and memory. More...

#include <stddef.h>
#include "amath.h"
Include dependency graph for amathc.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  texttag
 

Functions

void * AllocMemSafe (size_t)
 Allocate memory and add it to the global memory list. More...
 
void FreeMemSafe (void *)
 Deallocate memory from the global memory list. More...
 
void DetachMemSafe (void *)
 Detach an allocated memory from the global memory list. More...
 
void FreeAllSafe ()
 Deallocate all memory in the global memory list. More...
 
void MemUsage (long *, long *, long *)
 Get memory usage in the global memory list. More...
 
int StrLen (const char *string)
 Get the length of a null terminated string. More...
 
bool StrIsEqual (const char *s1, const char *s2)
 Compare two null terminated strings to each other. More...
 
void MemSet (void *destination, int c0, unsigned int length)
 Fill block of memory with a constant value. More...
 
void MemCopy (void *destination, const void *source, unsigned int length)
 Copy a block of memory, handling overlap. More...
 
unsigned int AllocAndCopy (char **destination, const char *source)
 Allocate memory and copy a string into the array. More...
 
void Untag (char *destination, const char *source, texttag tags[], unsigned int tagcount)
 

Detailed Description

C functions for manipulating strings and memory.

Definition in file amathc.h.

Function Documentation

◆ AllocAndCopy()

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.

Referenced by AnsiConoleEngine::AnsiConoleEngine(), CharBuffer::ClearAndCopy(), ConsoleBase::ConsoleBase(), AnsiConoleEngine::CopyLine(), DeleteStatement::DeleteStatement(), DrawStatement::DrawStatement(), ErrorNode::ErrorNode(), ExecuteStatement::ExecuteStatement(), FunctionNode::FunctionNode(), HelpStatement::HelpStatement(), Lexer::Lexer(), ListStatement::ListStatement(), StandardLanguage::LoadCatalog(), LoadStatement::LoadStatement(), PlotStatement::PlotStatement(), PromptStatement::PromptStatement(), SaveStatement::SaveStatement(), PreferencesBase::SetDefaults(), PreferencesBase::SetPrompt(), AnsiConoleEngine::SetPrompt(), ConsoleBase::SetPrompt(), AnsiConoleEngine::ShowLast(), ShowStatement::ShowStatement(), StatementNode::StatementNode(), Token::Token(), UserFunction::UserFunction(), and Variable::Variable().

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 
61 #if defined(AMIGA) // Take advantage of exec
62  CopyMem(s, d, n);
63 #else
64  while (n--)
65  *d++ = *s++;
66 #endif
67 
68  return size;
69 }
void * AllocMemSafe(size_t)
Allocate memory and add it to the global memory list.
Definition: mem.c:86
Here is the caller graph for this function:

◆ AllocMemSafe()

void* AllocMemSafe ( size_t  )

Allocate memory and add it to the global memory list.

Definition at line 86 of file mem.c.

References MemoryBlock::address, alloc_error(), MemoryList::count, MemoryList::first, list, MemoryBlock::next, MemoryList::peak, MemoryBlock::size, and MemoryList::size.

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 }
struct MemoryBlock * first
Definition: mem.c:69
size_t peak
Definition: mem.c:70
long count
Definition: mem.c:72
void alloc_error(char *, size_t)
Log a memory allocation error.
Definition: mem.c:252
size_t size
Definition: mem.c:71
struct MemoryBlock * next
Definition: mem.c:59
Block of allocated memory.
Definition: mem.c:57
void * address
Definition: mem.c:61
#define ALLOC_MEM(x)
Definition: mem.c:43
struct MemoryList * list
Global list of allocated memory.
Definition: mem.c:78
size_t size
Definition: mem.c:60
#define FREE_MEM(x)
Definition: mem.c:44
List of allocated memory. Uses the LIFO principle.
Definition: mem.c:67
Here is the call graph for this function:

◆ DetachMemSafe()

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.

References RemoveMemSafe().

210 {
211  RemoveMemSafe(block, false);
212 }
void RemoveMemSafe(void *block, bool deallocate)
Definition: mem.c:144
Here is the call graph for this function:

◆ FreeAllSafe()

void FreeAllSafe ( )

Deallocate all memory in the global memory list.

Definition at line 217 of file mem.c.

References MemoryBlock::address, MemoryList::first, list, and MemoryBlock::next.

Referenced by main().

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 }
struct MemoryBlock * first
Definition: mem.c:69
struct MemoryBlock * next
Definition: mem.c:59
Block of allocated memory.
Definition: mem.c:57
void * address
Definition: mem.c:61
struct MemoryList * list
Global list of allocated memory.
Definition: mem.c:78
#define FREE_MEM(x)
Definition: mem.c:44
Here is the caller graph for this function:

◆ FreeMemSafe()

void FreeMemSafe ( void *  )

Deallocate memory from the global memory list.

Definition at line 200 of file mem.c.

References RemoveMemSafe().

201 {
202  RemoveMemSafe(block, true);
203 }
void RemoveMemSafe(void *block, bool deallocate)
Definition: mem.c:144
Here is the call graph for this function:

◆ MemCopy()

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.

Referenced by CharBuffer::EnsureSize(), Lexer::GetDigitValue(), Lexer::GetLiteral(), Lexer::GetQuotedIdent(), DecimalSystem::GetText(), and Language::UntagText().

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
87 #if defined(AMIGA) // Take advantage of exec
88  CopyMem((void*)source, destination, length);
89 #else
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++);
109 #endif
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 }
#define wmask
Definition: amath.h:233
#define TLOOP1(s)
loop-t-times, t>0
Definition: memcpy.c:70
uint32_t word
sizeof(word) MUST BE A POWER OF TWO SO THAT wmask BELOW IS ALL ONES
Definition: memcpy.c:59
#define wsize
Definition: amath.h:232
uintptr_t mem_ptr
Definition: memcpy.c:60
#define TLOOP(s)
loop-t-times
Definition: memcpy.c:65
Here is the caller graph for this function:

◆ MemSet()

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 }
#define wmask
Definition: amath.h:233
#define wsize
Definition: amath.h:232
uintptr_t mem_ptr
Definition: memcpy.c:60

◆ MemUsage()

void MemUsage ( long *  ,
long *  ,
long *   
)

Get memory usage in the global memory list.

Definition at line 242 of file mem.c.

References MemoryList::count, list, MemoryList::peak, and MemoryList::size.

Referenced by MemoryStatement::Execute().

243 {
244  *blocks = list->count;
245  *size = (long)list->size;
246  *peak = (long)list->peak;;
247 }
size_t peak
Definition: mem.c:70
long count
Definition: mem.c:72
size_t size
Definition: mem.c:71
struct MemoryList * list
Global list of allocated memory.
Definition: mem.c:78
size_t size
Definition: mem.c:60
Here is the caller graph for this function:

◆ StrIsEqual()

bool StrIsEqual ( const char *  s1,
const char *  s2 
)

Compare two null terminated strings to each other.

Definition at line 50 of file strcmp.c.

Referenced by VariableList::CreateVariable(), FunctionList::Delete(), FunctionList::FindAlias(), Language::FindAlias(), FunctionList::GetFunctionCall(), FunctionList::GetFunctionDef(), Language::GetHelpText(), FunctionList::GetSystemFunction(), VariableList::GetVariable(), StandardProgram::Initialize(), CharBuffer::Is(), StandardFilesystem::ListDirectory(), CharBuffer::RemoveTrailing(), and StandardLanguage::StrIsEqualLoc().

51 {
52  int r;
53 
54  while (*s1 == *s2++)
55  if (*s1++ == '\0')
56  return true;
57 
58  r = (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
59 
60  return r == 0;
61 }
Here is the caller graph for this function:

◆ StrLen()

◆ Untag()

void Untag ( char *  destination,
const char *  source,
texttag  tags[],
unsigned int  tagcount 
)

Definition at line 32 of file untag.c.

References texttag::tag, and texttag::text.

Referenced by Language::UntagText().

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 != '\0')
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 != '\0' && *tag != '\0' && *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 = '\0';
82 }
const char * text
Definition: amathc.h:48
const char * tag
Definition: amathc.h:47
Here is the caller graph for this function: