-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathaddons.c
120 lines (98 loc) · 2.74 KB
/
addons.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// addons.c
// C functions used by FORTH
#include <sys/select.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
// used by KEY? to tell if there is any pending key press.
extern int kb_hit(void)
{
fd_set read_fd;
struct timeval tv ;
tv.tv_sec=0;
tv.tv_usec=0;
FD_ZERO(&read_fd);
FD_SET(0, &read_fd);
return select( 1, &read_fd, 0, 0, &tv);
}
// assist with file errors from C runtime.
extern int get_errno(){
return errno;
}
extern char* get_errstr(int n){
return strerror(n);
}
// sorted string pool
// I got fed up with the huge sparse string literal pool,
// and added this for the time being.
const int pool_size = 4096;
int next_string=0;
char* pool[pool_size];
int stringcompare(const void *a, const void *b) {
// look at string pointers
if( a == NULL && b == NULL) return 0;
if( a == NULL && b != NULL) return 1;
if( a != NULL && b == NULL) return -1;
// other wise look at string contents
char* as = *(char **)a;
char* bs = *(char **)b;
int r = strncmp( as, bs, 256 );
return r;
}
extern void init_string_pool() {
for( int i=0; i<pool_size; i++) {
pool[i]=NULL;
}
}
int free_index() {
for( int i=0; i < pool_size; i++) {
if (pool[i]==NULL ) return i;
}
return -1;
}
void sort_strings() {
qsort( pool, next_string, sizeof(char *), stringcompare);
}
char** find_string( const char *s) {
const char* key = s;
return (char**)bsearch( (const void *)&key, pool, next_string, sizeof(char*), stringcompare);
}
extern void list_strings() {
puts("\nList literal strings");
printf("\nCapacity %d used %d", pool_size, next_string-1);
for(int i=0; i<pool_size; i++) {
if( pool[i] != NULL) {
printf("\n%3d - %s", i, pool[i]);
}
}
}
void del_string( const char* s) {
char** l =find_string(s);
int n=((long)l-(long)&pool)/sizeof(char*);
if( pool[n] !=NULL) {
free(pool[n]);
}
for( int i=n; i<pool_size-1; i++) {
pool[i]=pool[i+1];
}
next_string--;
}
extern long locate_string( const char* s) {
char** l= find_string(s);
if( l==NULL) {
return 0;
}
return (long)*l;
}
// add string literal. only if we don't have it already
extern long add_string( const char* s) {
long l=locate_string(s);
if( l==0) {
pool[next_string] = strdup(s);
l=(long)pool[next_string];
next_string++;
sort_strings();
}
return l;
}