home | help
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)

home | help