foo
[visor] / visor / src / main_unix.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/mman.h>
6 #include <sys/stat.h>
7 #include "term.h"
8 #include "visor.h"
9
10 struct file {
11         int fd;
12         void *maddr;
13         size_t msize;
14 };
15
16 static int parse_args(int argc, char **argv);
17 static int init(void);
18 static void cleanup(void);
19 static void resized(int x, int y);
20 /* file operations */
21 static vi_file *file_open(const char *path, unsigned int flags);
22 static void file_close(vi_file *file);
23 static long file_size(vi_file *file);
24 static void *file_map(vi_file *file);
25 static void file_unmap(vi_file *file);
26 static long file_read(vi_file *file, void *buf, long count);
27 static long file_write(vi_file *file, void *buf, long count);
28 static long file_seek(vi_file *file, long offs, int whence);
29
30 static struct visor *vi;
31
32 static int num_fpaths;
33 static char **fpaths;
34
35 static struct vi_alloc alloc = {
36         malloc, free, realloc
37 };
38
39 static struct vi_fileops fops = {
40         file_open, file_close, file_size,
41         file_map, file_unmap,
42         file_read, file_write, file_seek
43 };
44
45 /*
46 static struct vi_ttyops ttyops = {
47         tty_clear, tty_clear_line, tty_clear_line_at,
48         tty_setcursor, tty_putchar, tty_putchar_at,
49         tty_scroll, tty_del_back, tty_del_fwd, tty_status
50 };
51 */
52
53 int main(int argc, char **argv)
54 {
55         if(parse_args(argc, argv) == -1) {
56                 return 1;
57         }
58         if(init() == -1) {
59                 return 1;
60         }
61
62         vi_redraw(vi);
63
64         for(;;) {
65                 int c = term_getchar();
66
67                 switch(c) {
68                 case 27:
69                 case 'q':
70                         goto end;
71                 }
72         }
73 end:
74
75         cleanup();
76         return 0;
77 }
78
79 static int parse_args(int argc, char **argv)
80 {
81         int i;
82
83         fpaths = argv + 1;
84         num_fpaths = 0;
85         for(i=1; i<argc; i++) {
86                 if(argv[i][0] == '-') {
87                         fprintf(stderr, "invalid option: %s\n", argv[i]);
88                         return -1;
89                 } else {
90                         argv[++num_fpaths] = argv[i];
91                 }
92         }
93         return 0;
94 }
95
96 static int init(void)
97 {
98         int i;
99
100         if(term_init(0) == -1) {
101                 return -1;
102         }
103         term_clear();
104
105         if(!(vi = vi_create(&alloc))) {
106                 return -1;
107         }
108         vi_set_fileops(vi, &fops);
109
110         for(i=0; i<num_fpaths; i++) {
111                 if(!vi_new_buf(vi, fpaths[i])) {
112                         return -1;
113                 }
114         }
115         return 0;
116 }
117
118 static void cleanup(void)
119 {
120         if(vi) {
121                 vi_destroy(vi);
122         }
123         term_cleanup();
124 }
125
126 static vi_file *file_open(const char *path, unsigned int flags)
127 {
128         struct file *file;
129
130         if(!(file = calloc(1, sizeof *file))) {
131                 return 0;
132         }
133         if((file->fd = open(path, flags)) == -1) {
134                 free(file);
135                 return 0;
136         }
137         return (vi_file*)file;
138 }
139
140 static void file_close(vi_file *vif)
141 {
142         struct file *file = vif;
143         if(!file) return;
144
145         if(file->fd >= 0) {
146                 if(file->maddr) {
147                         file_unmap(file);
148                 }
149                 close(file->fd);
150         }
151         free(file);
152 }
153
154 static long file_size(vi_file *vif)
155 {
156         struct file *file = vif;
157         struct stat st;
158
159         if(fstat(file->fd, &st) == -1) {
160                 return -1;
161         }
162         return st.st_size;
163 }
164
165 static void *file_map(vi_file *vif)
166 {
167         struct file *file = vif;
168         long sz;
169
170         if((sz = file_size(file)) == -1) {
171                 return 0;
172         }
173         if((file->maddr = mmap(0, sz, PROT_READ, MAP_PRIVATE, file->fd, 0)) == (void*)-1) {
174                 return 0;
175         }
176         file->msize = sz;
177         return file->maddr;
178 }
179
180 static void file_unmap(vi_file *vif)
181 {
182         struct file *file = vif;
183         if(file->maddr) {
184                 munmap(file->maddr, file->msize);
185         }
186         file->maddr = 0;
187 }
188
189 static long file_read(vi_file *vif, void *buf, long count)
190 {
191         struct file *file = vif;
192         return read(file->fd, buf, count);
193 }
194
195 static long file_write(vi_file *vif, void *buf, long count)
196 {
197         struct file *file = vif;
198         return write(file->fd, buf, count);
199 }
200
201 static long file_seek(vi_file *vif, long offs, int whence)
202 {
203         struct file *file = vif;
204         return lseek(file->fd, offs, whence);
205 }