Add xterm-256color as a valid terminal.
[eco.git] / file.c
blob6bb37be11cf8c8e9f84a8d868bbb924e7739e637
1 /*
2 * Copyright (C) 2008 - 2012 Diego Hernan Borghetti.
3 * Eco
4 */
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <stdarg.h>
12 #include <unistd.h>
14 #include "debug.h"
15 #include "term.h"
16 #include "screen.h"
17 #include "buffer.h"
18 #include "view.h"
19 #include "eco.h"
20 #include "status.h"
21 #include "file.h"
24 /* Buffer size for read file. */
25 #define BUF_SIZE 8192
27 E_File_Path *e_file_get_paths(char *file)
29 E_File_Path *paths;
30 char *s, *pwd, *slast;
31 int ndir_rem, i, count, len;
33 paths= (E_File_Path *)malloc(sizeof(E_File_Path));
34 paths->path= NULL;
35 paths->file= NULL;
36 paths->lock_file= NULL;
37 paths->locked= 0;
39 if (file[0] == '/') {
40 /* this is a absolute path, nothing to do here,
41 * just get the path.
43 s= strrchr(file, '/');
44 paths->path= (char *)malloc(s - file + 1);
45 strncpy(paths->path, file, s - file);
46 paths->path[s - file]= '\0';
47 paths->file= strdup(file);
49 else if (!strncmp(file, "..", 2)) {
50 /* ok, the "hard" case, relative path. */
51 ndir_rem= 1;
52 slast= NULL;
53 s= strstr(file, "..");
54 s++; /* skip the first. */
56 s= strstr(s, "..");
57 while (s) {
58 ndir_rem++;
59 s++;
60 slast= s;
61 s= strstr(s, "..");
64 /* get the current directory. */
65 pwd= getenv("PWD");
67 /* now we need remove ndir_rem from the path. */
68 len= strlen(pwd);
69 count= 0;
70 for (i= len-1; i > 0; i--) {
71 if (pwd[i] == '/') {
72 count++;
73 if (count == ndir_rem)
74 break;
78 if (!slast)
79 slast= file+3;
80 else
81 slast += 2; /* skip ./ */
83 paths->path= (char *)malloc(i+1);
84 strncpy(paths->path, pwd, i);
85 paths->path[i]= '\0';
86 paths->file= (char *)malloc(i + strlen(slast) + 2);
87 strncpy(paths->file, pwd, i);
88 sprintf(paths->file+i, "/%s", slast);
90 else {
91 pwd= getenv("PWD");
92 paths->path= strdup(pwd);
93 paths->file= (char *)malloc(strlen(paths->path) + strlen(file) + 2);
94 sprintf(paths->file, "%s/%s", paths->path, file);
97 if (paths->file) {
98 paths->lock_file= (char *)malloc(strlen(paths->file)+6);
99 sprintf(paths->lock_file, "%s.eco~", paths->file);
102 return(paths);
105 int e_file_is_lock(E_File_Path *paths)
107 struct stat st;
109 if (stat(paths->lock_file, &st))
110 return(0); /* not locked. */
111 return(1); /* locked. */
114 void e_file_lock(E_File_Path *paths)
116 FILE *fp;
118 fp= fopen(paths->lock_file, "w");
119 if (fp) {
120 paths->locked= 1;
121 fprintf(fp, "Eco lock file\n");
122 fclose(fp);
126 void e_file_lock_rem(E_File_Path *paths)
128 if (paths->locked) {
129 unlink(paths->lock_file);
130 paths->locked= 0;
134 E_Buffer *e_file_read(char *file, int *status)
136 struct stat st;
137 E_Buffer *bf;
138 FILE *fp;
139 char buf[BUF_SIZE];
140 int rb;
142 /* clean error status. */
143 *status= 0;
145 bf= e_buffer_new(file);
146 if (!bf)
147 return(NULL);
149 if (stat(bf->paths->file, &st)) {
150 e_buffer_free(bf);
151 return(NULL);
154 if (e_file_is_lock(bf->paths)) {
155 /* we already have this file open!! in other session!! */
156 *status= 2;
157 e_buffer_free(bf);
158 return(NULL);
161 if (!(S_ISREG(st.st_mode))) {
162 /* this is not a regular file. */
163 *status= 1;
165 e_buffer_free(bf);
166 return(NULL);
169 fp= fopen(bf->paths->file, "r");
170 if (!fp) {
171 /* the file exist, but we can't read it. */
172 *status= 1;
174 e_buffer_free(bf);
175 return(NULL);
178 /* Mark the buffer to avoid auto-complet of
179 * new lines.
181 bf->flag |= BUFFER_NOIDENT;
183 /* Read the file. */
184 do {
185 rb= fread((void *)&buf[0], 1, BUF_SIZE, fp);
186 if (rb > 0)
187 e_buffer_insert_str(bf, &buf[0], rb);
188 } while (rb == BUF_SIZE);
190 /* always go to the start with new files. */
191 e_buffer_goto_begin(bf);
193 /* e_buffer_insert/newline mark the buffer with changes,
194 * but in this case we are reading the file, so unmark
195 * when we finish.
197 BUFFER_UNSET(bf, BUFFER_FLUSH);
199 /* and lock the file. */
200 e_file_lock(bf->paths);
202 /* Remove the mark. */
203 bf->flag &= ~BUFFER_NOIDENT;
205 fclose(fp);
206 return(bf);
209 void e_file_write(E_Eco *ec, E_Buffer *bf)
211 FILE *fp;
212 E_Line *ln;
213 int i, nlines;
215 if (!(bf->flag & BUFFER_FLUSH))
216 return;
218 fp= fopen(bf->paths->file, "w");
219 if (!fp)
220 return;
222 ln= bf->lines;
223 nlines= 0;
224 while (ln) {
225 for (i= 0; i < ln->used; i++)
226 fputc(ln->text[i], fp);
228 if (ln->next)
229 fputc('\n', fp);
230 nlines++;
231 ln= ln->next;
234 fclose(fp);
235 BUFFER_UNSET(bf, BUFFER_FLUSH);
237 e_status_set_msg(ec, "(Wrote %d lines)", nlines);