Commits

Sulaiman  committed 970e783

إضافة filter وإصلاح عطب في scta_filter

  • Participants
  • Parent commits 34f4add

Comments (0)

Files changed (8)

File modules/a/scta.c

         
     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;
     
     else return n;
 }
 
+#define PTR(X) (((void **)(X))[0])
 
 int scta_macro_find_(void *p, bool (*comp)(void *a, void *b)){
     char *a = p;
     
     int i = 0;
     if (comp) {
-        for(; i < len; ++i) if (comp(a+(i*size), what)) break;
+        for(; i < len; ++i) if (comp( PTR(a+(i*size)), PTR(what))) break;
     }
     else {
         for(; i < len; ++i) if (!memcmp(a+(i*size), what, size)) break;
     else return -1;
 }
 
-bool scta_macro_filter_(void **z, bool (*comp)(void *a, void *b)){
+bool scta_macro_filter_(void **z, bool (*comp)(void *a, void *b), void (*freef)(void *a)){
     char *a = *z;
     int size = SCTA__EXTERN_SIZE(a)[0];
     int len = SCTA__EXTERN_LEN(a)[0];
     
     int i = 0;
     if (comp) {
-        for(; i < len; ++i) if (comp(a+(i*size), SCTA__EXTERN_STORAGE(a))) {
-            if (!scta_delete(a, i)) {
-                *z = a;
-                return false;
+        void *what = PTR(SCTA__EXTERN_STORAGE(a));
+        for(; i < len; ++i) {
+            if (comp(PTR(a+(i*size)), what)) {
+                if (freef) freef(PTR(a+(i*size)));
+                if (!scta_delete(a, i)) {
+                    *z = a;
+                    return false;
+                }
+                --len;
+                --i;
             }
-            --len;
-            --i;
         }
     }
     else {

File modules/a/scta.h

 bool scta_macro_delete_subset_(char **z);
 void* scta_macro_subset_(size_t size, int at, int length, void *p);
 int  scta_macro_find_(void *p, bool (*comp)(void *a, void *b));
-bool scta_macro_filter_(void **p, bool (*comp)(void *a, void *b));
+bool scta_macro_filter_(void **p, bool (*comp)(void *a, void *b), void (*freef)(void *a));
 
 /*
             ╭──────────╮
 
 */
 
-#define scta_filter(array, element, function)      (((array)[scta_length(array)+1]=element),\
-                                                     scta_macro_filter_((void **) (&array), (function)))
+#define scta_filter(array, element, test, free)      (((array)[scta_length(array)+1]=element),\
+                                                        scta_macro_filter_((void **) (&(array)), (test), (free)))
 /*
 sctdoc:scta_filter:
 NAME
     scta_filter
 
 SYNOPSIS
-    bool scta_filter(type* array, type target, bool test(void *a, void *b))
+    bool scta_filter(type* array, type b, 
+        bool (*test) (void *a, void *b), void (*free) (void *))
                                                      
 DESCRIPTION    
-    This macro filters out any element in `array' if `test()' returns true 
-    when supplied said element and `target'.
+    This macro filters out any element, A, in `array' if `test' 
+    returns true when supplied A and `b'.
     
-    if `test' is NULL, elements that match target exactly will be removed.
+    if `test' is NULL, elements that match target exactly (regardless 
+    of type) are removed.
+    
+    if 'free' and `test' are both not NULL, free is called on the 
+    element before its removal.
     
 RETURN
     true on success and false on error.

File modules/a/test.c

     { // testring filter
         int *a = scta_new(int);
         assert(scta_push_array(a, ((int[]){1, 2, 0, 5, 0, 0, 42, 2, 55 ,6}), 10));                
-        assert(scta_filter(a, 0, NULL));
+        assert(scta_filter(a, 0, NULL, NULL));
         assert(!memcmp(a, ((int[]){1, 2, 5, 42, 2, 55 ,6, 0}), sizeof(int)*8)); // terminating zero is tested explicitly in spite of it not being part of the array
-        assert(scta_filter(a, 2, NULL));
+        assert(scta_filter(a, 2, NULL, NULL));
         assert(!memcmp(a, ((int[]){1, 5, 42, 55 ,6, 0}), sizeof(int)*6)); // terminating zero is tested explicitly in spite of it not being part of the array
-        assert(scta_filter(a, 2223, NULL));
+        assert(scta_filter(a, 2223, NULL, NULL));
         assert(!memcmp(a, ((int[]){1, 5, 42, 55 ,6, 0}), sizeof(int)*6)); // terminating zero is tested explicitly in spite of it not being part of the array
         scta_free(a);
         
-        char **z = scta_new(char *);
-        assert(scta_push(z, "cat"));
-        assert(scta_push(z, "hat"));//
-        assert(scta_push(z, "fat"));//
-        assert(scta_push(z, "cat"));
-        assert(scta_push(z, "rat"));//
-        assert(scta_push(z, "cat"));
-        assert(scta_push(z, "cat"));
-        assert(scta_push(z, "cat"));
-        assert(scta_push(z, "bat"));//
-        assert(scta_filter(z, "cat", string_match));
-        assert(scta_find(z, "cat", string_match) == -1);
-        assert(scta_length(z) == 4);
-        scta_free(z);
+        {
+            char **z = scta_new(char *);
+            assert(scta_push(z, "cat"));
+            assert(scta_push(z, "hat"));//
+            assert(scta_push(z, "fat"));//
+            assert(scta_push(z, "cat"));
+            assert(scta_push(z, "rat"));//
+            assert(scta_push(z, "cat"));
+            assert(scta_push(z, "cat"));
+            assert(scta_push(z, "cat"));
+            assert(scta_push(z, "bat"));//
+            assert(scta_filter(z, "cat", string_match, NULL));
+            assert(scta_find(z, "cat", string_match) == -1);
+            assert(scta_length(z) == 4);
+            scta_free(z);
+        }
+        {
+            uint32_t **z = scta_new(uint32_t *);
+            assert(scta_push(z, ((uint32_t[]) {'c', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'h', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'f', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'c', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'r', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'c', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'c', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'c', 'a', 't', 0})));
+            assert(scta_push(z, ((uint32_t[]) {'b', 'a', 't', 0})));
+            assert(scta_filter(z, ((uint32_t[]) {'c', 'a', 't', 0}), string_match, NULL));
+            assert(scta_find(z, ((uint32_t[]) {'c', 'a', 't', 0}), string_match) == -1);
+            assert(scta_length(z) == 4);
+            scta_free(z);
+        }
     }
     
     

File modules/s/parts/filter.c

+#include "scts.h"
+
+//HEADER
+#ifndef SCTS_PART_FILTER
+#define SCTS_PART_FILTER
+bool scts_filter_c(char ***list_ptr, int criteria, char *what);
+bool scts_filter_u(char32_t ***list_ptr, int criteria, char32_t *what);
+#define scts_filter(list, criteria, what) (_Generic( (0, (list)), \
+    char32_t **:       scts_filter_u, \
+    const char32_t **: scts_filter_u, \
+    char **:       scts_filter_c, \
+    const char **: scts_filter_c \
+    )(&(list), (criteria), (what)))
+
+/*
+sctdoc:scts_filter:
+
+NAME
+    scts_filter
+
+SYNOPSIS
+
+    bool scts_filter(   [char**][char32_t**] list, 
+                        int criteria, 
+                        [char**][char32_t**] what)
+    
+    bool scts_filter_c(char ***list_ptr, int criteria, char *what);
+    bool scts_filter_u(char32_t ***list_ptr, int criteria, char32_t *what);
+    
+DESCRIPTION
+    This function/macro accepts `list' and filters out elements based on the 
+    criteria and `what'.
+    
+    CAUTION: This function should ONLY be used on lists returned by this 
+             library.
+    
+    There are 6 criterias by which strings are filtered out:
+        
+        SCTS_EMPTY                  Filters out empty strings
+        SCTS_NOT_EMPTY              Inverse of SCTS_EMPTY
+        SCTS_CONTAINS               Filters out strings containing the sub-
+                                    string `what'.
+        SCTS_NOT_CONTAINS           Filters out strings that do not contain 
+                                    the substring `what'.
+        SCTS_MATCHES                Filters out strings that match `what'.
+        SCTS_NOT_MATCHES            Filters out strings that don't match `what'.
+
+RETURN
+    This function returns false if an internal error occurs, and true 
+    otherwise.
+
+EXAMPLE
+    char **l;
+    l = scts_split("My name is bobias!", " ");
+    scts_filter(l, SCTS_EMPTY, NULL);
+    scts_filter(l, SCTS_CONTAINS, "a");
+    char *r = scts_join("", l);
+    puts(r); // Output: "Myis"
+    scts_free(r);
+    scts_free(l);
+    
+*/
+
+#endif
+
+//LIB
+
+bool matches_u(void *a, void *b) {
+    return scts_matches_u(a, b);
+}
+
+bool not_matches_u(void *a, void *b) {
+    return !matches_u(a, b);
+}
+
+bool contains_u(void *a, void *b) {
+    return (scts_find_u(a, b)!=-1);
+}
+
+bool not_contains_u(void *a, void *b) {
+    return !contains_u(a, b);
+}
+
+bool matches_c(void *a, void *b) {
+    return scts_matches_c(a, b);
+}
+
+bool not_matches_c(void *a, void *b) {
+    return !matches_c(a, b);
+}
+
+bool contains_c(void *a, void *b) {
+    return (scts_find_c(a, b)!=-1);
+}
+
+bool not_contains_c(void *a, void *b) {
+    return !contains_c(a, b);
+}
+
+
+bool scts_filter_u(char32_t ***list_ptr, int criteria, char32_t *what){
+    // input checks
+    if (!list_ptr || !list_ptr[0]) ERETURN(false, "list_ptr is null or points to null"); 
+    switch (criteria) {
+        case SCTS_EMPTY:
+        case SCTS_NOT_EMPTY:
+        case SCTS_CONTAINS:
+        case SCTS_NOT_CONTAINS:
+        case SCTS_MATCHES:
+        case SCTS_NOT_MATCHES:
+            break;
+        default:
+            ERETURN(false, "`criteria' is not a valid criteria"); 
+    }
+    if (!what && ((criteria!=SCTS_EMPTY) && (criteria!=SCTS_NOT_EMPTY))) ERETURN(false, "what is null"); 
+    
+    // logic
+    
+    switch (criteria) {
+    
+        case SCTS_EMPTY:
+            what = (char32_t[]) {0};
+            if (!(scta_filter((*list_ptr), what, matches_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        
+        case SCTS_NOT_EMPTY:
+            what = (char32_t[]) {0};
+            if (!(scta_filter((*list_ptr), what, not_matches_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        
+        case SCTS_CONTAINS:
+            if (!(scta_filter((*list_ptr), what, contains_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        case SCTS_NOT_CONTAINS:
+            if (!(scta_filter((*list_ptr), what, not_contains_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        case SCTS_MATCHES:
+            if (!(scta_filter((*list_ptr), what, matches_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        case SCTS_NOT_MATCHES:
+            if (!(scta_filter((*list_ptr), what, not_matches_u, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        default:
+            ERETURN(false, "`criteria' is not a valid criteria"); 
+    }
+    
+    return true;
+}
+
+
+
+bool scts_filter_c(char ***list_ptr, int criteria, char *what){
+    // input checks
+    if (!list_ptr || !list_ptr[0]) ERETURN(false, "list_ptr is null or points to null"); 
+    switch (criteria) {
+        case SCTS_EMPTY:
+        case SCTS_NOT_EMPTY:
+        case SCTS_CONTAINS:
+        case SCTS_NOT_CONTAINS:
+        case SCTS_MATCHES:
+        case SCTS_NOT_MATCHES:
+            break;
+        default:
+            ERETURN(false, "`criteria' is not a valid criteria"); 
+    }
+    if (!what && ((criteria!=SCTS_EMPTY) && (criteria!=SCTS_NOT_EMPTY))) ERETURN(false, "what is null"); 
+    
+    // logic
+    
+    switch (criteria) {
+    
+        case SCTS_EMPTY:
+            what = "";
+            if (!(scta_filter((*list_ptr), what, matches_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        
+        case SCTS_NOT_EMPTY:
+            what = "";
+            if (!(scta_filter((*list_ptr), what, not_matches_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        
+        case SCTS_CONTAINS:
+            if (!(scta_filter((*list_ptr), what, contains_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+        case SCTS_NOT_CONTAINS:
+            if (!(scta_filter((*list_ptr), what, not_contains_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        case SCTS_MATCHES:
+            if (!(scta_filter((*list_ptr), what, matches_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        case SCTS_NOT_MATCHES:
+            if (!(scta_filter((*list_ptr), what, not_matches_c, scts_free_pointer)))
+                ERETURN(false, "^");
+            break;
+            
+        default:
+            ERETURN(false, "`criteria' is not a valid criteria"); 
+    }
+    
+    return true;
+}
+
+
+
+//TEST
+#ifdef test_filter
+
+#include <assert.h>
+#include <stdio.h>
+
+int main() {
+    debug_fd = stderr;
+    {
+        char32_t **list = scta_new(char32_t *);
+        char32_t **fl = scta_new(char32_t *);
+        scta_push(list, scts_transcode(" something "));
+        scta_push(list, scts_transcode("something "));
+        scta_push(list, scts_transcode("something"));
+        scta_push(list, scts_transcode(""));
+        scta_push(list, scts_transcode(""));
+        scta_push(list, scts_transcode(" a thing"));
+        scta_push(list, scts_transcode(" a thing "));
+        
+        for (int i = 0; list[i]; ++i) scta_push(fl, list[i]);
+            
+        assert(scts_filter(list, SCTS_EMPTY, NULL));
+        assert(scta_length(list) == 5);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char32_t *[]) {fl[0], fl[1], fl[2], fl[5], fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_CONTAINS, ((char32_t[]) {'s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g', 0}) ));
+        assert(scta_length(list) == 2);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char32_t *[]) {fl[5], fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_MATCHES, ((char32_t[]) {' ', 'a', ' ', 't', 'h', 'i', 'n', 'g', 0}) ));
+        assert(scta_length(list) == 1);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char32_t *[]) {fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_NOT_MATCHES, ((char32_t[]) {' ', 'a', ' ', 't', 'h', 'i', 'n', 'g', 0}) ));
+        assert(scta_length(list) == 0);
+        
+        for (int i = 0; list[i]; ++i) scts_free(list[i]);
+        scta_free(list);
+        scta_free(fl);
+    }    
+    
+    {
+        char **list;
+        char **fl = scta_new(char *);
+
+        list = scts_split(" something ,something ,something,,, a thing, a thing ", ",");
+        assert(list);
+        for (int i = 0; list[i]; ++i) scta_push(fl, list[i]);
+        
+            
+        assert(scts_filter(list, SCTS_EMPTY, NULL));
+        assert(scta_length(list) == 5);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char *[]) {fl[0], fl[1], fl[2], fl[5], fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_CONTAINS, "something"));
+        assert(scta_length(list) == 2);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char *[]) {fl[5], fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_MATCHES, " a thing"));
+        assert(scta_length(list) == 1);
+        for (int i = 0; list[i]; ++i) assert(scts_matches(list[i], 
+            ((char *[]) {fl[6], NULL})[i] ));
+
+        assert(scts_filter(list, SCTS_NOT_MATCHES, " a thing"));
+        assert(scta_length(list) == 0);
+        
+        for (int i = 0; list[i]; ++i) scts_free(list[i]);
+        scta_free(list);
+        scta_free(fl);
+    }
+    
+    return 0;
+}
+
+#endif

File modules/s/parts/flow.c

 #ifndef SCTS_PART_FLOW
 #define SCTS_PART_FLOW
 
-#define SCTS_STOP                   ((int) 0)
-#define SCTS_APPEND                 ((int) 1)
-#define SCTS_INSERT                 ((int) 2)
-#define SCTS_JOIN                   ((int) 3)
-#define SCTS_REPLACE                ((int) 4)
-#define SCTS_SPLIT                  ((int) 5)
-#define SCTS_SUBSTRING              ((int) 6)
-#define SCTS_SELECT                 ((int) 8)
-#define SCTS_L_FILTER               ((int) 9)
-#define SCTS_NOT_EMPTY              ((int) 10)
-#define SCTS_CONTAINS               ((int) 11)
-#define SCTS_NOT_CONTAINS           ((int) 12)
-#define SCTS_NOT_MATCHES            ((int) 13)
-#define SCTS_ASSERT_LENGTH          ((int) 14)
+// Definition of operation/premitive constants is int init.h
 
 char32_t* scts_flow_iu(char32_t *primary, ...);
 
         sets the ith element of the stream list as the stream 
         string.
         
-    SCTS_L_FILTER  [l -> l]
+    SCTS_FILTER  [l -> l]
         Identical to `scts_filter'.
                 
     SCTS_NOT_EMPTY  [s -> s] ()
         stops the stream and returns an empty string if the length 
         of the stream list is nit `i'
         
-        
+    ----
+    SCTS_PRINT
+        A special operation that prints the stream, be it string or list,
+        to the standard error for the library `debug_fd'
+            
     
         
 
             }
             
             // list -> list
-                
-                // -- filter
+            case SCTS_FILTER: {
+                CHECK_INPUT_IS_LIST;
+                int criteria = va_arg(ar, int);
+                char32_t* what = va_arg(ar, char32_t*);
+                if (!scts_filter_u(&list, criteria, what)) {
+                    EPRINT("broken flow at operation %d: ^", index);
+                    goto SUPER_ERROR;
+                }
+                break;
+            }
                 
             // str -- flow control --> str
             case SCTS_NOT_EMPTY: {
                 break;
             }
             
+            
+            case SCTS_PRINT: {
+                if (!debug_fd) break;
+                if (last_output_type == type_string) {
+                    fprintf(debug_fd, "[%d] type:string -> '", index);
+                    scts_depprint(debug_fd, primary);
+                    fprintf(debug_fd, "'\n");
+                }
+                else {
+                    fprintf(debug_fd, "[%d] type:list[%d] -> ['", index, scta_length(list));
+                    for (int i = 0; list[i]; ++i) {
+                        if (i) fprintf(debug_fd, "', '");
+                        scts_depprint(debug_fd, list[i]);
+                    }
+                    fprintf(debug_fd, "']\n");
+                }    
+                break;
+            }
+            
             // list -- flow control --> list
             case SCTS_ASSERT_LENGTH: {
                 CHECK_INPUT_IS_LIST;
     debug_fd = stderr;
     char32_t *ll[200] = {0};
     char32_t *t = scts_flow_iu((ll[0] = scts_transcode("hel-yahoo-lo")), 
-        SCTS_SUBSTRING, 1, -2,
-        SCTS_APPEND, (ll[1]=scts_transcode("ly")), 
+        SCTS_SUBSTRING, 1, -2, 
+        SCTS_APPEND, (ll[1]=scts_transcode("ly")),
         SCTS_SPLIT, ((char32_t[]) {'-', 0}),
         SCTS_ASSERT_LENGTH, 3,
         SCTS_NOT_CONTAINS, (ll[4]=scts_transcode("ysadfoo")), 
         SCTS_JOIN, (ll[2]=scts_transcode("r")), 
         SCTS_NOT_MATCHES, (ll[3]=scts_transcode("yasoo")),
         SCTS_JOIN, ((char32_t*[]) {ll[7]=scts_transcode("you "), ll[8]=scts_transcode(" zebra"), 0}),
+        SCTS_SPLIT, ((char32_t[]) {' ', 0}),
+        SCTS_FILTER, SCTS_CONTAINS, ((char32_t[]) {'o', 0}),
+        SCTS_SELECT, 0,
         SCTS_STOP);
-    scts_depprint(stdout, t);
-    assert(scts_matches(t, ll[6] = scts_transcode("you yaroo zebra")));
+    
+    assert(scts_matches(t, ll[6] = scts_transcode("zebra")));
     
     for (int i = 0; i < 200; ++i) if (ll[i]) {
         scts_free(ll[i]);

File modules/s/parts/init.h

     return (RET); \
 }
 
+#define SCTS_STOP                   ((int) 0)
+#define SCTS_APPEND                 ((int) 1)
+#define SCTS_INSERT                 ((int) 2)
+#define SCTS_JOIN                   ((int) 3)
+#define SCTS_REPLACE                ((int) 4)
+#define SCTS_SPLIT                  ((int) 5)
+#define SCTS_SUBSTRING              ((int) 6)
+#define SCTS_SELECT                 ((int) 8)
+#define SCTS_FILTER                 ((int) 9)
+
+#define SCTS_EMPTY                  ((int) 10)
+#define SCTS_NOT_EMPTY              ((int) 11)
+#define SCTS_CONTAINS               ((int) 12)
+#define SCTS_NOT_CONTAINS           ((int) 13)
+#define SCTS_MATCHES                ((int) 14)
+#define SCTS_NOT_MATCHES            ((int) 15)
+#define SCTS_ASSERT_LENGTH          ((int) 16)
+
+#define SCTS_PRINT                  ((int) 17)
 

File modules/s/parts/scts.h

     return (RET); \
 }
 
+#define SCTS_STOP                   ((int) 0)
+#define SCTS_APPEND                 ((int) 1)
+#define SCTS_INSERT                 ((int) 2)
+#define SCTS_JOIN                   ((int) 3)
+#define SCTS_REPLACE                ((int) 4)
+#define SCTS_SPLIT                  ((int) 5)
+#define SCTS_SUBSTRING              ((int) 6)
+#define SCTS_SELECT                 ((int) 8)
+#define SCTS_FILTER                 ((int) 9)
+
+#define SCTS_EMPTY                  ((int) 10)
+#define SCTS_NOT_EMPTY              ((int) 11)
+#define SCTS_CONTAINS               ((int) 12)
+#define SCTS_NOT_CONTAINS           ((int) 13)
+#define SCTS_MATCHES                ((int) 14)
+#define SCTS_NOT_MATCHES            ((int) 15)
+#define SCTS_ASSERT_LENGTH          ((int) 16)
+
+#define SCTS_PRINT                  ((int) 17)
 
 
 // PARTIALS SECTION: AUTOMATICLY GENERATED
 
 
     
+//--filter
+#ifndef SCTS_PART_FILTER
+#define SCTS_PART_FILTER
+bool scts_filter_c(char ***list_ptr, int criteria, char *what);
+bool scts_filter_u(char32_t ***list_ptr, int criteria, char32_t *what);
+#define scts_filter(list, criteria, what) (_Generic( (0, (list)), \
+    char32_t **:       scts_filter_u, \
+    const char32_t **: scts_filter_u, \
+    char **:       scts_filter_c, \
+    const char **: scts_filter_c \
+    )(&(list), (criteria), (what)))
+
+/*
+sctdoc:scts_filter:
+
+NAME
+    scts_filter
+
+SYNOPSIS
+
+    bool scts_filter(   [char**][char32_t**] list, 
+                        int criteria, 
+                        [char**][char32_t**] what)
+    
+    bool scts_filter_c(char ***list_ptr, int criteria, char *what);
+    bool scts_filter_u(char32_t ***list_ptr, int criteria, char32_t *what);
+    
+DESCRIPTION
+    This function/macro accepts `list' and filters out elements based on the 
+    criteria and `what'.
+    
+    CAUTION: This function should ONLY be used on lists returned by this 
+             library.
+    
+    There are 6 criterias by which strings are filtered out:
+        
+        SCTS_EMPTY                  Filters out empty strings
+        SCTS_NOT_EMPTY              Inverse of SCTS_EMPTY
+        SCTS_CONTAINS               Filters out strings containing the sub-
+                                    string `what'.
+        SCTS_NOT_CONTAINS           Filters out strings that do not contain 
+                                    the substring `what'.
+        SCTS_MATCHES                Filters out strings that match `what'.
+        SCTS_NOT_MATCHES            Filters out strings that don't match `what'.
+
+RETURN
+    This function returns false if an internal error occurs, and true 
+    otherwise.
+
+EXAMPLE
+    char **l;
+    l = scts_split("My name is bobias!", " ");
+    scts_filter(l, SCTS_EMPTY, NULL);
+    scts_filter(l, SCTS_CONTAINS, "a");
+    char *r = scts_join("", l);
+    puts(r); // Output: "Myis"
+    scts_free(r);
+    scts_free(l);
+    
+*/
+
+#endif
+
+
+    
 //--find
 #ifndef SCTS_PART_FIND
 #define SCTS_PART_FIND
 #ifndef SCTS_PART_FLOW
 #define SCTS_PART_FLOW
 
-#define SCTS_STOP                   ((int) 0)
-#define SCTS_APPEND                 ((int) 1)
-#define SCTS_INSERT                 ((int) 2)
-#define SCTS_JOIN                   ((int) 3)
-#define SCTS_REPLACE                ((int) 4)
-#define SCTS_SPLIT                  ((int) 5)
-#define SCTS_SUBSTRING              ((int) 6)
-#define SCTS_SELECT                 ((int) 8)
-#define SCTS_L_FILTER               ((int) 9)
-#define SCTS_NOT_EMPTY              ((int) 10)
-#define SCTS_CONTAINS               ((int) 11)
-#define SCTS_NOT_CONTAINS           ((int) 12)
-#define SCTS_NOT_MATCHES            ((int) 13)
-#define SCTS_ASSERT_LENGTH          ((int) 14)
+// Definition of operation/premitive constants is int init.h
 
 char32_t* scts_flow_iu(char32_t *primary, ...);
 
         sets the ith element of the stream list as the stream 
         string.
         
-    SCTS_L_FILTER  [l -> l]
+    SCTS_FILTER  [l -> l]
         Identical to `scts_filter'.
                 
     SCTS_NOT_EMPTY  [s -> s] ()
         stops the stream and returns an empty string if the length 
         of the stream list is nit `i'
         
-        
+    ----
+    SCTS_PRINT
+        A special operation that prints the stream, be it string or list,
+        to the standard error for the library `debug_fd'
+            
     
         
 

File modules/std/sctstd.c

 /*
 //TODO
-
+    - finish flow
+    - work on /io. and rename scts_depprint back to scts_print, but let it 
+      continue being the dumb function that it is. (it's nessasary for 
+      flow, and posible feature modules), and I don't want to tie /s with
+      /io
+    
     - update sct test system
         ! ditch make files
         - convert files to use bash scripts instead of make files
         - update checklib to be as smart as parts.*
+        - unify how scripts initialize and work, even if a script does not 
+          need the fancy shmancy
     
     - modify fetch script to:
         - work locally