1
0

more cleaning

This commit is contained in:
dtb
2022-09-18 10:44:47 -04:00
parent 49b9f21067
commit 9189124f2d
26 changed files with 13 additions and 410 deletions

116
libio/libio.c Normal file
View File

@@ -0,0 +1,116 @@
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "libio.h"
/* Backups of standard library systems for the odd scenario where there is no
* standard library but there is the write(2) system call. */
static int _isdigit(int c);
static int _strlen(char *s);
/* Wrappers around write(2) */
static int _write(int fd, char *s, int n);
static int _write1(int fd, int c);
/* Normally in <ctype.h> */
static int
_isdigit(int c){
return c >= '0' && c <= '9';
}
/* Normally in <string.h> */
static int
_strlen(char *s){
int i;
for(i = 0; s[i] != '\0'; ++i);
return i;
}
/* Wrapper around write(2) - keeps re-running write(2) until the operation
* succeeds in full. Usually unnecessary but still good. */
static int
_write(int fd, char *s, int n){
int i;
for(
i = 0;
i < n;
i += write(fd, s+i, n-i)
);
return i;
}
/* For writing a single character. To optimize for speed, functions should
* allocate a buffer and add to that buffer before write(2)ing the buffer out
* in a single system call. However sometimes cheap tricks are as effective. */
static int
_write1(int fd, int c){
while(write(fd, &c, 1) != 1);
return 1;
}
int
fdprint(int fd, char *s){
return _write(fd, s, strlen(s));
}
int
fdputd(int fd, int d){
int r;
int s;
r = 0;
/* Just an implementation looking for a math person to improve it... */
/* Rather than storing the log base 10 of d, store 10^(log base 10 (d))
* which requires less Weird Hax. Then slowly chop off digits and print
* out the system encoding's representations. Finally, print a newline.
* Generally this function is slow and sucks implementation-wise. */
if(d < 100){
s = d < 10 ? 1 : 10;
goto put;
}
for(s = 10; d > (s *= 10););
put: while(s > 0){
r += _write1(fd, (d - (d % s)) / s + '0');
if((s /= 10) == 0)
r += _write1(fd, '\n');
}
return r;
}
int
fdputs(int fd, char *s){
int i;
int r;
i = strlen(s);
/* RACE CONDITION */
/* This leaves s as an invalid string while the write(2) syscall is
* performed, which can take a non-trivial amount of time. This
* implementation is unsuitable when s is shared between threads or
* whatever the CS term for that is. */
s[i] = '\n';
r = _write(fd, s, i + 1);
s[i] = '\0';
return r;
}
/* Another possible implementation would take char **s and leave *s at the next
* non-digit. But that's less simple; just while(isdigit(*s)) ++s;. */
unsigned int
parse_uint(char *s){
unsigned int r;
for(
r = 0;
isdigit(*s);
r = r * 10 + *s - '0',
++s
);
return r;
}

7
libio/libio.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _LIBIO_H
# define _LIBIO_H
int fdprint(int fd, char *s);
int fdputd(int fd, int d);
int fdputs(int fd, char *s);
unsigned int parse_uint(char *s);
#endif /* ifndef _LIBIO_H */