Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

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)

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>

home | help