debugging
[rrq/rrqmisc.git] / tests / example-vector.c
1 #include <arpa/inet.h>
2 #include <errno.h>
3 #include <fcntl.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/stat.h>
8 #include <sys/types.h>
9 #include <unistd.h>
10 #include "vector.h"
11
12 typedef struct _ipslot {
13     int family;
14     unsigned int bits;
15     char data[16];
16 } ipslot;
17
18 static struct {
19     vector data;
20     int fill;
21 } table;
22
23 #define BUFSZ 10000
24 static struct {
25     char data[ BUFSZ ];
26     int cur;
27     int end;
28 } stream;
29
30 static int readline(int fd,char **outp) {
31     for ( ;; ) {
32         char *curp = stream.data + stream.cur;
33         char *endp = stream.data + stream.end;
34         char *top = curp;
35         while  ( curp < endp ) {
36             if ( *(curp++) == '\n' ) {
37                 stream.cur = curp - stream.data;
38                 (*outp) = top;
39                 return curp - top;
40             }
41         }
42         if ( top != stream.data ) {
43             curp = stream.data;
44             while ( top < endp ) {
45                 *(curp++) = *(top++);
46             }
47             endp = curp;
48             stream.end = endp - stream.data;
49         }
50         stream.cur = 0;
51         ssize_t n = read( fd, endp, BUFSZ - stream.end );
52         if ( n <= 0 ) {
53             if ( stream.end == 0 ) {
54                 return -1; // No more data
55             }
56             (*outp) = stream.data;
57             return stream.end;
58         }
59         stream.end += n;
60     }
61     //unreachable
62 }
63
64 // Scan to NUL, CR or c. Return pointer not including character.
65 static char *scanto(char *p, char c) {
66     while ( *p && *p != '\n' && *p != c ) {
67         p++;
68     }
69     return p;
70 }
71
72 static int parse_addr(char *line,ipslot *addr) {
73     char *end = scanto( line, '\n' );
74     char *slash = scanto( line, '/' );
75     *slash = 0;
76     *end = 0;
77     if ( scanto( line, ':' ) != slash ) {
78         fprintf( stdout, "AF_INET6: %s\n", line );
79         if ( inet_pton( AF_INET6, line, addr->data ) == 1 ) {
80             addr->family = AF_INET6;
81             addr->bits = 128;
82         } else {
83             return 1;
84         }
85     } else if ( inet_pton( AF_INET, line, addr->data ) == 1 ) {
86         fprintf( stdout, "AF_INET: %s\n", line );
87         addr->family = AF_INET;
88         addr->bits = 32;
89     } else {
90         return 1;
91     }
92     if ( slash != end && sscanf( slash+1, "%u", &addr->bits ) != 1 ) {
93         return 1;
94     }
95     return 0;
96 }
97
98 static void add_entry(ipslot *tmp) {
99     ipslot *p = (ipslot *) malloc( sizeof( ipslot ) );
100     memmove( p, tmp, sizeof( ipslot ) );
101     if ( table.data.size == table.fill ) {
102         (void) vector_resize( &table.data, table.fill + 256, 0, 0 );
103     }
104     vector_set( &table.data, table.fill++, p );
105 }
106
107 static void load_file(const char *filename) {
108     int fd = open( filename, O_RDONLY );
109     if ( fd < 0 ) {
110         perror( filename );
111         exit( errno );
112     }
113     char *line;
114     int n;
115     while ( ( n = readline( fd, &line ) ) >= 0 ) {
116         ipslot addr;
117         if ( parse_addr( line, &addr ) ) {
118             fprintf( stderr, "Bad address: %s\n", line );
119             continue;
120         }
121         add_entry( &addr );
122     }
123 }
124
125 static int int_reclaim(vector *pv,unsigned long index,void *item,void *data) {
126     return 0;
127 }
128
129 static int dumpitem(const unsigned long index,const void *item) {
130     fprintf( stdout, "[%ld] %p\n", index, item );
131     return 0;
132 }
133
134 static int dump_ipslot(const unsigned long index,const void *item) {
135     static char buffer[100];
136     ipslot *ip = (ipslot*) item;
137     const char *p = inet_ntop( ip->family, ip->data, buffer, 100 );
138     fprintf( stdout, "[%ld] %s/%d\n", index, p, ip->bits );
139     return 0;
140 }
141
142 int main(int argc,char **argv) {
143     vector test = { 0 };
144     vector_resize( &test, 100, 0, 0 );
145     vector_set( &test, 5, (void*) 500 );
146     vector_set( &test, 55, (void*) 600 );
147     vector_resize( &test, 300, 0, 0 );
148     vector_set( &test, 55, (void*) 650 );
149     vector_resize( &test, 30000, 0, 0 );
150     vector_set( &test, 22255, (void*) 26 );
151     vector_dump( &test, dumpitem );
152     vector_resize( &test, 100, int_reclaim, 0 );
153     vector_set( &test, 5, (void*) 2 );
154     vector_dump( &test, dumpitem );
155
156     int i;
157     for ( i = 1; i < argc; i++ ) {
158         load_file( argv[ i ] );
159     }
160     vector_dump( &table.data, dump_ipslot );
161
162     return 0;
163 }