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