- ALIGN
-
__
macros for alignment. They take a number or pointer, and align upwards to 2,4,8,..256 There are the macros ALIGN_2 ALIGN_4 ALIGN_8 ..., and ALIGN_P, which aligns to the size of a pointer. (8 for amd64)
- OPTFENCE
-
#ifndef clang
prevent gcc to optimize away registers and variables the macro OPTFENCE(...) can be invoked with any parameter. The parameters will get calculated, even if gcc doesn't recognize the use of the parameters, e.g. cause they are needed for an inlined asm syscall. The macro translates to an asm jmp and a function call to the function opt_fence, which is defined with the attribute "noipa" - (the compiler "forgets" the function body, so gcc is forced to generate all arguments for the function) The generated asm jump hops over the call to the function, but this gcc doesn't recognize. This generates some overhead, (a few (never reached) bytes for setting up the function call, and the jmp) but I didn't find any other solution, which gcc wouldn't cut for optimizations from time to time. (volatile, volatile asm, optimize attributes, andsoon have all shown up to be unreliable - sometimes(!)). Had some fun debugging these bugs, which naturally showed up only sometimes. (Many syscalls also work with scrambled arguments..) And, I believe it IS a compiler bug. Volatile should be volatile for sure, not only sometimes. I mean, why the heck do I write volatile??
../include/syscall.h l.66
- OPTIMIZATIONS
-
__
enable some optimizations, with a slitghtly bigger memory footprint. defaults to off (yet only calloc is optimized. todo)
../include/config.h l.33
- _die
-
void _die()
internal implementation of die
../src/process/die.c l.36
- _match
-
int _match(char *text, const char *re, text_match *st_match)
../src/match/match.c l.96
- _match_ext2
-
char* _match_ext2(char *text, char *re, void(*p_matched_cb)(int number, char *pos,int len), int(*p_wildcard_cb)(int number, char *match_char), text_match *st_match)
internal implementation of match_ext
- accept
-
int accept( int fd, struct sockaddr *upeersockaddr, int *upeeraddrlen)
../include/syscall_stubs.h l.247 manpage: accept
- assert
-
__
Defines: kill getpid memcpy write rt_sigaction
../macros/assert.h l.4
- bind
-
int bind( int fd, struct sockaddr *umyaddr, int addrlen)
../include/syscall_stubs.h l.241 manpage: bind
- bsd_cksum
-
unsigned int bsd_cksum( const char* p, unsigned int len )
bsd checksum
../src/file/cksum.c l.31
- bsd_cksumblock
-
unsigned int bsd_cksumblock( unsigned int hash, const char* p, unsigned int len )
bsd checksum, called by bsd_cksum, with initial hash value
../src/file/cksum.c l.20
- bsd_definitions
-
__
definitions, found at BSD enable with mini_bsd_definitions
- bsd_timespec
-
__
timespec functions, copied from freebsd
- bsearch
-
void* bsearch(const void *key, const void *base0, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
search for an element code is copied from netbsd
../src/sort/bsearch.c l.55 manpage: bsearch
- calloc
-
void* calloc(int nmemb, int size)
../src/memory/calloc.c l.2 manpage: calloc
- cfmakeraw
-
void cfmakeraw(struct termios tp)
*Defines: termio
../src/termios/cfmakeraw.c l.3 manpage: cfmakeraw
- config
-
__
configuration settings, to be compiled statically. System specific paths, maximums, etc go here. Other values are within globaldefs.h; architecture specific values are within the folder headers.
- ctype_functions
-
#ifdef mini_ctype_functions
create functions instead of macros for isalpha, .., isprint the ctype macros are defined also without being explicitely enabled.
../include/ctype.h l.23
- def
-
#define SETOPT_short( opts, option ) (
Set a option flag(s) (bit(s)) manually. param options: e.g. just a, or ( a+h+l) to check for several flags at once
../macros/getoptm.h l.52
- die
-
#define die(errnum,msg) {ewritesl(msg);exit_errno(errnum);}
Defines: execve errno_str exit write
write msg to stderr and exit with failure if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.11
- die_if
-
#define die_if( when, errnum, msg ) if( when ) die( errnum, msg )
Defines: write execve errno_str exit
when arg1 is true, write msg to stderr and exit with failure if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.59
- dief
-
#define dief(errnum,fmt,…) {fprintf(stderr,fmt,VA_ARGS);exit_errno(errnum);}
Defines: getpid fileno write kill errno_str exit execve strlen globals
write fmt andargs via fprintf to stderr and exit with failure if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.20
- dief_if
-
#define dief_if( when, errnum, fmt,… ) if( when ) dief( errnum, fmt, VA_ARGS )
Defines: write exit errno_str execve
when arg1 is true, vall dief(errnum,fmt) if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.69
- dies
-
#define dies(errnum,…) {eprintsl(VA_ARGS);exit_errno(errnum);}
Defines: execve errno_str exit write
write variable string list to stderr and exit with failure if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.30
- dies_if
-
#define dies_if( when, errnum, … ) if( when ) dies( errnum, VA_ARGS )
Defines: exit errno_str execve write
when arg1 is true, vall dies(errnum, ... ) if errno is defined and set, /bin/errno is executed to give a verbose error message if errno is either not defined or not set, exit with -1
../src/process/die.c l.80
- dirbuf_malloc
-
#ifndef mini_dirbuf_malloc
which malloc to use for allocating the dir handles malloc : use malloc, therefore the minibuf malloc_brk : use malloc_brk defaults to malloc
../include/dirent.h l.31
- eprintf
-
#define eprintf(fmt,…) fprintf(stderr, fmt, VA_ARGS)
Defines: strlen write fileno
write fmt and arguments to stderr.
../include/prints.h l.133
- err
-
#define err( status, fmt … ) { fprintf(stderr,fmt ); fprints(stderr,":",strerror(errno)); exit(status); }
Defines: kill exit strlen globals getpid strerror errno write fileno
print an error message to stderr, print an error message dependend on errno ( strerror(errno) ), exit with status
../src/process/error.h l.20 manpage: err
- error
-
#define error( status, errnum, fmt … ) { fprintf(stderr,fmt ); if (errnum) fprints(stderr,":",strerror(errnum)); if ( status ) exit(status); }
Defines: exit kill strlen globals getpid strerror fileno write
print an error message to stderr when errnum is not 0, print either the number, or a verbose error message (with strerror), when mini_verbose_errstr is defined. (verbose error messages add aboyut 4kB) when status is non null, terminate with status
- errx
-
#define errx( status, fmt … ) { fprintf(stderr,fmt); exit(status); }
Defines: kill exit strlen globals getpid write fileno
print an error message to stderr, exit with status
../src/process/error.h l.27 manpage: errx
- ether_ntoa
-
char* ether_ntoa( const struct ether_addr e )
*Defines: network
../src/network/ether_ntoa.c l.3 manpage: ether_ntoa
- ewritesl
-
#define ewritesl(str) write(STDERR_FILENO,str"\n",sizeof(str)+1)
Defines: write
write the constant str to stderr, followed by a newline. Computes length with sizeof(str) at compile time.
../include/prints.h l.100
- fgetsn
-
int fgetsn(char buf, int size, FILE F)
Defines: read fileno
get a line like fgets, but return the len of the read string.
- fgetsp
-
char* fgetsp(char buf, int size, FILE F)
Defines: read fileno
read a line from F into buf with max chars size. Return a pointer to the terminating '0' byte. A terminating linebreak is not written to buf.
- fgetud
-
unsigned int fgetud(FILE* F)
Defines: read fileno
read an unsigned integer from the stream F reads all digits until a nondigit is read.
- fgetul
-
unsigned long int fgetul(FILE* F)
Defines: fileno read
read an unsigned long integer from the stream F reads all digits until a nondigit is read.
- flock
-
int flock( unsigned int fd, unsigned int cmd)
../include/syscall_stubs.h l.130 manpage: flock
- fwritesl
-
#define fwritesl(fd,str) write(fd,str"\n",sizeof(str)+1)
Defines: write
write the constant str to fd,followed by a newline. Computes length with sizeof(str) at compile time.
../include/prints.h l.114
- getegid
-
int DEF_syscall(getegid,0)
../include/syscall_stubs.h l.215 manpage: getegid
- geteuid
-
int DEF_syscall(geteuid,0)
../include/syscall_stubs.h l.213 manpage: geteuid
- getgrouplist
-
int getgrouplist(const char* user, gid_t group, gid_t groups, int *ngroups)
*Defines: grent token_i userdb passwdfile_open setpwent pwent setgrent token_s write open mmap
needs rewrite. now nonstandard.
../src/userdb/getgrouplist.c l.5 manpage: getgrouplist
- getgroups
-
int getgroups(int maxgroups, int list)
*Defines: token_s write open mmap getuid grent token_i userdb passwdfile_open setpwent pwent setgrent
get the groups of the calling process does not necessarily contain the primary group, which is given in the passwd entry. This function calls internally setgrent() and getgrent(); therefore any iteration with getgrent will be resetted.
../src/userdb/getgroups.c l.8 manpage: getgroups
- gethostname
-
int gethostname(char name,int len)
*Defines: network uname
gethostname
../src/network/gethostname.c l.4 manpage: gethostname
- getresuid
-
int getresuid( uid_t *ruid, uid_t *euid, uid_t *suid)
../include/syscall_stubs.h l.210 manpage: getresuid
- getrlimit
-
int getrlimit( unsigned int resource, struct rlimit *rlim)
../include/syscall_stubs.h l.231 manpage: getrlimit
- getrusage
-
int getrusage( int who, struct rusage *ru)
../include/syscall_stubs.h l.142 manpage: getrusage
- getsid
-
int getsid( pid_t pid)
../include/syscall_stubs.h l.164 manpage: getsid
- getsockopt
-
int getsockopt( int fd, int level, int optname, char *optval, int *optlen)
../include/syscall_stubs.h l.245 manpage: getsockopt
- getusergroups
-
int getusergroups(const char* user, int maxgroups, int list)
*Defines: userdb passwdfile_open pwent setpwent setgrent grent token_i mmap token_s write open
get the supplementary groups for the user uid. does not necessarily contain the primary group, which is given in the passwd entry. This function calls internally setgrent() and getgrent(); therefore any iteration with getgrent will be resetted.
- group_printf
-
//
Defines: getpid fileno write itooct uitohex atoi globals uitodec uitoHEX ultodec kill strlen
printf, eprintf, fprintf, itodec, ltodec, itohex, anprintf, sprintf (conversions %d %l %x %ud %ul %ux ),
- htonl
-
uint32_t htonl(uint32_t i)
Defines: network
../src/network/htonl.c l.5 manpage: htonl
- htons
-
uint16_t htons(uint16_t i)
Defines: network
../src/network/htons.c l.3 manpage: htons
- inet_aton
-
int inet_aton(const char* s, struct in_addr addr)
*Defines: network
../src/network/inet_aton.c l.3 manpage: inet_aton
- inet_ntoa
-
char* inet_ntoa( struct in_addr in)
Defines: network
convert a address This returns a pointer to a string in the globals, therefore the routine isn't reentrant. (whoever thought this might be a good idea..)
../src/network/inet_ntoa.c l.7 manpage: inet_ntoa
- initgroups
-
int initgroups(const char* user, gid_t group)
../src/userdb/initgroups.c l.2 manpage: initgroups
- killpg
-
int killpg( int pid, int signal )
../src/process/killpg.c l.2 manpage: killpg
- listen
-
int listen( int fd, int backlog)
../include/syscall_stubs.h l.248 manpage: listen
- locale_dummies
-
__
several dummy definitions, mostly locale related. (locales are not the target of minilib, so define mini_dummies to have code relying on locales running) Quite often some code does only checking for locales, but doesn't rely on them.
../include/dummies.h l.10
- lstat
-
int lstat(const char* filename,struct stat* statbuf)
../include/syscall_stubs.h l.113 manpage: lstat
- match_ext
-
int match_ext(char *text, const char *re, void(*p_match)(int number, char *pos,int len, void *userdata), int(*p_match_char)(int number, char *match_char, void *userdata), tmatch_ext *st_match, void *userdata)
text matching engine This is somewhere between a fully fledged expression machine, and a simplicistic solution. Consciusly named 'text matching', since the inherent logic is quite different to a regular expression machine. The engine matches from left to right, backtracking is done as less as possible. Since the matching is nongreedy in general, many tries can be spared. Opposed to another route, where most patterns are per default greedy, and therfore not the first matching next char is seeked for, but the first solution while matching the most chars. (I do not want to make this a hard statement, and it depends onto each pattern. But it is the way, the solution of the pattern is searched for, in most patterns.) This shows up in the logic of the patterns, which is more natural to me. It is a compromise between performance, size and capabilities. The logic is different of a "regular" regular expression machine, but has advantages (and disadvantages). I'd say, the main advantage is the easiness of adding callbacks, and defining your own matching/logic within these. Performance might be better as well overall, but this depends also on the expressions. A few nonextensive benchmarks show, this engine is a bit faster than perl's regular expression machine, slower than gnu grep (around factor2), and has the same speed as sed. This might however vary with each usecase. In favor of codesize I'm not going to optimize match_ext, but there would be several possibilities, if you'd need a faster engine. (Albite I'd like to emphasise, sed (and match_ext), also perl, are quite fast. About 10 times faster than most expression engines.) matches: * for every count of any char + for 1 or more chars ? for 1 char # for space or end of text (0) $ match end of text backslash: escape *,?,%,$,!,+,#,& and backslash itself. !: invert the matching of the next character or character class ,: separator. e.g. %,1 matches like ?*1. ( without the commata, the '1' would be part of the % match) predefined character classes: \d - digit \D - nondigit \s - space \S - nonspace \w - word character ( defined as ascii 32-126,160-255 ) \W - nonword character ( defined as ascii 0-31,127-159 ) [xyz]: character classes, here x,y or z the characters are matched literally, also \,*,?,+,.. it is not possible to match the closing bracket (]) within a character class {nX}: counted match Match n times X. For X, all expressions are allowed. If you need to match a number at the first char of 'X', separate X by a commata. E.g. {5,0} matches 5 times '0'. %[1]..%[9]: matches like a '+', and calls the callback supplied as 3rd argument (when not null). the number past the %, e.g. %1, is optional, p_match will be callen with this number as first parameter. When not supplied, p_matched will be callen with the parameter 'number' set to 0. The matching is 'nongreedy'. It is possible to rewrite the string to match from within the p_matched callback. This will not have an effect onto the current matching, even if text is e.g. deleted by writing 0's. The matched positions are called in reverse order. (The last matched % in the regex calls p_match first, the first % in the regex from the left will be callen last) supply 0 for p_matched, when you do not need to extract matches. This will treat % in the regex like a *, a following digit (0..9) in the regex is ignored. if the 5th argument, a pointer to a tmatch_ext struct, is supplied, it will be filled with the first match. (counting from left) &[1] .. &[9] "match" like a '?' and call p_match_char p_match_char has to return either RE_MATCH, RE_NOMATCH, RE_MATCHEND or a number of the count of chars, which have been matched. Therefore it is possible to e.g. rule your own character classes, defined at runtime, or do further tricks like changing the matched chars, match several chars, andsoon. When returning RE_NOMATCH, it is possible, the p_match and p_match_char callbacks are callen several times, but with different pos or len parameters. The matching works straight from left to right. So, a "*&*" will call the callback & for the first char. When returning RE_NOMATCH, the second char will be matched. Until either RE_MATCH is returned from the callback, or the last char has been matched. Matching several characters is also posssible from within the callback, the position within the text will be incremented by that number, you return from the callback. When returning RE_MATCHEND from the callback, the whole regular expression is aborted, and returns with matched; no matter, if there are chars left in the expression. The difference between % and & is the logic. % matches nongreedy, and has to check therefore the right side of the star for its matching. Possibly this has to be repeated, when following chars do not match. & is matched straight from left to right. Whatever number you return, the textpointer will be incremented by that value. However, a & isn't expanded on it's own. ( what a % is ). e.g. "x%x" will match 'aa' in xaax, x&x will match the whole expression only, when you return '2' from the callback. Performancewise, matching with & is faster, since the % has on its right side to be matched with recursing calls of match_ext. When using closures for the callbacks, you will possibly have to enable an executable stack for the trampoline code of gcc. Here, gcc complains about that. For setting this bit, have a look into the ldscripts in the folder with the same name. supply 0 for p_match_char, when you don't need it. This will treat & in the regex like ?, and match a following digit (0..9) in the text, a following digit (0..9) in the regex is ignored. ----- In general, you have to somehow invert the logic of regular expressions when using match_ext. e.g. when matching the parameter 'runlevel=default' at the kernel's commandline, a working regular expression would be "runlevel=(\S*)". This could be written here as "*runlevel=%#". For matching e.g. numbers, you'd most possibly best of with writing your own & callback. returns: 1 on match, 0 on no match ( RE_MATCH / RE_NOMATCH ) if the pointer (argument 5) st_match is nonnull, the supplied struct tmatch_ext will be set to the first matching '%' location; if there is no match, tmatch_ext.len will be set to 0. The struct is defined as: typedef struct _tmatch_ext { char* pos; int len; } tmatch_ext; (memo) When the regex ist defined within C/cpp source code, a backslash has to be defined as double backslash. (note) - be careful when negating a following *, or ?. somehow - it is logical, but seems to me I overshoot a bit, tragically hit my own foot, and stumbled into a logical paradox. Negating EVERYTHING translates to true. However, since truth is negated as well, there's a problem, cause it's now 'false', but 'false' is true. This is very close to proving 42 is the answer. What is the escape velocity in km/s out of the solar system, btw. (I'm not kidding here. Just don't do a regex with !* or !?.. And, please, do not ask me what is going to happen when the impossible gets possibilized. I have to point at the according sentences of the BSD license;// there is NO WARRANTY for CONSEQUENTIAL DAMAGE, LOSS OF PROFIT, etc pp.) A "!+" will translate into nongreedy matching of any char, however; "%!+" will match with % everything but the last char; while "%+" matches with % only the first char. !+ basically sets the greedyness of the left * or % higher.
../src/match/match_ext.c l.193
- match_ext2
-
int match_ext2(char *text, char *re, void(*p_matched_cb)(int number, char *pos,int len), int(*p_wildcard_cb)(int number, char *match_char),text_match *st_match)
text matching engine WORK IN PROGRESS, please use ext_match Atm, please nested brackets are featureful. nesting {} within () seems to work. Nesting round brackets within {} gives sometimes trouble, when wildcards are used within the brackets. I'm leaving this at it is for now. Possibly I'm going to hardcode an error message for nested brackets, or nested brackets with wildcards. This is somewhere between a fully fledged expression machine, and a simplicistic solution. Consciusly named 'text matching', since the inherent logic is quite different to a regular expression machine; "natural expressions" might fit better for the name. The engine matches from left to right, backtracking is done as less as possible. Since the matching is nongreedy in general, many tries can be spared. Opposed to another route, where most patterns are per default greedy, and therfore not the first matching next char is seeked for, but the first solution while matching the most chars. (I do not want to make this a hard statement, and it depends onto each pattern. But it is the way, the solution of the pattern is searched for, in most patterns.) This shows up in the logic of the patterns, which is more natural to me. Your mileage might vary. It is a compromise between performance, size and capabilities. The logic is different of a "regular" regular expression machine, but has advantages (and disadvantages). I'd say, the main advantage is the easiness of adding callbacks, and defining your own matching/logic within these. Performance might be better as well overall, but this depends on the expressions and usecases as well. Yet I for myself have to get a grip of the possibilities of this engine. However, I have the feeling, the logic is much more natural. With regular regexes you always have to think kind of 'backwards', e.g., match ".*" -> match "." (any char) x times. gets to a simple "*" or, to match all group and user id's of /etc/passwd, a regular expression would be: "(\d*):(\d*)" This is here: "*(\d*):(\d*)*" The content in the brackets looks the same, but it's matched quite different. The regular expression (the first) matches x times \d, for x>=0. In the second expressin, the ext_match expression, the first digit is matched, and then nongreedy any chars, until the first occurence of ':'. It is another logic. Whether it suits you, you have to decide. The callbacks have shown up to be a mighty tool, while at the same time having a good performance. A few nonextensive benchmarks show, this engine is a bit faster than perl's regular expression machine, slower than gnu grep (around factor2), and has the same speed as sed. This might vary with each usecase, but the callbacks for extracting matches have some advantage, as well as the strict left to right and nongreedy parsing. In favor of codesize I'm not going to optimize ext_match, but there would be several possibilities, if you'd need a faster engine. (Albite I'd like to emphasise, sed (and ext_match), also perl, are quite fast. About 5 to 10 times faster than most expression engines.) matches: * for every count of any char + for 1 or more chars ? for 1 char # for space, end of text (\0), linebreak, tab ( \t \n \f \r \v ) @ matches the beginning of the text or endofline (\n) $ match end of text (\0) or linebreak backslash: escape *,?,%,@,$,!,+,#,& and backslash itself. !: invert the matching of the next character or character class ,: separator. e.g. %,1 matches like ?*1. ( without the commata, the '1' would be part of the % match) predefined character classes: \d - digit \D - nondigit \s - space \S - nonspace \w - word character ( defined as ascii 32-126,160-255 ) \W - nonword character ( defined as ascii 0-31,127-159 ) \x - hexadecimal digit (0-9,a-f,A-F) [xyz]: character classes, here x,y or z the characters are matched literally, also \,*,?,+,.. it is not possible to match the closing bracket (]) within a character class {nX}: counted match Match n times X. For X, all expressions are allowed. If you need to match a number at the first char of 'X', separate X by a commata. E.g. {5,0} matches 5 times '0'. n can be a number, * or +. ('*' matches 0 or more, '+' 1 or more times) (X): match the subexpression X. atm, no nesting of round () and {} brackets allowed %[1]..%[9]: matches like a '+', and calls the callback supplied as 3rd argument (when not null). the number past the %, e.g. %1, is optional, p_matched_cb will be callen with this number as first parameter. When not supplied, p_matched_cb will be callen with the parameter 'number' set to 0. The matching is 'nongreedy'. It is possible to rewrite the string to match from within the p_matched_cb callback. This will not have an effect onto the current matching, even if text is e.g. deleted by writing 0's. The matched positions are called in reverse order. (The last matched % in the regex calls p_matched_cb first, the first % in the regex from the left will be callen last) / The regex is first matched; when the regex has matched, the %'s are filled/ the callbacks executed. (x) bracketed patterns are matched the same way. (Not like &, which callbacks are invoked, while matching) supply 0 for p_matched_cb, when you do not need to extract matches. This will treat % in the regex like a *, a following digit (0..9) in the regex is ignored. if the 5th argument, a pointer to a text_match struct, is supplied, it will be filled with the first match. (counting from left) &[1] .. &[9] "match" like a '?' and call p_wildcard_cb p_wildcard_cb has to return either RE_MATCH, RE_NOMATCH, RE_MATCHEND or the number of the count of chars, which have been matched. Therefore it is possible to e.g. rule your own character classes, defined at runtime, or do further tricks like changing the matched chars, match several chars, andsoon. When returning RE_NOMATCH, it is possible, the p_wildcard_cb callback is callen several times, but with different pos or len parameters, since p_wildcard_cb is invoked while matching. The matching works straight from left to right. So, a "*&*" will call the callback & for the first char. When returning RE_NOMATCH, the second char will be tried to match. Until either RE_MATCH is returned from the callback, or the last char of the text has been tried to match. Matching several characters is also posssible from within the callback, the position within the text will be incremented by that number, you return from the callback. When returning RE_MATCHEND from the callback, the whole expression is aborted, and returns with matched; no matter, if there are chars left in the expression. The difference between % and & is the logic. % matches nongreedy, and has to check therefore the right side of the star for its matching. Possibly this has to be repeated, when following chars do not match. & is matched straight from left to right. Whatever number you return, the textpointer will be incremented by that value. However, a & isn't expanded on it's own. ( what a % is ). e.g. "x%x" will match 'aa' in xaax, x&x will match the whole expression only, when you return '2' from the callback. Performancewise, matching with & is faster, since the % has on its right side to be matched with recursing calls of ext_match. When using closures for the callbacks, you will possibly have to enable an executable stack for the trampoline code of gcc. Here, gcc complains about that. For setting this bit, please have a look into the ldscripts in the folder with the same name. supply 0 for p_wildcard_cb, when you don't need it. This will treat & in the regex like ?, and match a following digit (0..9) in the text, a following digit (0..9) in the regex is ignored. ----- In general, you have to somehow invert the logic of regular expressions when using ext_match. Regular expressions could be regarded as "polish rpn notation", first the char to be matched, then the count. This expression machine could be described as "natural expression" machine. First you define the number, then the chars or expression to be matched. Furthermore, *,% and + match as less as possible. You have to think about what needs to follow the wildcards. e.g. when matching the parameter 'runlevel=default' at the kernel's commandline, a working regular expression would be "runlevel=(\S*)". This could be written here as "*runlevel=%#". For matching e.g. numbers, you'd most possibly best of with writing your own & callback. returns: 1 on match, 0 on no match ( RE_MATCH / RE_NOMATCH ) if the pointer (argument 5) st_match is nonnull, the supplied struct text_match will be set to the first matching '%' location; if there is no match, text_match.len will be set to 0. The struct is defined as: typedef struct _text_match { char* pos; int len; } text_match; (memo) When the regex ist defined within C/cpp source code, a backslash has to be defined as double backslash. (note) - be careful when negating a following *, or ?. somehow - it is logical, but seems to me I overshoot a bit, tragically hit my own foot, and stumbled into a logical paradox. Negating EVERYTHING translates to true. However, since truth is negated as well, there's a problem, cause it's now 'false', but 'false' is true. This is very close to proving 42 is the answer. What is the escape velocity in km/s out of the solar system, btw. (I'm not kidding here. Just don't do a regex with !* or !?.. And, please, do not ask me what is going to happen when the impossible gets possibilized. I have to point at the according sentences of the BSD license; there is NO WARRANTY for CONSEQUENTIAL DAMAGE, LOSS OF PROFIT, etc pp.) A "!+" will translate into nongreedy matching of any char, however; "%!+" will match with % everything but the last char; while "%+" matches with % only the first char. !+ basically sets the greedyness of the left * or % higher. (work in progress here) please use ext_match return 0 for nomatch, the current textpos ( >0 ) for a match With the exception of an empty text, matched by e.g. "*". This will return 0, albite the regex formally matches, with 0 chars. (todo) bracket matching () and {} needs debugging. (test/extmatch2 for testing) Add a callback for bracket matches, and add a matchlist (linked list, allocated with malloc_brk) Trouble: e.g. *:(*) doesn't match, albite it should .. better. Now: # matches the end, after a bracket. Like it should $ doesn't. But should as well. change '+' to greedy matching of any char for {n,X} let n be * or + as well. (this would be closer to regular regulars again.?.) note. About a tokenizer: matching quoted string is really easy with the callback structure: just match with &. When a quote is matched, look forward to the next quote, and return that many chars. Same time, the quoted string is matched. That's so easy, it is hard to believe. When using closures for that, it is same time easy to collect all tokens. It is even easier. just a "*("*")*" is enough. ->There is something needed for partial matching. Possibly spare the last *, and return, as soon the pattern is at it's end (and not the text?) Already works this way. Should start to define the language for the init scripts. Or better, start thinking abut that, but follow my other obligations the next time. Have to think thouroughly about what points would make such a language useful. The reason to think about that is clear - performance squeezing, faster startup time. And writing the startup scripts in C is. Well. little bit painful. However, together with minilib, there is nearly no difference between having a C program compiled and run, or working with scripts. To not have the overhead of linking the external libraries in, is of quite some advance. The only difference, the compiled binaries are "cached". have just to sort something sensible out for the systematic. Implement an own loader? possibly easy. Since the loading address is fixed. This could possibly also be the solution for the yet unclear question of the line between parsing arguments and calling the main function of the small core tools, andsoon. ..yet I've to fiddle out the possibilities (and quirks) of this machine. seems, this expression language did overpower it's creator. Bugs (features): matching e.g. *matches*@*doesn't match* potentiates the *@* to many possibilities. One for every linebreak following 'matches'.
- memchr
-
void* memchr(const void *s, int c, unsigned int n)
../src/memory/memchr.c l.2 manpage: memchr
- msync
-
int msync( void* addr, size_t len, int flags)
../include/syscall_stubs.h l.262 manpage: msync
- network
-
__
network definitions
- ntohl
-
#define ntohl(i) htonl(i)
../src/network/ntohl.h l.2 manpage: ntohl
- ntohs
-
#define ntohs(i) htons(i)
Defines: network
../src/network/macros.h l.2 manpage: ntohs
- optimization_fence
-
void optimization_fence(void*p)
prevent optimizations. cast a var to void*, and calling this, leaves the compiler unknown on what he can strip. The function attribute noipa means, the compiler doesn't know, what the function itself does. (the function does nothing, but don't tell that gcc, please..) therefore, everything used as parameter to this function, will be calculated, defined, and so on before. It's used for the globals, shich are pushed within _start onto the stack. since _start itself only provides a global pointer, and initialitzes some of the globals, but doesn't use them again, this construction is needed. more funnily, the function will never be called. It's past the asm inline syscall to exit. But again, luckily gcc doesn't know. All other options, like having the globals volatile, setting the optimization flag of _start to 0, having a volatile asm call with the globals as param, and so on, have been useless. All after all, seems to me, ai has it's restrictions. With less overhead the macro OPTFENCE(...) goes. There the call to the "ipa" function is jumped over, via asm inline instructions. Doesn't work with clang. But yet I also didn't it with clang.
- poll
-
int poll(struct pollfd *fds, nfds_t cnt, int timeout)
../include/poll.h l.25 manpage: poll
- prctl
-
int prctl( int option, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)
../include/syscall_stubs.h l.274
- pwent
-
__
define passwd and group structures
- qsort
-
void qsort(void base, size_t nel, size_t width, int (*comp)(const void *, const void *))
*Defines: swap
(quick) shell sort routine following the tradition, this isn't exactly a quicksort algorithm, albite named quicksort. It is a shell sort implementation, originally done by Ray Gardner, 5/90; which in turn I did find within musl.
../src/sort/qsort.c l.35 manpage: qsort
- readlink
-
int readlink( const char *path, char *buf, int bufsiz)
../include/syscall_stubs.h l.127 manpage: readlink
- recv
-
int recv(int sockfd, void buf, size_t len, int flags)
*Defines: recvfrom
../src/network/recv.c l.3 manpage: recv
- recvfrom
-
int recvfrom( int fd, void *ubuf, size_t size, unsigned flags, struct sockaddr *addr, unsigned int *addr_len)
../include/syscall_stubs.h l.236 manpage: recvfrom
- rt_sigsuspend
-
int rt_sigsuspend( const sigset_t *mask, size_t sigsetsize)
../include/syscall_stubs.h l.188
- sendto
-
int sendto( int fd, void *buff, size_t len, unsigned flags, struct sockaddr *addr, int addr_len)
../include/syscall_stubs.h l.239 manpage: sendto
- setbrk
-
int setbrk(long addr)
Defines: sys_brk
set the current brk wrapper for brk(), with type of brk changed to long
- setenv
-
int setenv( const char name, const char *value, int overwrite )
*Defines: stpcpy strcpy ret_errno strlen 0 environ
put a string into the environmental vars UNTESTED (!) TODO the supplied string's pointer is put into the environmental array of pointers. The supplied strings are copied into memory. If overwrite is zero, an existing environmental variable is not overritten. If overwrite is 1, the environmental variable is overwritten, but not(!) freed from memory. The supplied value is not checked for e.g. an '=' Returns: - 0 on success - EINVAL on error
../src/system/setenv.c l.15 manpage: setenv
- setresuid
-
int setresuid( uid_t *ruid, uid_t *euid, uid_t *suid)
../include/syscall_stubs.h l.211 manpage: setresuid
- setreuid
-
int setreuid( uid_t ruid, uid_t euid)
../include/syscall_stubs.h l.163 manpage: setreuid
- setrlimit
-
int setrlimit( unsigned int resource, struct rlimit *rlim)
../include/syscall_stubs.h l.232 manpage: setrlimit
- setsockopt
-
int setsockopt( int fd, int level, int optname, const void *optval, int optlen)
../include/syscall_stubs.h l.243 manpage: setsockopt
- short_errstr
-
const char* short_errstr(int num)
short error (errno) string. this adds about 2kB to the compiled binary(!)
- sigsuspend
-
int sigsuspend( const sigset_t mask )
*Defines: rt_sigsuspend
../src/process/sigaction.c l.53 manpage: sigsuspend
- snprintfs
-
int snprintfs( char* buf, int size, char *fmt, …)
prints formatted and unbuffered output into buf. only %s and %c are recognized. snprintfs instead of snprintf can save some bytes. untested
- socket
-
int socket( int family, int type, int protocol)
../include/syscall_stubs.h l.229 manpage: socket
- stpcpy
-
char *stpcpy(char *dest, const char *src)
copy src to dest, return a pointer to the last char +1 ( ending '0' )
../src/string/stpcpy.c l.3 manpage: stpcpy
- stplcpy
-
char *stplcpy(char *dest, const char *src, int size)
copy src to dest, return a pointer to the last char +1 ( ending '0' ) doesn't pad dest with 0, when size<src;
- stpncpy
-
char *stpncpy(char *dest, const char *src, int size)
copy src to dest, return a pointer to the last char +1 ( ending '0' ) Please note stplcpy (terminology borrowed from freebsd), which does the same, but doesn't pad dest with 0's.
../src/string/stpncpy.c l.6 manpage: stpncpy
- strcspn
-
int strcspn(const char *s1, const char *s2)
look for the first place in s1, containing one of the chars of s2. Optimizes a bit (+16Bytes code), when OPTIMIZE is defined
../src/string/strcspn.c l.6 manpage: strcspn
- strlcpy
-
char *strlcpy(char *dest, const char *src, int n)
copy max n chars from src to dest, when src is longer than dest, end dest[n-1] with '\0'.
../src/string/strlcpy.c l.5 manpage: strlcpy
- strncat
-
char* strncat( char* dst, const char* src, unsigned int n)
../src/string/strncat.c l.2 manpage: strncat
- strndup
-
char strndup(const char *source, int maxlen)
*Defines: stplcpy strlen 0
../src/string/strndup.c l.5 manpage: strndup
- strnlen
-
int strnlen(const char*str, int max)
return len of str. if str points to 0, return 0 if no 0 is within max chars of str, return max
../src/string/strnlen.c l.8 manpage: strnlen
- strpbrk
-
char* strpbrk(const char* s, const char* charset)
../src/string/strpbrk.c l.2 manpage: strpbrk
- strspn
-
int strspn(const char *s1, const char *s2)
../src/string/strspn.c l.2 manpage: strspn
- strtoimax
-
int strtoimax(const char *c, const char **endp, int base)
conversion
../src/string/strtoimax.c l.4 manpage: strtoimax
- strtok
-
char* strtok(char s, const char *delim)
*Defines: strtok_r
../src/string/strtok.c l.3 manpage: strtok
- strtok_r
-
char* strtok_r(char *s, const char *delim, char **last)
../src/string/strtok_r.c l.2 manpage: strtok_r
- strtoll
-
long long int strtoll(const char c, const char **endp, int base)
*Defines: strtol
conversion doesn't check for overflow(!) For linux x64, long long and long both have 64 bit. Therefore, strtoll just calls strtol
../src/string/strtoll.c l.8 manpage: strtoll
- sys_signame
-
_const char* sys_signame[] = _
abbreviated signal names, according to BSD > 4.2
../src/process/signames.h l.3 manpage: sys_signame
- tcgetpgrp
-
int tcgetpgrp(int fd)
../src/termios/tcgetpgrp.c l.2 manpage: tcgetpgrp
- tcsetpgrp
-
int tcsetpgrp(int fd, int pgrp)
../src/termios/tcsetpgrp.c l.2 manpage: tcsetpgrp
- term_width
-
int term_width()
Defines: environ termio
get the terminal width reads the environmental var COLS, if not present, returns 80. Doesn't check for the existence of a terminal.
- termio
-
__
termios structures and definitions
- timerfd_create
-
int timerfd_create( int clockid, int flags)
../include/syscall_stubs.h l.268
- timerfd_gettime
-
int timerfd_gettime( int ufd, struct itimerspec *otmr)
../include/syscall_stubs.h l.272
- timerfd_settime
-
int timerfd_settime( int ufd, int flags, const struct itimerspec *utmr, struct itimerspec *otmr)
../include/syscall_stubs.h l.270
- times
-
int times( struct tms *info)
../include/syscall_stubs.h l.149 manpage: times
- token_i
-
int token_i( userdb* udb, char **p )
../src/userdb/userdb.c l.33
- token_s
-
char *token_s( userdb *udb, char **p )
tokenizer for the passwd/group files. used by the group/user pwentry access functions. performance of subsequent calls could be improved by replacing all ':' and '\n' by 0's when loading the db file. it would be possible as well, testing not only single bytes, but integers of longs at once. However, in most cases, e.g. for big directories with many small files, in most cases all files do have the same owner and group. Since the last result to calls of the access functions is cached, there wouldn't be an improvement by optimizing the tokenizing functions. So I'm leaving this for now, as it is. And most possibly it would be better to implement bsd's cached versions of the user db access functions instead.
- unsetenv
-
int unsetenv( char name)
*Defines: ret_errno environ
remove a string from the environmental vars The env var is not free'd. (It's not possible, since we don't know whether the string has been allocated with malloc or has been setup by the system ) Returns: - 0 on success, - EINVAL: string was 0, did contain a '=', some other error
../src/system/unsetenv.c l.10 manpage: unsetenv
- userdb_open
-
int userdb_open(userdb udb, const char file)
Defines: fstat close write globals
../src/userdb/userdb_open.c l.3
- warn
-
#define warn( fmt … ) { fprintf(stderr,fmt ); }
Defines: write fileno strlen globals getpid kill
print an error message to stderr
../src/process/error.h l.33 manpage: warn
- where
-
int where(const char file,char *buf)
*Defines: access environ
locate an executable in PATH
- writesl
-
#define writesl(str) write(STDOUT_FILENO,str "\n",sizeof(str)+1)
Defines: write
write the constant str to stdout, followed by a newline. Computes length with sizeof(str) at compile time.
../include/prints.h l.93