Need remove the flag after every redraw.
[eco.git] / file.c
blob04c65f32978bc33a2605bc1c8ac42fbad41393d8
1 /*
2 * Copyright (C) 2008 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 E_File_Path *e_file_get_paths(char *file)
26 E_File_Path *paths;
27 char *s, *pwd, *slast;
28 int ndir_rem, i, count, len;
30 paths= (E_File_Path *)malloc(sizeof(E_File_Path));
31 paths->path= NULL;
32 paths->file= NULL;
33 paths->lock_file= NULL;
34 paths->locked= 0;
36 if (file[0] == '/') {
37 /* this is a absolute path, nothing to do here,
38 * just get the path.
40 s= strrchr(file, '/');
41 paths->path= (char *)malloc(s - file + 1);
42 strncpy(paths->path, file, s - file);
43 paths->path[s - file]= '\0';
44 paths->file= strdup(file);
46 else if (!strncmp(file, "..", 2)) {
47 /* ok, the "hard" case, relative path. */
48 ndir_rem= 1;
49 slast= NULL;
50 s= strstr(file, "..");
51 s++; /* skip the first. */
53 s= strstr(s, "..");
54 while (s) {
55 ndir_rem++;
56 s++;
57 slast= s;
58 s= strstr(s, "..");
61 /* get the current directory. */
62 pwd= getenv("PWD");
64 /* now we need remove ndir_rem from the path. */
65 len= strlen(pwd);
66 count= 0;
67 for (i= len-1; i > 0; i--) {
68 if (pwd[i] == '/') {
69 count++;
70 if (count == ndir_rem)
71 break;
75 if (!slast)
76 slast= file+3;
77 else
78 slast += 2; /* skip ./ */
80 paths->path= (char *)malloc(i+1);
81 strncpy(paths->path, pwd, i);
82 paths->path[i]= '\0';
83 paths->file= (char *)malloc(i + strlen(slast) + 2);
84 strncpy(paths->file, pwd, i);
85 sprintf(paths->file+i, "/%s", slast);
87 else {
88 pwd= getenv("PWD");
89 paths->path= strdup(pwd);
90 paths->file= (char *)malloc(strlen(paths->path) + strlen(file) + 2);
91 sprintf(paths->file, "%s/%s", paths->path, file);
94 if (paths->file) {
95 paths->lock_file= (char *)malloc(strlen(paths->file)+6);
96 sprintf(paths->lock_file, "%s.eco~", paths->file);
99 return(paths);
102 int e_file_is_lock(E_File_Path *paths)
104 struct stat st;
106 if (stat(paths->lock_file, &st))
107 return(0); /* not locked. */
108 return(1); /* locked. */
111 void e_file_lock(E_File_Path *paths)
113 FILE *fp;
115 fp= fopen(paths->lock_file, "w");
116 if (fp) {
117 paths->locked= 1;
118 fprintf(fp, "Eco lock file\n");
119 fclose(fp);
123 void e_file_lock_rem(E_File_Path *paths)
125 if (paths->locked) {
126 unlink(paths->lock_file);
127 paths->locked= 0;
131 E_Buffer *e_file_read(char *file, int *status)
133 struct stat st;
134 E_Buffer *bf;
135 FILE *fp;
136 int c;
138 /* clean error status. */
139 *status= 0;
141 bf= e_buffer_new(file);
142 if (!bf)
143 return(NULL);
145 if (stat(bf->paths->file, &st)) {
146 e_buffer_free(bf);
147 return(NULL);
150 if (e_file_is_lock(bf->paths)) {
151 /* we already have this file open!! in other session!! */
152 *status= 2;
153 e_buffer_free(bf);
154 return(NULL);
157 if (!(S_ISREG(st.st_mode))) {
158 /* this is not a regular file. */
159 *status= 1;
161 e_buffer_free(bf);
162 return(NULL);
165 fp= fopen(bf->paths->file, "r");
166 if (!fp) {
167 /* the file exist, but we can't read it. */
168 *status= 1;
170 e_buffer_free(bf);
171 return(NULL);
174 c= fgetc(fp);
175 while (!feof(fp)) {
176 if (c == '\n')
177 e_buffer_newline(bf);
178 else if (c == '\t')
179 e_buffer_insert(bf, '\t');
180 else
181 e_buffer_insert(bf, c);
182 c= fgetc(fp);
185 /* always go to the start with new files. */
186 e_buffer_goto_begin(bf);
188 /* e_buffer_insert/newline mark the buffer with changes,
189 * but in this case we are reading the file, so unmark
190 * when we finish.
192 BUFFER_UNSET(bf, BUFFER_FLUSH);
194 /* and lock the file. */
195 e_file_lock(bf->paths);
197 fclose(fp);
198 return(bf);
201 void e_file_write(E_Eco *ec, E_Buffer *bf)
203 FILE *fp;
204 E_Line *ln;
205 int i, nlines;
207 if (!(bf->flag & BUFFER_FLUSH))
208 return;
210 fp= fopen(bf->paths->file, "w");
211 if (!fp)
212 return;
214 ln= bf->lines;
215 nlines= 0;
216 while (ln) {
217 for (i= 0; i < ln->used; i++)
218 fputc(ln->text[i], fp);
220 if (ln->next)
221 fputc('\n', fp);
222 nlines++;
223 ln= ln->next;
226 fclose(fp);
227 BUFFER_UNSET(bf, BUFFER_FLUSH);
229 e_status_set_msg(ec, "(Wrote %d lines)", nlines);