/*- Author: Brian Tiffin Dedicated to the public domain Date started: January 2017 Modified: 2017-01-08/06:16-0500 Tectonics: gcc -o unilist.so -shared -fpic unilist.c unicon -s unilist.icn -x +*/ /* unilist.c, trials with C functions and Unicon lists */ #include #include #include #include "icall.h" /* access src/runtime/rstruct.r low level put */ void c_put(descriptor *, descriptor *); /* some characters for random strings */ #define ALPHABET "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" #define ALPHASIZE (sizeof(ALPHABET) - 1) /* replace all character positions with a random element from ALPHABET */ char * randomize(char *str) { int i; unsigned int rnd; static unsigned int seed; char *p = str; if (seed == 0) { seed = ((unsigned) time(NULL)<<8) ^ (unsigned)clock(); } srand(seed++); while (*p) { rnd = rand() % ALPHASIZE; *p++ = (ALPHABET)[rnd]; } return str; } /* Build out a heterogeneous list */ int unilist(int argc, descriptor argv[]) { char *str; int len; int size; int limit; double dbl; descriptor listReturn; descriptor stringReturn; descriptor fileReturn; descriptor realReturn; /* Cheating, need list to work with todo: create your own list ya lazy git */ ArgList(1); /* set a limit on randomized string lengths */ ArgInteger(2); limit = IntegerVal(argv[2]); /* make a randomized string, 0 to limit, don't care about bias */ size = 0; while (size < 1) { size = ((float)rand()) / RAND_MAX * limit+1; } str = malloc(size); if (!str) exit(1); memset(str, ' ', size); str[size-1] = '\0'; len = size; randomize(str); /* add string to end of list */ Protect(StringAddr(stringReturn) = alcstr(str, len), Error(306)); StringLen(stringReturn) = len; c_put(&argv[1], &stringReturn); free(str); /* random real from [0, size], ignoring bias */ dbl = ((double)rand() / (double)(RAND_MAX)) * (size-1); realReturn.dword = D_Real; #if defined(DescriptorDouble) realReturn.vword.realval = dbl; #else Protect(realReturn = alcreal(dbl), Error(307)); realReturn.vword.bptr = (union block *)realReturn; #endif /* add real to end of list */ c_put(&argv[1], &realReturn); /* return string size */ RetInteger(size-1); }