Commits

Sulaiman  committed ca672e4

تغييرات كثيرة ودوال جديدة. أنظر للدف

  • Participants
  • Parent commits 473832e

Comments (0)

Files changed (70)

File __policies__/modules

-
-DEFINITION
-    A module is a pair that consists of a c source code file, and a c header.
-
-OBJECTIVE
-    To standarize implementation and hadling of stc modules.
-
-
-VERSIONING
-    Each module has a 3-segment, colomn-seperated version string. The first
-    segment describes the API version and MUST be incremented with each 
-    change to the module's public API. The second segment describes the ABI 
-    version and MUST be incremented with each change to the module's ABI.
-    
-    The last segment describes describes source version, and MUST be 
-    incremented with each release.
-    
-    The developer SHOULD avoid changing the modules API unless necesary.
-    
-    The following is an example of a stc version string: "1:0:65".
-    
-
-C STANDARDS COMPLIANCE
-    Modules MUST be compilable with a c1x compiler, and MUST be conferming 
-    to ISO/IEC 9899:201x.
-
-    
-ADDITIONAL STANDARD INCLUSION
-    Modules MAY depend on the most recent revesion of the POSIX/SUS 
-    standards. At the time of this writting, it was POSIX.1-2008, SUSv4
-    Furthermore, modules MAY depend on the linux kernals stable APIs. But 
-    POSIX/SUS APIs should be geven prefence.
-
-
-THIRD-PARTY LIBRARY INCLUSION
-    Developers are strongly advised against using third party libraries, 
-    unless:
-        A.  The library is common and well-supported.
-        B.  The library can be included in the module itself.
-
-
-CONCURENCY
-    Modules MUST be thread safe.
-    
-    
-GLOBAL VARIABLES AND CONSTANT LITERALS
-    Modules MUST define the following variables:
-    
-    bool stc{module name}_config_debug;
-        This variable SHOULD enable verbos debuging information as development 
-        aid. The generated output MUST NOT be consumed under normal operation 
-        and is subject to change between source versions.
-    
-    int stc{module name}_config_version[3] = {API, ABI, SRC};
-        This variable MUST contains the numrical representation of the  version 
-        string as described in section "VERSIONING". API, ABI, and SRC 
-        corispond to the API, ABI, and source version segments, respectivly.
-        
-    
-CROSS-MODULE DEPENDENCIES
-    Modules that make use of other modules SHOULD check API version.
-
-
-COMMENTS
-    1.  Developers should try and minimize compiler warnings if posible. GCC's 
-        '-Wextra' is an exception.

File __policies__/usage

-VERSION CHECKING
-    Whenever using a module in your source code, you should check it's API 
-    version. Furthermore, if you use modules as shared objects, check the ABI
-    as well.

File a/Makefile

-test: scta.* test.c
-	gcc -o test -std=c99 -pedantic -g -Wall -Wextra scta.c test.c
-
-memcheck: test
-	valgrind --tool=memcheck ./test
-
-clean:
-	rm test

File a/TODO

-- Add sorted_insert?

File a/scta.c

-/*
-
-    scta: Generic Dynamic Array Module
-
-    Sulaiman (seininn) Mustafa     2014-02-26
-    
-    This module is a part of libstc, a modular, c99/c1x-compliant, 
-    toolkit library. use stcmod to determine this module's 
-    dependencies, if any.
-    
-*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <limits.h>
-
-#include "scta.h"
-
-
-FILE *scta_config_debug = NULL;
-int scta_config_version[3] = {1, 1, 1};
-
-/*
-    internal array layout
-
-    +------------------+
-    |       SIZE       |  <- internal pointer points here
-    +------------------+
-    |      LENGTH      |
-    +------------------+
-    |      RETURN      |  used to be used for return status, might remove later
-    +------------------+
-    |   ARGUMENT_INT_1 |  argument regesters for functions to avoid multiple 
-    +------------------+  macro argument invokations. unfortunetly, the array
-    |   ARGUMENT_INT_2 |  argument must be invoked more than once. (that, or
-    +------------------+  use statement expressions wich makes this non-c code)
-    |   ARGUMENT_PTR_1 |  :
-    +------------------+  :
-    |   ARGUMENT_PTR_2 |  :
-    +------------------+  '
-    |     ELEMENT_0    |  <- external pointer points here 
-    +------------------+
-    +---------:--------+
-    +---------:--------+
-    +------------------+
-    |     ELEMENT_N    |
-    +------------------+
-    |         0        |  Auto-null terminated
-    +------------------+
-    |      STORAGE     |  (same size as normal array elements)
-    +------------------+
-    
-*/
-
-#define ERRMSG_AND_RETURN(RET, ...) {\
-    if (scta_config_debug) {\
-        fprintf(scta_config_debug, "scta:%s():%d: ", __func__, __LINE__);\
-        fprintf(scta_config_debug, __VA_ARGS__);\
-        fprintf(scta_config_debug, "\n");\
-    }\
-    return (RET); \
-}
-
-#define ___INTERNAL_INT_ARRAY_PRINTER___\
-    fprintf(stderr, "length: %d, size: %zu, { ", SCTA__INTERN_LEN(ra)[0], SCTA__INTERN_SIZE(ra)[0]);\
-    for (int i = 0; i < SCTA__INTERN_LEN(ra)[0]+2; ++i) fprintf(stderr, "%d ", ((int *)((char *) ra + SCTA_HEAD))[i]);\
-    fprintf(stderr, "} \n");
-
-
-// XXX EXTERN SHOULD NOT APPEAR IN THIS DOCUMENT
-
-bool make_space(void **ra, int at, int count){
-    // makes a space inside *ra, and moves everything (including storage) to the right
-    // count is the number of elements to remove and has nothing to do with size
-    size_t size = SCTA__INTERN_SIZE(*ra)[0];
-    int length = SCTA__INTERN_LEN(*ra)[0];
-    void *temp;
-    
-    if (!size) 
-        ERRMSG_AND_RETURN(false, "element size can not be zero.")
-    
-    if (length == INT_MAX) 
-        ERRMSG_AND_RETURN(false, "cannot increase array size do to int limit.")
-        
-    if (!(temp=realloc(*ra, (SCTA_HEAD)+ size*length + size*count + size + size))) 
-        ERRMSG_AND_RETURN(false, "memory operation failed: new size is %zu", ((SCTA_HEAD+size)+size*length+size+size))
-    *ra = temp;
-    
-    
-    memmove( ((char *) *ra) + SCTA_HEAD + at*size + size*count, 
-             ((char *) *ra) + SCTA_HEAD + at*size, 
-             (length*size) - (at*size) + size + size);
-    
-    
-    SCTA__INTERN_LEN(*ra)[0]+=count;
-    return true;
-}
-
-bool collapse_space(void **ra, int at, int count){
-    // removes a space from *ra, and moves everything (including storage) to the left
-    // count is the number of elements to remove and has nothing to do with size
-    size_t size = SCTA__INTERN_SIZE(*ra)[0];
-    int length = SCTA__INTERN_LEN(*ra)[0];
-    void *temp;
-    
-    if (!size) 
-        ERRMSG_AND_RETURN(false, "element size can not be zero.")
-    
-    if (!length) 
-        ERRMSG_AND_RETURN(false, "cannot shorten a zero length array")
-        
-    
-    memmove( ((char *) *ra) + SCTA_HEAD + at*size, 
-             ((char *) *ra) + SCTA_HEAD + at*size + size*count, 
-             (length*size) - (at*size + size*count) + size + size);
-    
-    if (!(temp=realloc(*ra, SCTA_HEAD + size*length - size*count + size + size))) 
-        ERRMSG_AND_RETURN(false, "memory operation failed: new size is %zu", ((SCTA_HEAD+size)+size*length-size))
-    *ra = temp;
-    
-    SCTA__INTERN_LEN(*ra)[0] -= count;
-    return true;
-}
-
-
-void* make_raw_array(size_t size){
-    void *ra;
-    
-    if (!size) 
-        ERRMSG_AND_RETURN(NULL, "requested array member size is 0. minimum is 1.")
-    
-    if (!(ra = malloc(SCTA_HEAD + size + size)))
-        ERRMSG_AND_RETURN(NULL, "could not allocate enough memory: requested %zu", SCTA_HEAD + size)
-        
-    memset(ra, 0, SCTA_HEAD + size + size);
-    
-    /* debugging macros
-    fprintf(stderr, "base %p\n", c);
-    fprintf(stderr, "size loc %p\n", SCTA__INTERN_SIZE(c));
-    fprintf(stderr, "len loc %p\n", SCTA__INTERN_LEN(c));
-    fprintf(stderr, "MTS: 0x%lx (0x%lx, 0x%lx, 0x%lx)\n", SCTA_HEAD, sizeof(size_t), sizeof(int), sizeof(bool));
-    fprintf(stderr, "len loc %p\n", SCTA__INTERN_LEN(c));
-    */
-    
-    SCTA__INTERN_SIZE(ra)[0] = size;
-    SCTA__INTERN_LEN(ra)[0] = 0;
-    
-    return ra;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-// Macro functions. Dont forget:
-// -- to differeantiat between internal functions and macro ones and:
-// -- convert arrays to raw arrays and vice versa when nessary by sub/add SCTA__OFFSET_HEADER
-// -- functions here must not use EXTERN functions for concistancy.
-// -- arguments are stored in the array itself. the specification of this is in the function's comment
-// -- arrays passed by macros are in there normal form and not raw form
-
-void* scta_macro_new_(size_t size){/**/
-    void *ra = make_raw_array(size);
-    if (ra) return ((char *)ra)+SCTA_HEAD;
-    else return NULL;
-}
-
-void scta_macro_free_(void *c){ free((char *)c-SCTA_HEAD); }
-
-
-bool scta_macro_set_length_(char **z, int newl){
-    void *ra = *z-SCTA_HEAD;
-    int oldl = SCTA__INTERN_LEN(ra)[0];
-    int size = SCTA__INTERN_SIZE(ra)[0];
-    if (newl > oldl) {
-        if (!make_space(&ra, oldl, newl-oldl)) return false;
-        memset((char *)ra+SCTA_HEAD+(oldl*SCTA__INTERN_SIZE(ra)[0]), 0, (newl-oldl)*size + size + size);
-    }
-    if (newl < oldl) {
-        if (!collapse_space(&ra, newl, oldl-newl)) return false;
-    }
-    
-    *z = (char *) ra + SCTA_HEAD;
-    return true;    
-}
-
-bool scta_macro_insert_(char **z){/*
-    inserts an element in an array
-    
-    INT1 : at
-    STORAGE: what
-*/
-    void *ra = *z-SCTA_HEAD;
-    
-    
-    size_t size = SCTA__INTERN_SIZE(ra)[0];
-    int oldl = SCTA__INTERN_LEN(ra)[0];
-
-    int at = SCTA__INTERN_INT1(ra)[0];
-    
-    // if negative indexing: normalize
-    if (at < 0) at = oldl + at;
-    // if at is larger than length of array, set to insert to length
-    if (at > oldl) at = oldl;
-    
-    
-    if ( at < 0) 
-        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
-                                 "\tlength: %d\n" 
-                                 "\top index at: %d\n", oldl, at)
-    
-    if (!make_space(&ra, at, 1)) return false;
-    
-    memmove(    ((char *) ra) + SCTA_HEAD + size*at, 
-                SCTA__INTERN_STORAGE(ra), size);
-    
-    
-    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
-    *z = (char *) ra + SCTA_HEAD;
-    return true;
-}
-
-bool scta_macro_insert_array_(char **z){/*
-    inserts an element in an array
-    
-    INT1 : at
-    INT2 : length
-    PTR1: pointer
-*/
-    void *ra = *z-SCTA_HEAD;    
-    
-    size_t size = SCTA__INTERN_SIZE(ra)[0];
-    int oldl = SCTA__INTERN_LEN(ra)[0];
-
-    int target_length = SCTA__INTERN_INT2(ra)[0];
-    void *target_addr = SCTA__INTERN_PTR1(ra)[0];
-
-    int at = SCTA__INTERN_INT1(ra)[0];
-    
-    // normalize index if negative
-    if (at < 0) at = oldl + at;
-    // set after last element if index is larger than array length
-    if (at > oldl) at = oldl;
-    
-    if ( at < 0) 
-        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
-                                  "\tlength: %d\n" 
-                                 "\top index at: %d\n", oldl, at)
-    
-    if (!make_space(&ra, at, target_length)) return false;
-    
-    memmove(    ((char *) ra) + SCTA_HEAD + size*at, 
-                target_addr , size*target_length);
-    
-    
-    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
-    *z = (char *) ra + SCTA_HEAD;
-    return true;
-}
-
-
-bool scta_macro_delete_subset_(char **z){/*
-    deletes a subset that starts at `at' and has a length of `length'
-    
-    input
-    
-    INT1 : at
-    INT2 : length
-    
-    output:
-    STORAGE fist element in deleted subset
-    
-*/
-    void *ra = *z-SCTA_HEAD;    
-    
-    size_t size = SCTA__INTERN_SIZE(ra)[0];
-    int oldl = SCTA__INTERN_LEN(ra)[0];
-
-    int target_length = SCTA__INTERN_INT2(ra)[0];
-
-    int at = SCTA__INTERN_INT1(ra)[0];
-    // normalze if index is negative
-    if (at < 0) at = oldl + at;
-    // set index BEFORE last element if larger than length (so that the last 
-    // element is deleted
-    if (at > oldl) at = oldl-1;
-    
-    if ( oldl < (at+target_length) || at < 0) 
-        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
-                                 "\tlength: %d\n" 
-                                 "\tdeletion starts at: %d\n" 
-                                 "\tand spans %d element(s)\n", oldl, at, target_length)
-
-    
-    memmove( SCTA__INTERN_STORAGE(ra), 
-            ((char *) ra) + SCTA_HEAD + size*at, size);
-    
-    if (!collapse_space(&ra, at, target_length)) return false;
-    
-    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
-    *z = (char *) ra + SCTA_HEAD;
-    return true;
-}
-
-
-
-// APPENDIX A: EXTERNAL CODE
-void* scta_macro_subset_(size_t size, int at, int length, void *p){
-    void *n = scta_macro_new_(size);
-    if (!n) return NULL;
-    
-    if (at < 0) at = SCTA__EXTERN_LEN(p)[0] + at;
-    
-    if(!scta_insert_array(n, 0, (char *) p + at*SCTA__EXTERN_SIZE(p)[0], length)) return NULL;
-    else return n;
-}

File a/scta.h

-/*
-
-    scta: Generic Dynamic Array Module
-
-    Sulaiman (seininn) Mustafa     2014-02-26
-    
-    This module is a part of libstc, a modular, c99/c1x-compliant, 
-    toolkit library. use stcmod to determine this module's 
-    dependencies, if any.
-    
-*/
-
-#ifndef SCTA_H
-#define SCTA_H
-
-#include <stdio.h>
-#include <stdbool.h>
-#include <limits.h>
-
-
-
-/*
-‎         .                 لا تستخدم الماكروات التالية واقتصر على الماكروات
-‎        ╱ ╲           ‫المعرفة في "PUBLIC API". استغرار هذه الماكروات غير مضمون.
-‎       ╱ | ╲
-‎      ╱  ·  ╲           Do NOT use the following macros and limit your use
-‎     ∙───────∙         to the macros defined under "PUBLIC API". This macros
-                                  are not garanteed to be stable.
-
-*/
-
-#define SCTA__OFFSET_SIZE 0
-#define SCTA__OFFSET_LEN  (SCTA__OFFSET_SIZE + sizeof(size_t))
-#define SCTA__OFFSET_RET  (SCTA__OFFSET_LEN + sizeof(int))
-#define SCTA__OFFSET_INT1 (SCTA__OFFSET_RET + sizeof(bool))
-#define SCTA__OFFSET_INT2 (SCTA__OFFSET_INT1 + sizeof(int))
-#define SCTA__OFFSET_PTR1 (SCTA__OFFSET_INT2 + sizeof(int))
-#define SCTA__OFFSET_PTR2 (SCTA__OFFSET_PTR1 + sizeof(void *))
-#define SCTA__OFFSET_HEADER  (SCTA__OFFSET_PTR2 + sizeof(void *))
-
-#define SCTA_HEAD SCTA__OFFSET_HEADER
-
-
-
-#define SCTA___SIZE(PTR, OFFSET)  ((size_t *) (((char *) PTR) + SCTA__OFFSET_SIZE   + OFFSET))
-#define SCTA___LEN(PTR, OFFSET)   ((int *)    (((char *) PTR) + SCTA__OFFSET_LEN    + OFFSET))
-#define SCTA___RET(PTR, OFFSET)   ((bool *)   (((char *) PTR) + SCTA__OFFSET_RET    + OFFSET))
-#define SCTA___INT1(PTR, OFFSET)  ((int *)    (((char *) PTR) + SCTA__OFFSET_INT1   + OFFSET))
-#define SCTA___INT2(PTR, OFFSET)  ((int *)    (((char *) PTR) + SCTA__OFFSET_INT2   + OFFSET))
-#define SCTA___PTR1(PTR, OFFSET)  ((void **)  (((char *) PTR) + SCTA__OFFSET_PTR1   + OFFSET))
-#define SCTA___PTR2(PTR, OFFSET)  ((void **)  (((char *) PTR) + SCTA__OFFSET_PTR2   + OFFSET))
-
-
-
-// returns the size, length, and status of the true bigening of the array (internal)
-#define SCTA__INTERN_SIZE(X) SCTA___SIZE(X, 0)
-#define SCTA__INTERN_LEN(X)  SCTA___LEN(X, 0)
-#define SCTA__INTERN_RET(X)  SCTA___RET(X, 0)
-#define SCTA__INTERN_INT1(X) SCTA___INT1(X, 0)
-#define SCTA__INTERN_INT2(X) SCTA___INT2(X, 0)
-#define SCTA__INTERN_PTR1(X) SCTA___PTR1(X, 0)
-#define SCTA__INTERN_PTR2(X) SCTA___PTR2(X, 0)
-
-
-
-
-// returns the size, length, and status of apparent bigening of the array (external)
-#define SCTA__EXTERN_SIZE(X) SCTA___SIZE(X, -SCTA_HEAD)
-#define SCTA__EXTERN_LEN(X)  SCTA___LEN(X,  -SCTA_HEAD)
-#define SCTA__EXTERN_RET(X)  SCTA___RET(X,  -SCTA_HEAD)
-#define SCTA__EXTERN_INT1(X) SCTA___INT1(X, -SCTA_HEAD)
-#define SCTA__EXTERN_INT2(X) SCTA___INT2(X, -SCTA_HEAD)
-#define SCTA__EXTERN_PTR1(X) SCTA___PTR1(X, -SCTA_HEAD)
-#define SCTA__EXTERN_PTR2(X) SCTA___PTR2(X, -SCTA_HEAD)
-
-#define SCTA__INTERN_STORAGE(X) (((char *) X)+SCTA__OFFSET_HEADER+(SCTA__INTERN_SIZE(X)[0]*SCTA__INTERN_LEN(X)[0]+SCTA__INTERN_SIZE(X)[0]))
-#define SCTA__EXTERN_STORAGE(X) ((X)+(SCTA__EXTERN_SIZE(X)[0]*SCTA__EXTERN_LEN(X)[0]+SCTA__EXTERN_SIZE(X)[0]))
-
-
-void* scta_macro_new_(size_t size);
-void scta_macro_free_(void *c);
-bool scta_macro_set_length_(char **z, int newlength);
-bool scta_macro_insert_(char **z);
-bool scta_macro_insert_array_(char **z);
-bool scta_macro_delete_subset_(char **z);
-void* scta_macro_subset_(size_t size, int at, int length, void *p);
-
-
-
-/*
-            ╭──────────╮
-            │          │
-            │   ╭──╮   │
-            │   ╰──╯   │
-            │          │                         ╭────╮ ╭────╮ ╭─╮  
-            │   ╭──────╯ ╭─╮    ╭─╮  ╭─╮ ╭──╮    │ ╭╮ │ │ ╭╮ │ │ │
-            │   │ ╭─╮╭─╮ │ ╰──╮ │ │  │ │ │ ╭╯    │ ╰╯ │ │ ╰╯ │ │ │
-            │   │ │ ││ │ │ ╭╮ │ │ │  │ │ │ │     │ ╭╮ │ │ ╭──╯ │ │
-            │   │ │ ╰╯ │ │ ╰╯ │ │ ╰╮ │ │ │ ╰╮    │ ││ │ │ │    │ │
-            ╰───╯ ╰────╯ ╰────╯ ╰──╯ ╰─╯ ╰──╯    ╰─╯╰─╯ ╰─╯    ╰─╯
-         ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ 
-*/
-
-
-extern FILE *scta_config_debug;
-extern int scta_config_version[3];
-
-
-#define scta_new(type)                              (scta_macro_new_(sizeof(type)))/*
-sctman:scta_new
-
-NAME
-    scta_new
-
-SYNOPSIS
-    bool scta_new(type)
-    
-DESCRIPTION
-    Takes any type as its input, and returns a pointer to a zero length array
-    with elements of the same type.
-
-NOTES
-    This function is implemented as a macro.
-
-RETURN
-    a pointer of type `type *' on success, and null otherwise.
-
-EXAMPLE
-    int *list = scta_new(int);
-    char *list = scta_new(char);
-    struct foo *list = scta_new(struct foo);
-    struct foo **list = scta_new(struct foo *);
-
-*/
-
-
-#define scta_free                                scta_macro_free_/*
-sctman:scta_free
-NAME
-    scta_free
-    
-SYNOPSIS
-    void scta_free(type* array)
-
-DESCRIPTION    
-    Takes a dynamic array and frees it.
-
-RETURN
-    None
-*/
-
-
-#define scta_length(A)                              (SCTA__EXTERN_LEN(A)[0])/*
-sctman:scta_length
-NAME
-    scta_length
-    
-SYNOPSIS
-    int scta_length(type* array)
-
-DESCRIPTION    
-    Returns the length of the array 
-
-RETURN
-    The length of `array' as an int.
-*/
-
-#define scta_set_length(A, newl)                    (scta_macro_set_length_((char **) &(A), newl))/*
-sctman:scta_set_length
-NAME
-    scta_set_length
-
-SYNOPSIS
-    bool scta_set_length(type* array, int newl)
-
-DESCRIPTION    
-    Expands or collapses an array. If newl is larger than the length of the 
-    array, the array is expanded and all new elements are set to zero. If 
-    newl is smaller than the length of the provided array, the array is 
-    collapsed.
-    
-RETURN
-    A boolean value indicating success or failure; stdbool definitions are used.
-    
-
-*/
-
-#define scta_insert(A, where, what)                 ((SCTA__EXTERN_INT1(A)[0]=where),\
-                                                     ((A)[scta_length(A)+1]=what),\
-                                                     scta_macro_insert_((char **) &(A)))/*
-sctman:scta_insert
-NAME
-    scta_insert
-
-SYNOPSIS
-    bool scta_insert(type* array, int where, type what)
-                                                     
-DESCRIPTION    
-    This macro inserts value `what' in a dynamic array `A' at index `where'.
-
-NOTES
-    1.  `where' can be a negative value which denotes the index starting from 
-        the end of the array.
-    2.  `array' is evaluated more than once in this macro.
-    
-RETURN
-    A boolean value indicating success or failure; stdbool definitions are used.
-
-EXAMPLE
-    int *a; // [1, 2, 3]
-    if (!scta_insert(a, 1, 300)) {
-        puts("this macro failed");
-    }
-    a; // [1, 300, 2, 3]
-*/
-                     
-                                                     
-#define scta_insert_array(A, where, target, length) ((SCTA__EXTERN_INT1(A)[0]=(where)),\
-                                                     (SCTA__EXTERN_INT2(A)[0]=(length)),\
-                                                     (SCTA__EXTERN_PTR1(A)[0]=(target)),\
-                                                     scta_macro_insert_array_((char **) &(A)))
-/*
-sctman:scta_insert
-NAME
-    scta_insert_array
-
-SYNOPSIS
-    bool scta_insert(type* array, int where, type what)
-                                                     
-DESCRIPTION    
-    This macro inserts value `what' in a dynamic array `A' at index `where'.
-
-RETURN
-    A boolean value indicating success or failure; stdbool definitions are used.
-
-EXAMPLE
-    int *a; // [1, 2, 3]
-    if (!scta_insert(a, 1, 300)) {
-        puts("this macro failed");
-    }
-    a; // [1, 300, 2, 3]
-*/
-                                                     
-                                                                                             
-#define scta_push(A, what)                          scta_insert((A), INT_MAX, (what))
-
-#define scta_push_array(A, target, length)          (scta_insert_array((A), INT_MAX, (target), (length)))
-
-#define scta_delete_subset(A, where, length)        ((SCTA__EXTERN_INT1(A)[0]=(where)),\
-                                                     (SCTA__EXTERN_INT2(A)[0]=(length)),\
-                                                     scta_macro_delete_subset_((char **) &(A)))
-
-#define scta_pop(A, var)                            (scta_delete_subset((A), INT_MAX, 1) ?\
-                                                     ((var)=((A)[scta_length(A)+1]),true) :\
-                                                     false)
-
-#define scta_subset(array, at, length)              (scta_macro_subset_(sizeof((array[0])), (at), (length), (array)))
-
-#endif

File a/test.c

-#include <stdio.h>
-#include <string.h>
-#include <inttypes.h>
-#include <assert.h>
-
-#include "scta.h"
-
-int main (){
-    
-    scta_config_debug=stderr;
-    {// push tests
-        {// insert size size(int) 
-            int *a = scta_new(int);
-            
-            for (int i = 1; i < 11; ++i) {
-                assert(scta_length(a) == i-1);
-                assert(scta_push(a, i*2));
-            }
-            assert(a[0] == 2);
-            assert(a[1] == 4);
-            assert(a[2] == 6);
-            assert(a[3] == 8);
-            assert(a[4] == 10);
-            assert(a[5] == 12);
-            assert(a[6] == 14);
-            assert(a[7] == 16);
-            assert(a[8] == 18);
-            assert(a[9] == 20);
-            
-            scta_free(a);    
-        }
-        
-        {// insert size 1
-            char *a = scta_new(char);
-            
-            for (int i = 0; i < 10; ++i) {
-                assert(scta_length(a) == i);
-                assert(scta_push(a, 'a'+i));
-            }
-            for (int i = 0; i < 10; ++i) assert(a[i] == 'a'+i);
-            assert(scta_push(a, 0));
-            assert(!strcmp(a, "abcdefghij"));
-            scta_free(a);    
-        }
-        
-        {// insert size 101
-            struct dogs {
-                char strings[100];
-                bool spotted;
-            };
-            
-            struct dogs *a = scta_new(struct dogs);
-            
-            for (int i = 0; i < 10; ++i) {
-                assert(scta_length(a) == i);
-                assert(scta_push(a, ((struct dogs) {.strings="const", .spotted="false"})));
-            }
-            for (int i = 0; i < 10; i+=2) assert(!strcmp(a[i].strings, "const"));
-            
-            scta_free(a);    
-        }        
-    }
-
-    {// insert midpoint
-        int *a = scta_new(int);
-        
-        assert(scta_push(a, 1));
-        assert(scta_push(a, 1));
-        assert(scta_push(a, 1));
-        
-        assert(scta_insert(a, 2, 10));        
-        assert(a[0] == 1);
-        assert(a[1] == 1);
-        assert(a[2] == 10);
-        assert(a[3] == 1);  
-        assert(scta_length(a) == 4);
-        
-        assert(scta_insert(a, 0, 10));
-        assert(a[0] == 10);
-        assert(a[1] == 1);
-        assert(a[2] == 1);
-        assert(a[3] == 10);
-        assert(a[4] == 1);  
-        assert(scta_length(a) == 5);
-        
-        assert(scta_insert(a, 4, 20));
-        assert(a[0] == 10);
-        assert(a[1] == 1);
-        assert(a[2] == 1);
-        assert(a[3] == 10);
-        assert(a[4] == 20);  
-        assert(a[5] == 1);  
-        assert(scta_length(a) == 6);
-        
-        assert(scta_insert(a, 400, 80));
-        assert(a[0] == 10);
-        assert(a[1] == 1);
-        assert(a[2] == 1);
-        assert(a[3] == 10);
-        assert(a[4] == 20);  
-        assert(a[5] == 1);  
-        assert(a[6] == 80);  
-        assert(scta_length(a) == 7);
-        
-
-        assert(scta_insert(a, -2, 13));
-        assert(a[0] == 10);
-        assert(a[1] == 1);
-        assert(a[2] == 1);
-        assert(a[3] == 10);
-        assert(a[4] == 20);  
-        assert(a[5] == 13);  
-        assert(a[6] == 1);  
-        assert(a[7] == 80);  
-        assert(scta_length(a) == 8);
-        
-        assert(scta_insert(a, -1, 77));
-        assert(a[0] == 10);
-        assert(a[1] == 1);
-        assert(a[2] == 1);
-        assert(a[3] == 10);
-        assert(a[4] == 20);  
-        assert(a[5] == 13);  
-        assert(a[6] == 1);  
-        assert(a[7] == 77);  
-        assert(a[8] == 80);  
-        assert(scta_length(a) == 9);                
-
-        assert(scta_insert(a, 0, 11));
-        assert(a[0] == 11);
-        assert(a[1] == 10);
-        assert(a[2] == 1);
-        assert(a[3] == 1);
-        assert(a[4] == 10);
-        assert(a[5] == 20);  
-        assert(a[6] == 13);  
-        assert(a[7] == 1);  
-        assert(a[8] == 77);  
-        assert(a[9] == 80);  
-        assert(scta_length(a) == 10);                        
-        
-        scta_free(a);    
-    }
-    {// testing insert_array
-        int *a = scta_new(int);
-        
-        assert(scta_push(a, 1));
-        assert(scta_push(a, 2));
-        assert(scta_push(a, 3));
-        
-        assert(scta_insert_array(a, 2, ((int[]){10, 20, 30}), 3));        
-        assert(a[0] == 1);
-        assert(a[1] == 2);
-        assert(a[2] == 10);
-        assert(a[3] == 20);
-        assert(a[4] == 30);
-        assert(a[5] == 3);  
-        assert(scta_length(a) == 6);
-        
-        assert(scta_insert_array(a, 0, ((int[]){17, 27, 37}), 3));        
-        assert(a[0] == 17);
-        assert(a[1] == 27);
-        assert(a[2] == 37);
-        assert(a[3] == 1);
-        assert(a[4] == 2);
-        assert(a[5] == 10);
-        assert(a[6] == 20);
-        assert(a[7] == 30);
-        assert(a[8] == 3);  
-        assert(scta_length(a) == 9);
-        
-        assert(scta_insert_array(a, -2, ((int[]){88, 8}), 2));        
-        assert(a[0] == 17);
-        assert(a[1] == 27);
-        assert(a[2] == 37);
-        assert(a[3] == 1);
-        assert(a[4] == 2);
-        assert(a[5] == 10);
-        assert(a[6] == 20);
-        assert(a[7] == 88);
-        assert(a[8] == 8); 
-        assert(a[9] == 30);
-        assert(a[10] == 3);  
-        assert(scta_length(a) == 11);
-        
-        assert(scta_insert_array(a, 1e6, ((int[]){1e6}), 1));        
-        assert(a[0] == 17);
-        assert(a[1] == 27);
-        assert(a[2] == 37);
-        assert(a[3] == 1);
-        assert(a[4] == 2);
-        assert(a[5] == 10);
-        assert(a[6] == 20);
-        assert(a[7] == 88);
-        assert(a[8] == 8); 
-        assert(a[9] == 30);
-        assert(a[10] == 3);  
-        assert(a[11] == 1e6);  
-        assert(scta_length(a) == 12);
-        
-        assert(scta_insert_array(a, 1e6, ((int[]){1e6}), 0));        
-        assert(a[0] == 17);
-        assert(a[1] == 27);
-        assert(a[2] == 37);
-        assert(a[3] == 1);
-        assert(a[4] == 2);
-        assert(a[5] == 10);
-        assert(a[6] == 20);
-        assert(a[7] == 88);
-        assert(a[8] == 8); 
-        assert(a[9] == 30);
-        assert(a[10] == 3);  
-        assert(a[11] == 1e6);  
-        assert(scta_length(a) == 12);
-        
-        scta_free(a);
-        
-        a = scta_new(int);
-        
-        assert(scta_insert_array(a, 0, ((int[]){1, 2, 3, 4, 5 ,6}), 6));        
-        assert(a[0] == 1);
-        assert(a[1] == 2);
-        assert(a[2] == 3);
-        assert(a[3] == 4);
-        assert(a[4] == 5);
-        assert(a[5] == 6);  
-        assert(scta_length(a) == 6);
-        
-        scta_free(a);
-        
-        // insert nothing 
-        a = scta_new(int);
-        assert(scta_insert_array(a, 0, ((int[]){1, 2, 3, 4, 5 ,6}), 0));        
-        assert(scta_length(a) == 0);
-        scta_free(a);
-        
-        // bad indexing
-        a = scta_new(int);
-        scta_config_debug=NULL;
-        assert(!scta_insert_array(a, -1000, ((int[]){1, 2, 3, 4, 5 ,6}), 1));        
-        scta_config_debug=stderr;
-        assert(scta_length(a) == 0);
-        scta_free(a);
-    }
-    
-    
-    {// testing scta_delete_subset
-        int *a = scta_new(int);
-        assert(scta_insert_array(a, 0, ((int[]){1, 2, 3, 4, 5 ,6}), 6));                
-        
-        assert(scta_delete_subset(a, 1, 3));
-        assert(a[0] == 1);
-        assert(a[1] == 5);
-        assert(a[2] == 6);  
-        assert(scta_length(a) == 3);        
-        scta_free(a);
-               
-    }
-        
-    {// testing scta_pop
-        int *a = scta_new(int);
-        assert(scta_insert_array(a, 0, ((int[]){10, 20, 30, 40, 50 ,60}), 6));                
-        int pv = 0;
-        
-        assert(scta_pop(a, pv));
-        assert(scta_length(a) == 5);
-        assert(pv == 60);
-        
-        assert(scta_pop(a, pv));
-        assert(pv == 50);
-        assert(scta_length(a) == 4);
-        
-        assert(scta_pop(a, pv));
-        assert(pv == 40);
-        assert(scta_length(a) == 3);
-        
-        assert(scta_pop(a, pv));
-        assert(pv == 30);
-        assert(scta_length(a) == 2);
-        
-        assert(scta_pop(a, pv));
-        assert(pv == 20);
-        assert(scta_length(a) == 1);
-        
-        assert(scta_pop(a, pv));
-        assert(pv == 10);
-        assert(scta_length(a) == 0);
- 
-        scta_config_debug=NULL;       
-        assert(!scta_pop(a, pv));
-        scta_config_debug=stderr;
-        
-        scta_free(a);
-    }
-    
-    
-    {// testing scta_subset
-        int *a = scta_new(int), *b;
-        assert(scta_insert_array(a, 0, ((int[]){1, 2, 3, 4, 5 ,6}), 6));                
-        
-        assert((b=scta_subset(a, 3, 2)));
-        assert(b[0] == 4);
-        assert(b[1] == 5);
-        assert(scta_length(b) == 2);        
-        scta_free(b);
-        
-        
-        assert((b=scta_subset(a, -1, 1)));
-        assert(b[0] == 6);
-        assert(scta_length(b) == 1);        
-        scta_free(b);
-        
-        scta_free(a);
-    }
-    
-    {// testing scta_set_length
-        int *a = scta_new(int);
-        assert(scta_insert_array(a, 0, ((int[]){1, 2, 3, 4, 5 ,6}), 6));                
-        assert(scta_set_length(a, 3));
-        assert(scta_length(a) == 3);
-        
-        assert(scta_set_length(a, 6));
-        assert(scta_length(a) == 6);
-        assert(a[0] == 1);
-        assert(a[1] == 2);
-        assert(a[2] == 3);
-        assert(a[3] == 0);
-        assert(a[4] == 0);
-        assert(a[5] == 0);
-        
-        scta_free(a);
-        
-        // grind test, just in case
-        uint64_t *z = scta_new(uint64_t);
-        assert(scta_set_length(z, 20000));
-        
-        for (int i = 0; i < 20000; ++i) z[i] = i*i;
-        for (int i = 0; i < 20000; ++i) assert(z[i] == (uint64_t) i*i);
-        assert(scta_set_length(z, 10000));
-        assert(scta_set_length(z, 20000));
-        for (int i = 0; i < 10000; ++i) assert(z[i] == (uint64_t) i*i);
-        for (int i = 10000; i < 20000; ++i) assert(z[i] == 0);
-        
-        scta_free(z);
-    }
-    
-    printf("[ok] %10s %d:%d:%d    %s\n", "scta", 
-        scta_config_version[0], scta_config_version[1], 
-        scta_config_version[2], __TIMESTAMP__);
-    return 0;
-}

File ac/Makefile

-test: sctac.* test.c
-	gcc -o test -std=c99 -pedantic -g -Wall -Wextra -I../a ../a/scta.c sctac.c test.c
-
-memcheck: test
-	valgrind --tool=memcheck ./test
-
-clean:
-	rm test

File ac/sctac.c

-/*
-
-    sctac: Mutable Character Array Module
-
-    Sulaiman (seininn) Mustafa     2014-02-26
-    
-    This module is a part of libstc, a modular, c99/c1x-compliant, 
-    toolkit library. use stcmod to determine this module's 
-    dependencies, if any.
-    
-*/
-
-#include "scta.h"
-#include <string.h>
-
-FILE *sctac_config_debug = NULL;
-int sctac_config_version[3] = {1, 0, 0};
-
-char *sctac_insert_(char **string, char *appendee, int at){
-    char *s = *string;
-    int len = strlen(appendee);
-    
-    if (!scta_insert_array(s, at, appendee, len)) {
-        return NULL;
-    }
-    
-    *string = s;
-    return s;
-}
-
-char *sctac_append_(char **string, char *appendee){
-    return sctac_insert_(string, appendee, scta_length(*string));
-}
-
-
-char *sctac_delete_(char **string, int start, int length){
-    char *s = *string;
-    
-    if (!scta_delete_subset (s, start, length)) {
-        return NULL;
-    }
-    
-    *string = s;
-    return s;
-}
-
-
-char *sctac_clone_(char **string, int start, int length){
-    char *s = *string;
-    
-    if (!scta_subset (s, start, length)) {
-        return NULL;
-    }
-    
-    *string = s;
-    return s;
-}
-
-

File ac/sctac.h

-/*
-
-    sctac: Mutable Character Array Module
-
-    Sulaiman (seininn) Mustafa     2014-02-26
-    
-    This module is a part of libstc, a modular, c99/c1x compliant, 
-    toolkit library. use stcmod to determine this module's 
-    dependencies, if any.
-    
-*/
-
-#ifndef SCTAC_H
-#define SCTAC_H
-
-extern FILE *sctac_config_debug;
-extern int sctac_config_version[3];
-
-
-char *sctac_insert_(char **string, char *appendee, int at);
-char *sctac_append_(char **string, char *appendee);
-char *sctac_delete_(char **string, int start, int length);
-char *sctac_clone_(char **string, int start, int length);
-
-#define sctac_insert(S, A, T) sctac_insert_(&(S), (A), (T))
-#define sctac_append(S, A) sctac_append_(&(S), (A))
-#define sctac_delete(S, B, L) sctac_delete_(&(S), (B), (L))
-#define sctac_clone(S, B, L) sctac_clone_(&(S), (B), (L))
-
-
-#endif

File ac/test.c

-#include <stdio.h>
-#include "scta.h"
-#include "sctac.h"
-
-int main(){
-    /*
-    char *s;
-    s = scta_new(char);
-    puts(s);
-    sctac_append(s, "hello their my friend!");
-    puts(s);
-    sctac_insert(s, "epic ", -7);
-    puts(s);
-    sctac_delete(s, 1, 7);
-    puts(s);
-    sctac_delete(s, 0, 5);
-    puts(s);
-    scta_free(s);
-    */
-
-    printf("[ok] %10s %d:%d:%d    %s\n", "sctac",
-        sctac_config_version[0], sctac_config_version[1], 
-        sctac_config_version[2], __TIMESTAMP__);    
-    return 0;
-    
-}

File checklib

-#!/bin/bash
-
-test(){
-	cd "$1"
-	printf "\e[1;31m"
-	make -s test 2>&1 > /dev/null || {
-		echo "make failed for '$1'."
-		printf "\e[0m"
-		exit 1
-	}
-	printf "\e[0m"
-
-	printf "\e[1m"
-	./test || exit 1
-	printf "\e[0m"
-	make -s clean 2>&1 > /dev/null
-	cd - > /dev/null
-
-}
-
-test "a"
-test "ac"
-test "frame"
-test "time"
-test "os"
-test "ml"

File frame/Makefile

-test: sctframe.* test.c
-	gcc -o test -std=c99 -pedantic -g -Wall -I../a ../a/scta.c sctframe.c test.c
-
-memcheck: test
-	valgrind --tool=memcheck ./test
-
-clean:
-	rm test

File frame/sctframe.c

-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-#include "sctframe.h"
-#include "scta.h"
-
-FILE *sctframe_config_debug = NULL;
-int sctframe_config_version[3] = {1, 0, 0};
-
-sctframe_t *sctframe_new() {
-    sctframe_t *f = malloc(sizeof(sctframe_t));
-    if (!f) {
-        // bad memory
-        return NULL;
-    }
-    f->records = scta_new(struct record);
-    if (!f->records) {
-        // darray fail
-        free(f);
-        return NULL;
-    } 
-    return f;
-}
-
-
-
-void *sctframe_add_(sctframe_t *f, ...) 
-{
-    struct record r;
-    
-    va_list ap;
-    va_start(ap, f);
-    
-    if (!(r.address = va_arg(ap, void *))) goto EXIT;
-    r.freef = va_arg(ap, void (*)(void *));
-    
-    
-    if (!scta_push(f->records, r)) {
-        // could not store array
-        r.address = NULL;
-        goto EXIT;
-    }
-    
-    EXIT:
-    va_end(ap);
-    return r.address;
-}
-
-void sctframe_free(sctframe_t *f) {
-    for (int i = 0; i < scta_length(f->records); ++i) {
-        if (f->records[i].freef) f->records[i].freef(f->records[i].address);
-        else free(f->records[i].address);
-    }
-    scta_free(f->records);
-    free(f);
-}
-

File frame/sctframe.h

-#ifndef SCTFRAME_H
-#define SCTFRAME_H
-
-extern FILE *sctframe_config_debug;
-extern int sctframe_config_version[3];
-
-struct record {
-    void *address;
-    void (*freef)(void *);
-};
-
-typedef struct {
-    struct record *records;
-} sctframe_t;
-
-
-sctframe_t *sctframe_new();
-void *sctframe_add_(sctframe_t *f, ...);
-void sctframe_free(sctframe_t *f);
-
-#define C(f, ...) (sctframe_add_(f, __VA_ARGS__, NULL))
-
-#endif

File frame/test.c

-#include <stdio.h>
-#include <stdlib.h>
-#include <assert.h>
-
-#include "sctframe.h"
-
-
-void freecustom(void *ptr){
-    free( (char *) ptr-4);
-}
-
-int main (int argc, char **argv){
-    sctframe_t * f = sctframe_new();
-    
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, malloc(100)));
-    assert(C(f, (char *) malloc(100)+4, freecustom));
-    assert(C(f, (char *) malloc(100)+4, freecustom));
-    
-    sctframe_free(f);
-    
-    
-    
-    printf("[ok] %10s %d:%d:%d    %s\n", "sctframe",
-        sctframe_config_version[0], sctframe_config_version[1], 
-        sctframe_config_version[2], __TIMESTAMP__);
-    return 0;
-}

File ml/Makefile

-name=ml
-
-test: sct$(name).* test.c
-	gcc -o test -std=c99 -pedantic -g -Wall -I../str -I../a -I../os sct$(name).c ../str/sctstr.c ../os/sctos.c ../a/scta.c test.c
-
-memcheck: test
-	valgrind --tool=memcheck ./test
-
-clean:
-	rm test

File ml/sctml.c

-/*
-
-    sctml: Usefull HTML Routines
-    Sulaiman (seininn) Mustafa
-    Date: 2014-01-21
-    
-*/
-
-#define _POSIX_C_SOURCE 200809L
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdbool.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <unistd.h>
-#include <errno.h>
-
-#include "sctstr.h"
-#include "sctos.h"
-#include "scta.h"
-
-
-
-FILE *sctml_config_debug = NULL;
-int sctml_config_version[3] = {1, 0, 1};
-
-char *sctml_percent_encode(char *s, char *exceptions){
-    // implemented what I needed, prob. doesn't conferm to spec. Fix later
-    char *out = NULL;
-    
-    if (!exceptions) exceptions = "";
-    
-    for (;*s;++s) {
-        if ((*s >= 0x20 && *s < 0x30) && !strchr(exceptions, *s)) {
-            char buf[4];
-            snprintf(buf, 4, "%%%x", *s);
-            sctstr_append(&out, buf);
-        }
-        else sctstr_append(&out, (char [2]) {*s, 0});
-    }
-    return out;
-}
-
-char *sctml_xml_escape(char *s, char *exceptions){
-    // implemented what I needed, prob. doesn't conferm to spec. Fix later
-    char *out = NULL, *ptr;
-    char *list_in = "\"'<>&";
-    char *list_out[] = {"quot", "apos", "lt", "gt", "amp"};
-    
-    if (!exceptions) exceptions = "";
-    
-    for (;*s;++s) {
-        if ((ptr = strchr(list_in, *s)) && !strchr(exceptions, *s)) {
-            char buf[7] = {0};
-            strcat(buf, "&");
-            strcat(buf, list_out[ptr-list_in]);
-            strcat(buf, ";");
-            sctstr_append(&out, buf);
-        }
-        else sctstr_append(&out, (char [2]) {*s, 0});
-    }
-    return out;    
-}
-
-
-char **sctml_get_tags(char *string, char *tag){
-    #define ERROR_PROC {\
-        scta_free(opening);\
-        scta_free(closing);\
-        for (int i = 0; i < scta_length(list); ++i) free(list[i]);\
-        scta_free(list);\
-        return NULL;\
-    }
-        
-    #define OP_JUMP_CALC {\
-        ++c;\
-        i+=opening_length;\
-        {\
-            char *tc = strstr(string+i, ">");\
-            if (tc) {\
-                i=tc-string;\
-            }\
-            else ERROR_PROC\
-        }\
-    }
-        
-    
-    
-    int tag_length = strlen(tag);
-    
-    char *opening, *closing;
-    int opening_length, closing_length;
-    
-    char *t;
-    
-    // <tag
-    t = scta_new(char);
-    scta_push_array(t, "<", 1);
-    scta_push_array(t, tag, tag_length+1);
-    opening = t;
-    opening_length = tag_length+1;
-    
-    // </tag>
-    t = scta_new(char);
-    scta_push_array(t, "</", 2);
-    scta_push_array(t, tag, tag_length);
-    scta_push_array(t, ">", 2);
-    closing = t;
-    closing_length = tag_length+3;
-    
-    
-    char **list = scta_new(char *);
-
-    while (*string) {
-        // first occurence
-        int c = 0; // match counter 
-        int i = 0; // index
-        
-        string = strstr(string, opening);
-        
-        // if not found break, else skip to after opining string
-        if (!string) break;
-        else OP_JUMP_CALC
-
-        
-        // ignore submatches
-        while (*(string+i) && c) {
-            if (!strncmp(string+i, opening, opening_length)) {
-                OP_JUMP_CALC
-                continue;
-            }
-            if (!strncmp(string+i, closing, closing_length)) {
-                --c;
-                i+=closing_length;
-                continue;
-            }
-            ++i;
-        }
-        
-        if (c) {
-            //error
-            ERROR_PROC
-        }
-        if (i) { //match
-            char *p = malloc(i+1);
-            if (!p) {
-                //error
-                ERROR_PROC
-            }
-            strncpy(p, string, i);
-            p[i] = 0;
-            scta_push(list, p);
-        }
-        
-        string = string+i;
-    }
-    scta_free(opening);
-    scta_free(closing);
-    scta_push(list, NULL);
-    return list;
-}
-
-void sctml_free_tags(char **list) {
-    if (scta_length(list)) for (int i = 0; list[i]; ++i) free(list[i]);
-    scta_free(list);
-}
-
-
-
-
-
-
-char *sctml_strip_tags(char *tag){
-    char *start = strchr(tag, '>');
-    char *end = strrchr(tag, '<');
-    
-    if (!start || !end) {
-        return NULL;
-    }
-    
-    if (start > end) {
-        return NULL;
-    }
-    
-    return strndup(start+1, end-start-1);
-}
-
-
-
-char **sctml_get_tags_from_file(char *filename, char *tag){
-    // Also consider using lim for a more robust method (will be equivilant to js getTextContent)
-    // HERE
-    char *buf;
-    if (!sctos_load(filename, &buf)) {
-        if (sctml_config_debug) fprintf(sctml_config_debug, "failed to load `%s'. enable sctos debuging for further information.\n", filename);
-        return NULL;
-    }
-    char **ret = sctml_get_tags(buf, tag);
-    free(buf);
-    return ret;
-}
-

File ml/sctml.h

-/*
-
-    sctml: Usefull XML/HTML Routines
-    Sulaiman (seininn) Mustafa
-    Date: 2014-01-21
-    
-*/
-
-#ifndef sctml_H
-#define sctml_H
-
-#include <stdbool.h>
-#include <stdio.h>
-
-extern FILE *sctml_config_debug;
-extern int sctml_config_version[3];
-
-
-char **sctml_get_tags(char *string, char *tag);
-char **sctml_get_tags_from_file(char *filename, char *tag);
-char *sctml_strip_tags(char *tag);
-void sctml_free_tags(char **list);
-
-char *sctml_percent_encode(char *s, char *exceptions);
-char *sctml_xml_escape(char *s, char *exceptions);
-
-#endif

File ml/test.c

-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <assert.h>
-#include <string.h>
-
-#include "sctml.h"
-#include "scta.h"
-
-int main (int argc, char **argv){
-    char *p[6];
-    assert(!strcmp(p[0]=sctml_percent_encode(" !\"#$%&'()*+,-./", NULL), 
-        "%20%21%22%23%24%25%26%27%28%29%2a%2b%2c%2d%2e%2f"));
-    assert(!strcmp(p[1]=sctml_percent_encode("a s!d\"f#g$h%j&k'l(z)x*c+v,b-n.m/q", NULL), 
-        "a%20s%21d%22f%23g%24h%25j%26k%27l%28z%29x%2ac%2bv%2cb%2dn%2em%2fq"));
-    assert(!strcmp(p[2]=sctml_percent_encode(" !\"#$%&'()*+,-./", ""), 
-        "%20%21%22%23%24%25%26%27%28%29%2a%2b%2c%2d%2e%2f"));
-    assert(!strcmp(p[3]=sctml_percent_encode(" !\"#$%&'()*+,-./", " ()+ /"), 
-        " %21%22%23%24%25%26%27()%2a+%2c%2d%2e/"));
-        
-    assert(!strcmp(p[4]=sctml_xml_escape("<>&\"'", NULL), 
-        "&lt;&gt;&amp;&quot;&apos;"));
-    assert(!strcmp(p[5]=sctml_xml_escape("<>&\"'", ">"), 
-        "&lt;>&amp;&quot;&apos;"));
-    
-    
-    for (int i= 0; i< 6; ++i) free(p[i]);
-    
-    char **list = sctml_get_tags("<test id='temp'>111</test><test>22</test>  <test>3</test>", "test");
-    assert(list);
-    assert(!strcmp(list[0], "<test id='temp'>111</test>"));
-    assert(!strcmp(list[1], "<test>22</test>"));
-    assert(!strcmp(list[2], "<test>3</test>"));
-    assert(!list[3]);
-    sctml_free_tags(list);
-    
-    list = sctml_get_tags("   <test>3</test>    ", "test");
-    assert(list);
-    assert(!strcmp(list[0], "<test>3</test>"));
-    assert(!list[1]);
-    sctml_free_tags(list);
-    
-    list = sctml_get_tags("   <test><test>hi mom</test></test> <test></test>   ", "test");
-    assert(list);
-    assert(!strcmp(list[0], "<test><test>hi mom</test></test>"));
-    assert(!strcmp(list[1], "<test></test>"));
-    assert(!list[2]);
-    sctml_free_tags(list);
-    
-    assert(!sctml_get_tags("   <test><test>hi mom</test></test> <test>   ", "test"));
-    assert(!sctml_get_tags("   <test><test>hi mom</test>   ", "test"));
-    
-    list = sctml_get_tags_from_file("test.d/test.xml", "title");
-    assert(list);
-    assert(!strcmp(list[0], "<title>some text</title>"));
-    assert(!list[1]);
-    sctml_free_tags(list);
-    
-    
-    
-    char *z;
-    #define TEST_STRIP_TAGS(TAG, RESULT)\
-    z=sctml_strip_tags(TAG);\
-    assert(!(!RESULT && z));\
-    assert(!(RESULT && !z));\
-    if (RESULT) assert(!(strcmp(z, RESULT?RESULT:"(NULL)")));\
-    free(z);
-    
-    TEST_STRIP_TAGS("<jaja>1</jaja>", "1")
-    TEST_STRIP_TAGS("<jaja some=stuff>22</jaja>", "22")
-    TEST_STRIP_TAGS("<jaja some=stuff></jaja>", "")
-    TEST_STRIP_TAGS("<jaja some=stuff>", NULL)
-    
-    
-    
-    
-    
-    printf("[ok] %10s %d:%d:%d    %s\n", "sctml",
-        sctml_config_version[0], sctml_config_version[1], 
-        sctml_config_version[2], __TIMESTAMP__);
-    return 0;
-}

File ml/test.d/test.xml

-<test>
-	<title>some text</title>
-</test>

File modules/a/Makefile

+test: scta.* test.c
+	gcc -o test -std=c99 -pedantic -g -Wall -Wextra scta.c test.c
+
+memcheck: test
+	valgrind --tool=memcheck ./test
+
+clean:
+	rm test

File modules/a/TODO

+- Add sorted_insert?

File modules/a/scta.c

+/*
+
+    scta: Generic Dynamic Array Module
+
+    Sulaiman (seininn) Mustafa     2014-02-26
+    
+    This module is a part of libstc, a modular, c99/c1x-compliant, 
+    toolkit library. use stcmod to determine this module's 
+    dependencies, if any.
+    
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include "scta.h"
+
+
+FILE *scta_config_debug = NULL;
+int scta_config_version[3] = {1, 1, 1};
+
+/*
+    internal array layout
+
+    +------------------+
+    |       SIZE       |  <- internal pointer points here
+    +------------------+
+    |      LENGTH      |
+    +------------------+
+    |      RETURN      |  used to be used for return status, might remove later
+    +------------------+
+    |   ARGUMENT_INT_1 |  argument regesters for functions to avoid multiple 
+    +------------------+  macro argument invokations. unfortunetly, the array
+    |   ARGUMENT_INT_2 |  argument must be invoked more than once. (that, or
+    +------------------+  use statement expressions wich makes this non-c code)
+    |   ARGUMENT_PTR_1 |  :
+    +------------------+  :
+    |   ARGUMENT_PTR_2 |  :
+    +------------------+  '
+    |     ELEMENT_0    |  <- external pointer points here 
+    +------------------+
+    +---------:--------+
+    +---------:--------+
+    +------------------+
+    |     ELEMENT_N    |
+    +------------------+
+    |         0        |  Auto-null terminated
+    +------------------+
+    |      STORAGE     |  (same size as normal array elements)
+    +------------------+
+    
+*/
+
+#define ERRMSG_AND_RETURN(RET, ...) {\
+    if (scta_config_debug) {\
+        fprintf(scta_config_debug, "scta:%s():%d: ", __func__, __LINE__);\
+        fprintf(scta_config_debug, __VA_ARGS__);\
+        fprintf(scta_config_debug, "\n");\
+    }\
+    return (RET); \
+}
+
+#define ___INTERNAL_INT_ARRAY_PRINTER___\
+    fprintf(stderr, "length: %d, size: %zu, { ", SCTA__INTERN_LEN(ra)[0], SCTA__INTERN_SIZE(ra)[0]);\
+    for (int i = 0; i < SCTA__INTERN_LEN(ra)[0]+2; ++i) fprintf(stderr, "%d ", ((int *)((char *) ra + SCTA_HEAD))[i]);\
+    fprintf(stderr, "} \n");
+
+
+// XXX EXTERN SHOULD NOT APPEAR IN THIS DOCUMENT
+
+bool make_space(void **ra, int at, int count){
+    // makes a space inside *ra, and moves everything (including storage) to the right
+    // count is the number of elements to remove and has nothing to do with size
+    size_t size = SCTA__INTERN_SIZE(*ra)[0];
+    int length = SCTA__INTERN_LEN(*ra)[0];
+    void *temp;
+    
+    if (!size) 
+        ERRMSG_AND_RETURN(false, "element size can not be zero.")
+    
+    if (length == INT_MAX) 
+        ERRMSG_AND_RETURN(false, "cannot increase array size do to int limit.")
+        
+    if (!(temp=realloc(*ra, (SCTA_HEAD)+ size*length + size*count + size + size))) 
+        ERRMSG_AND_RETURN(false, "memory operation failed: new size is %zu", ((SCTA_HEAD+size)+size*length+size+size))
+    *ra = temp;
+    
+    
+    memmove( ((char *) *ra) + SCTA_HEAD + at*size + size*count, 
+             ((char *) *ra) + SCTA_HEAD + at*size, 
+             (length*size) - (at*size) + size + size);
+    
+    
+    SCTA__INTERN_LEN(*ra)[0]+=count;
+    return true;
+}
+
+bool collapse_space(void **ra, int at, int count){
+    // removes a space from *ra, and moves everything (including storage) to the left
+    // count is the number of elements to remove and has nothing to do with size
+    size_t size = SCTA__INTERN_SIZE(*ra)[0];
+    int length = SCTA__INTERN_LEN(*ra)[0];
+    void *temp;
+    
+    if (!size) 
+        ERRMSG_AND_RETURN(false, "element size can not be zero.")
+    
+    if (!length) 
+        ERRMSG_AND_RETURN(false, "cannot shorten a zero length array")
+        
+    
+    memmove( ((char *) *ra) + SCTA_HEAD + at*size, 
+             ((char *) *ra) + SCTA_HEAD + at*size + size*count, 
+             (length*size) - (at*size + size*count) + size + size);
+    
+    if (!(temp=realloc(*ra, SCTA_HEAD + size*length - size*count + size + size))) 
+        ERRMSG_AND_RETURN(false, "memory operation failed: new size is %zu", ((SCTA_HEAD+size)+size*length-size))
+    *ra = temp;
+    
+    SCTA__INTERN_LEN(*ra)[0] -= count;
+    return true;
+}
+
+
+void* make_raw_array(size_t size){
+    void *ra;
+    
+    if (!size) 
+        ERRMSG_AND_RETURN(NULL, "requested array member size is 0. minimum is 1.")
+    
+    if (!(ra = malloc(SCTA_HEAD + size + size)))
+        ERRMSG_AND_RETURN(NULL, "could not allocate enough memory: requested %zu", SCTA_HEAD + size)
+        
+    memset(ra, 0, SCTA_HEAD + size + size);
+    
+    /* debugging macros
+    fprintf(stderr, "base %p\n", c);
+    fprintf(stderr, "size loc %p\n", SCTA__INTERN_SIZE(c));
+    fprintf(stderr, "len loc %p\n", SCTA__INTERN_LEN(c));
+    fprintf(stderr, "MTS: 0x%lx (0x%lx, 0x%lx, 0x%lx)\n", SCTA_HEAD, sizeof(size_t), sizeof(int), sizeof(bool));
+    fprintf(stderr, "len loc %p\n", SCTA__INTERN_LEN(c));
+    */
+    
+    SCTA__INTERN_SIZE(ra)[0] = size;
+    SCTA__INTERN_LEN(ra)[0] = 0;
+    
+    return ra;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// Macro functions. Dont forget:
+// -- to differeantiat between internal functions and macro ones and:
+// -- convert arrays to raw arrays and vice versa when nessary by sub/add SCTA__OFFSET_HEADER
+// -- functions here must not use EXTERN functions for concistancy.
+// -- arguments are stored in the array itself. the specification of this is in the function's comment
+// -- arrays passed by macros are in there normal form and not raw form
+
+void* scta_macro_new_(size_t size){/**/
+    void *ra = make_raw_array(size);
+    if (ra) return ((char *)ra)+SCTA_HEAD;
+    else return NULL;
+}
+
+void scta_free(void *c){ 
+    if (!c) return;
+    free((char *)c-SCTA_HEAD); 
+}
+
+
+bool scta_macro_set_length_(char **z, int newl){
+    void *ra = *z-SCTA_HEAD;
+    int oldl = SCTA__INTERN_LEN(ra)[0];
+    int size = SCTA__INTERN_SIZE(ra)[0];
+    if (newl > oldl) {
+        if (!make_space(&ra, oldl, newl-oldl)) return false;
+        memset((char *)ra+SCTA_HEAD+(oldl*SCTA__INTERN_SIZE(ra)[0]), 0, (newl-oldl)*size + size + size);
+    }
+    if (newl < oldl) {
+        if (!collapse_space(&ra, newl, oldl-newl)) return false;
+    }
+    
+    *z = (char *) ra + SCTA_HEAD;
+    return true;    
+}
+
+bool scta_macro_insert_(char **z){/*
+    inserts an element in an array
+    
+    INT1 : at
+    STORAGE: what
+*/
+    void *ra = *z-SCTA_HEAD;
+    
+    
+    size_t size = SCTA__INTERN_SIZE(ra)[0];
+    int oldl = SCTA__INTERN_LEN(ra)[0];
+
+    int at = SCTA__INTERN_INT1(ra)[0];
+    
+    // if negative indexing: normalize
+    if (at < 0) at = oldl + at;
+    // if at is larger than length of array, set to insert to length
+    if (at > oldl) at = oldl;
+    
+    
+    if ( at < 0) 
+        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
+                                 "\tlength: %d\n" 
+                                 "\top index at: %d\n", oldl, at)
+    
+    if (!make_space(&ra, at, 1)) return false;
+    
+    memmove(    ((char *) ra) + SCTA_HEAD + size*at, 
+                SCTA__INTERN_STORAGE(ra), size);
+    
+    
+    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
+    *z = (char *) ra + SCTA_HEAD;
+    return true;
+}
+
+bool scta_macro_insert_array_(char **z){/*
+    inserts an element in an array
+    
+    INT1 : at
+    INT2 : length
+    PTR1: pointer
+*/
+    void *ra = *z-SCTA_HEAD;    
+    
+    size_t size = SCTA__INTERN_SIZE(ra)[0];
+    int oldl = SCTA__INTERN_LEN(ra)[0];
+
+    int target_length = SCTA__INTERN_INT2(ra)[0];
+    void *target_addr = SCTA__INTERN_PTR1(ra)[0];
+
+    int at = SCTA__INTERN_INT1(ra)[0];
+    
+    // normalize index if negative
+    if (at < 0) at = oldl + at;
+    // set after last element if index is larger than array length
+    if (at > oldl) at = oldl;
+    
+    if ( at < 0) 
+        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
+                                  "\tlength: %d\n" 
+                                 "\top index at: %d\n", oldl, at)
+    
+    if (!make_space(&ra, at, target_length)) return false;
+    
+    memmove(    ((char *) ra) + SCTA_HEAD + size*at, 
+                target_addr , size*target_length);
+    
+    
+    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
+    *z = (char *) ra + SCTA_HEAD;
+    return true;
+}
+
+
+bool scta_macro_delete_subset_(char **z){/*
+    deletes a subset that starts at `at' and has a length of `length'
+    
+    input
+    
+    INT1 : at
+    INT2 : length
+    
+    output:
+    STORAGE fist element in deleted subset
+    
+*/
+    void *ra = *z-SCTA_HEAD;    
+    
+    size_t size = SCTA__INTERN_SIZE(ra)[0];
+    int oldl = SCTA__INTERN_LEN(ra)[0];
+
+    int target_length = SCTA__INTERN_INT2(ra)[0];
+
+    int at = SCTA__INTERN_INT1(ra)[0];
+    // normalze if index is negative
+    if (at < 0) at = oldl + at;
+    // set index BEFORE last element if larger than length (so that the last 
+    // element is deleted
+    if (at > oldl) at = oldl-1;
+    
+    if ( oldl < (at+target_length) || at < 0) 
+        ERRMSG_AND_RETURN(false, "inconsistant paramiters:\n" 
+                                 "\tlength: %d\n" 
+                                 "\tdeletion starts at: %d\n" 
+                                 "\tand spans %d element(s)\n", oldl, at, target_length)
+
+    
+    memmove( SCTA__INTERN_STORAGE(ra), 
+            ((char *) ra) + SCTA_HEAD + size*at, size);
+    
+    if (!collapse_space(&ra, at, target_length)) return false;
+    
+    /*REMMOVE LATER */ memset((char *) ra + SCTA_HEAD + size * SCTA__INTERN_LEN(ra)[0], 0, size);
+    *z = (char *) ra + SCTA_HEAD;
+    return true;
+}
+
+
+
+// APPENDIX A: EXTERNAL CODE
+void* scta_macro_subset_(size_t size, int at, int length, void *p){
+    void *n = scta_macro_new_(size);
+    if (!n) return NULL;
+    
+    if (at < 0) at = SCTA__EXTERN_LEN(p)[0] + at;
+    
+    if(!scta_insert_array(n, 0, (char *) p + at*SCTA__EXTERN_SIZE(p)[0], length)) return NULL;
+    else return n;
+}
+
+
+
+bool scta_macro_in_(void *p){
+    char *a = p;
+    int size = SCTA__EXTERN_SIZE(p)[0];
+    int len = SCTA__EXTERN_LEN(p)[0];
+    void *what = a+size*(len+1);
+    
+    int i = 0;
+    for(; i < len; ++i) if (!memcmp(a+(i*size), what, size)) break;
+    if (i < len) return true;
+    else return false;
+}

File modules/a/scta.h

+/*
+
+    scta: Generic Dynamic Array Module
+
+    Sulaiman (seininn) Mustafa     2014-02-26
+    
+    This module is a part of libstc, a modular, c99/c1x-compliant, 
+    toolkit library. use stcmod to determine this module's 
+    dependencies, if any.
+    
+*/
+
+#ifndef SCTA_H
+#define SCTA_H
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <limits.h>
+
+
+
+/*
+‎         .                 لا تستخدم الماكروات التالية واقتصر على الماكروات
+‎        ╱ ╲           ‫المعرفة في "PUBLIC API". استغرار هذه الماكروات غير مضمون.
+‎       ╱ | ╲
+‎      ╱  ·  ╲           Do NOT use the following macros and limit your use
+‎     ∙───────∙         to the macros defined under "PUBLIC API". This macros
+                                  are not garanteed to be stable.
+
+*/
+
+#define SCTA__OFFSET_SIZE 0
+#define SCTA__OFFSET_LEN  (SCTA__OFFSET_SIZE + sizeof(size_t))
+#define SCTA__OFFSET_RET  (SCTA__OFFSET_LEN + sizeof(int))
+#define SCTA__OFFSET_INT1 (SCTA__OFFSET_RET + sizeof(bool))
+#define SCTA__OFFSET_INT2 (SCTA__OFFSET_INT1 + sizeof(int))
+#define SCTA__OFFSET_PTR1 (SCTA__OFFSET_INT2 + sizeof(int))
+#define SCTA__OFFSET_PTR2 (SCTA__OFFSET_PTR1 + sizeof(void *))
+#define SCTA__OFFSET_HEADER  (SCTA__OFFSET_PTR2 + sizeof(void *))
+
+#define SCTA_HEAD SCTA__OFFSET_HEADER
+
+
+
+#define SCTA___SIZE(PTR, OFFSET)  ((size_t *) (((char *) PTR) + SCTA__OFFSET_SIZE   + OFFSET))
+#define SCTA___LEN(PTR, OFFSET)   ((int *)    (((char *) PTR) + SCTA__OFFSET_LEN    + OFFSET))
+#define SCTA___RET(PTR, OFFSET)   ((bool *)   (((char *) PTR) + SCTA__OFFSET_RET    + OFFSET))
+#define SCTA___INT1(PTR, OFFSET)  ((int *)    (((char *) PTR) + SCTA__OFFSET_INT1   + OFFSET))
+#define SCTA___INT2(PTR, OFFSET)  ((int *)    (((char *) PTR) + SCTA__OFFSET_INT2   + OFFSET))
+#define SCTA___PTR1(PTR, OFFSET)  ((void **)  (((char *) PTR) + SCTA__OFFSET_PTR1   + OFFSET))
+#define SCTA___PTR2(PTR, OFFSET)  ((void **)  (((char *) PTR) + SCTA__OFFSET_PTR2   + OFFSET))
+
+
+
+// returns the size, length, and status of the true bigening of the array (internal)
+#define SCTA__INTERN_SIZE(X) SCTA___SIZE(X, 0)
+#define SCTA__INTERN_LEN(X)  SCTA___LEN(X, 0)
+#define SCTA__INTERN_RET(X)  SCTA___RET(X, 0)
+#define SCTA__INTERN_INT1(X) SCTA___INT1(X, 0)
+#define SCTA__INTERN_INT2(X) SCTA___INT2(X, 0)
+#define SCTA__INTERN_PTR1(X) SCTA___PTR1(X, 0)
+#define SCTA__INTERN_PTR2(X) SCTA___PTR2(X, 0)
+
+
+
+
+// returns the size, length, and status of apparent bigening of the array (external)
+#define SCTA__EXTERN_SIZE(X) SCTA___SIZE(X, -SCTA_HEAD)
+#define SCTA__EXTERN_LEN(X)  SCTA___LEN(X,  -SCTA_HEAD)
+#define SCTA__EXTERN_RET(X)  SCTA___RET(X,  -SCTA_HEAD)
+#define SCTA__EXTERN_INT1(X) SCTA___INT1(X, -SCTA_HEAD)
+#define SCTA__EXTERN_INT2(X) SCTA___INT2(X, -SCTA_HEAD)
+#define SCTA__EXTERN_PTR1(X) SCTA___PTR1(X, -SCTA_HEAD)
+#define SCTA__EXTERN_PTR2(X) SCTA___PTR2(X, -SCTA_HEAD)
+
+#define SCTA__INTERN_STORAGE(X) (((char *) X)+SCTA__OFFSET_HEADER+(SCTA__INTERN_SIZE(X)[0]*SCTA__INTERN_LEN(X)[0]+SCTA__INTERN_SIZE(X)[0]))
+#define SCTA__EXTERN_STORAGE(X) ((X)+(SCTA__EXTERN_SIZE(X)[0]*SCTA__EXTERN_LEN(X)[0]+SCTA__EXTERN_SIZE(X)[0]))
+
+
+void* scta_macro_new_(size_t size);
+void scta_free(void *c);
+bool scta_macro_set_length_(char **z, int newlength);
+bool scta_macro_insert_(char **z);
+bool scta_macro_insert_array_(char **z);
+bool scta_macro_delete_subset_(char **z);
+void* scta_macro_subset_(size_t size, int at, int length, void *p);
+bool scta_macro_in_(void *p);
+
+
+/*
+            ╭──────────╮
+            │          │
+            │   ╭──╮   │
+            │   ╰──╯   │
+            │          │                         ╭────╮ ╭────╮ ╭─╮  
+            │   ╭──────╯ ╭─╮    ╭─╮  ╭─╮ ╭──╮    │ ╭╮ │ │ ╭╮ │ │ │
+            │   │ ╭─╮╭─╮ │ ╰──╮ │ │  │ │ │ ╭╯    │ ╰╯ │ │ ╰╯ │ │ │
+            │   │ │ ││ │ │ ╭╮ │ │ │  │ │ │ │     │ ╭╮ │ │ ╭──╯ │ │
+            │   │ │ ╰╯ │ │ ╰╯ │ │ ╰╮ │ │ │ ╰╮    │ ││ │ │ │    │ │
+            ╰───╯ ╰────╯ ╰────╯ ╰──╯ ╰─╯ ╰──╯    ╰─╯╰─╯ ╰─╯    ╰─╯
+         ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ ⇩ 
+*/
+
+
+extern FILE *scta_config_debug;
+extern int scta_config_version[3];
+
+
+#define scta_new(type)                              (scta_macro_new_(sizeof(type)))/*
+sctman:scta_new
+
+NAME
+    scta_new
+
+SYNOPSIS
+    bool scta_new(type)
+    
+DESCRIPTION
+    Takes any type as its input, and returns a pointer to a zero length array
+    with elements of the same type.
+
+NOTES
+    This function is implemented as a macro.
+
+RETURN
+    a pointer of type `type *' on success, and null otherwise.
+
+EXAMPLE
+    int *list = scta_new(int);
+    char *list = scta_new(char);
+    struct foo *list = scta_new(struct foo);
+    struct foo **list = scta_new(struct foo *);
+
+*/
+
+