Krolyxon
Commit ff013dd

Branches

Refs →

nsxivff013dd

Revised handling of file names & paths

Author
Bert
Date
2011-08-18 00:38 +0200
Parent
2a3a965
Commit
ff013dd0092df247b2c9f1c550e03542581ed21d

+100 −81

10 files changed

  1. M Makefile +1 −1
  2. M events.c +15 −15
  3. M image.c +4 −4
  4. M image.h +1 −1
  5. M main.c +41 −28
  6. M thumbs.c +19 −30
  7. M thumbs.h +2 −2
  8. M types.h +5 −0
  9. M util.c +11 −0
  10. M util.h +1 −0
M Makefile View
@@ -1,6 +1,6 @@
11 all: sxiv
22
3−VERSION = 0.9
3+VERSION = git-20110818
44
55 CC = gcc
66 DESTDIR =
M events.c View
@@ -52,7 +52,7 @@ extern img_t img;
5252 extern tns_t tns;
5353 extern win_t win;
5454
55−extern char **filenames;
55+extern fileinfo_t *files;
5656 extern int filecnt, fileidx;
5757
5858 int timo_cursor;
@@ -163,7 +163,7 @@ void run() {
163163 gettimeofday(&t0, 0);
164164
165165 while (tns.cnt < filecnt && !XPending(win.env.dpy)) {
166− if (tns_load(&tns, tns.cnt, filenames[tns.cnt], 0))
166+ if (tns_load(&tns, tns.cnt, &files[tns.cnt], 0))
167167 tns.cnt++;
168168 else
169169 remove_file(tns.cnt, 0);
@@ -513,7 +513,7 @@ int open_with(arg_t a) {
513513
514514 if((pid = fork()) == 0) {
515515 execlp(prog, prog,
516− filenames[mode == MODE_NORMAL ? fileidx : tns.sel], NULL);
516+ files[mode == MODE_NORMAL ? fileidx : tns.sel].path, NULL);
517517 warn("could not exec: %s", prog);
518518 exit(1);
519519 } else if (pid < 0) {
@@ -526,30 +526,30 @@ int open_with(arg_t a) {
526526 int run_command(arg_t a) {
527527 const char *cline = (const char*) a;
528528 char *cn, *cmdline;
529− const char *co, *fname;
530− int fncnt, fnlen, status;
529+ const char *co, *fpath;
530+ int fpcnt, fplen, status;
531531 pid_t pid;
532532
533533 if (!cline || !*cline)
534534 return 0;
535535
536536 /* build command line: */
537− fncnt = 0;
537+ fpcnt = 0;
538538 co = cline - 1;
539539 while ((co = strchr(co + 1, '#')))
540− fncnt++;
541− if (!fncnt)
540+ fpcnt++;
541+ if (!fpcnt)
542542 return 0;
543− fname = filenames[mode == MODE_NORMAL ? fileidx : tns.sel];
544− fnlen = strlen(fname);
545− cn = cmdline = (char*) s_malloc((strlen(cline) + fncnt * (fnlen + 2)) *
543+ fpath = files[mode == MODE_NORMAL ? fileidx : tns.sel].path;
544+ fplen = strlen(fpath);
545+ cn = cmdline = (char*) s_malloc((strlen(cline) + fpcnt * (fplen + 2)) *
546546 sizeof(char));
547547 /* replace all '#' with filename: */
548548 for (co = cline; *co; co++) {
549549 if (*co == '#') {
550550 *cn++ = '"';
551− strcpy(cn, fname);
552− cn += fnlen;
551+ strcpy(cn, fpath);
552+ cn += fplen;
553553 *cn++ = '"';
554554 } else {
555555 *cn++ = *co;
@@ -575,11 +575,11 @@ int run_command(arg_t a) {
575575
576576 if (mode == MODE_NORMAL) {
577577 if (fileidx < tns.cnt)
578− tns_load(&tns, fileidx, filenames[fileidx], 1);
578+ tns_load(&tns, fileidx, &files[fileidx], 1);
579579 img_close(&img, 1);
580580 load_image(fileidx);
581581 } else {
582− if (!tns_load(&tns, tns.sel, filenames[tns.sel], 0)) {
582+ if (!tns_load(&tns, tns.sel, &files[tns.sel], 0)) {
583583 remove_file(tns.sel, 0);
584584 tns.dirty = 1;
585585 if (tns.sel >= tns.cnt)
M image.c View
@@ -50,12 +50,12 @@ void img_init(img_t *img, win_t *win) {
5050 }
5151 }
5252
53−int img_load(img_t *img, const char *filename) {
54− if (!img || !filename)
53+int img_load(img_t *img, const fileinfo_t *file) {
54+ if (!img || !file || !file->name || !file->path)
5555 return 0;
5656
57− if (access(filename, R_OK) || !(img->im = imlib_load_image(filename))) {
58− warn("could not open image: %s", filename);
57+ if (access(file->path, R_OK) || !(img->im = imlib_load_image(file->path))) {
58+ warn("could not open image: %s", file->name);
5959 return 0;
6060 }
6161
M image.h View
@@ -43,7 +43,7 @@ typedef struct {
4343
4444 void img_init(img_t*, win_t*);
4545
46−int img_load(img_t*, const char*);
46+int img_load(img_t*, const fileinfo_t*);
4747 void img_close(img_t*, int);
4848
4949 void img_render(img_t*, win_t*);
M main.c View
@@ -25,6 +25,7 @@
2525 #include "image.h"
2626 #include "options.h"
2727 #include "thumbs.h"
28+#include "types.h"
2829 #include "util.h"
2930 #include "window.h"
3031
@@ -38,7 +39,7 @@ img_t img;
3839 tns_t tns;
3940 win_t win;
4041
41−char **filenames;
42+fileinfo_t *files;
4243 int filecnt, fileidx;
4344 size_t filesize;
4445
@@ -54,21 +55,30 @@ void cleanup() {
5455 }
5556 }
5657
57−int check_add_file(char *filename) {
58− if (!filename)
59− return 0;
58+void check_add_file(char *filename) {
59+ if (!filename || !*filename)
60+ return;
6061
6162 if (access(filename, R_OK)) {
6263 warn("could not open file: %s", filename);
63− return 0;
64− } else {
65− if (fileidx == filecnt) {
66− filecnt *= 2;
67− filenames = (char**) s_realloc(filenames, filecnt * sizeof(char*));
64+ return;
65+ }
66+
67+ if (fileidx == filecnt) {
68+ filecnt *= 2;
69+ files = (fileinfo_t*) s_realloc(files, filecnt * sizeof(fileinfo_t));
70+ }
71+ if (*filename != '/') {
72+ files[fileidx].path = absolute_path(filename);
73+ if (!files[fileidx].path) {
74+ warn("could not get absolute path of file: %s\n", filename);
75+ return;
6876 }
69− filenames[fileidx++] = filename;
70− return 1;
7177 }
78+ files[fileidx].name = s_strdup(filename);
79+ if (*filename == '/')
80+ files[fileidx].path = files[fileidx].name;
81+ fileidx++;
7282 }
7383
7484 void remove_file(int n, unsigned char silent) {
@@ -82,9 +92,12 @@ void remove_file(int n, unsigned char silent) {
8292 exit(!silent);
8393 }
8494
85− if (n + 1 < filecnt)
86− memmove(filenames + n, filenames + n + 1, (filecnt - n - 1) *
87− sizeof(char*));
95+ if (n + 1 < filecnt) {
96+ if (files[n].path != files[n].name)
97+ free((void*) files[n].path);
98+ free((void*) files[n].name);
99+ memmove(files + n, files + n + 1, (filecnt - n - 1) * sizeof(fileinfo_t));
100+ }
88101 if (n + 1 < tns.cnt) {
89102 memmove(tns.thumbs + n, tns.thumbs + n + 1, (tns.cnt - n - 1) *
90103 sizeof(thumb_t));
@@ -106,14 +119,14 @@ void load_image(int new) {
106119 win_set_cursor(&win, CURSOR_WATCH);
107120 img_close(&img, 0);
108121
109− while (!img_load(&img, filenames[new])) {
122+ while (!img_load(&img, &files[new])) {
110123 remove_file(new, 0);
111124 if (new >= filecnt)
112125 new = filecnt - 1;
113126 }
114127
115128 fileidx = new;
116− if (!stat(filenames[new], &fstats))
129+ if (!stat(files[new].path, &fstats))
117130 filesize = fstats.st_size;
118131 else
119132 filesize = 0;
@@ -127,14 +140,14 @@ void update_title() {
127140 if (mode == MODE_THUMBS) {
128141 n = snprintf(win_title, TITLE_LEN, "sxiv: [%d/%d] %s",
129142 tns.cnt ? tns.sel + 1 : 0, tns.cnt,
130− tns.cnt ? filenames[tns.sel] : "");
143+ tns.cnt ? files[tns.sel].name : "");
131144 } else {
132145 size = filesize;
133146 size_readable(&size, &unit);
134147 n = snprintf(win_title, TITLE_LEN,
135148 "sxiv: [%d/%d] <%d%%> <%dx%d> (%.2f%s) %s",
136149 fileidx + 1, filecnt, (int) (img.zoom * 100.0), img.w, img.h,
137− size, unit, filenames[fileidx]);
150+ size, unit, files[fileidx].name);
138151 }
139152
140153 if (n >= TITLE_LEN) {
@@ -146,13 +159,13 @@ void update_title() {
146159 }
147160
148161 int fncmp(const void *a, const void *b) {
149− return strcoll(*((char* const*) a), *((char* const*) b));
162+ return strcoll(((fileinfo_t*) a)->name, ((fileinfo_t*) b)->name);
150163 }
151164
152165 int main(int argc, char **argv) {
153166 int i, len, start;
154167 size_t n;
155− char *filename = NULL;
168+ char *filename;
156169 struct stat fstats;
157170 r_dir_t dir;
158171
@@ -174,17 +187,16 @@ int main(int argc, char **argv) {
174187 else
175188 filecnt = options->filecnt;
176189
177− filenames = (char**) s_malloc(filecnt * sizeof(char*));
190+ files = (fileinfo_t*) s_malloc(filecnt * sizeof(fileinfo_t));
178191 fileidx = 0;
179192
180193 /* build file list: */
181194 if (options->from_stdin) {
195+ filename = NULL;
182196 while ((len = getline(&filename, &n, stdin)) > 0) {
183197 if (filename[len-1] == '\n')
184198 filename[len-1] = '\0';
185− if (!*filename || !check_add_file(filename))
186− free(filename);
187− filename = NULL;
199+ check_add_file(filename);
188200 }
189201 } else {
190202 for (i = 0; i < options->filecnt; i++) {
@@ -202,13 +214,14 @@ int main(int argc, char **argv) {
202214 continue;
203215 }
204216 start = fileidx;
217+ printf("reading dir: %s\n", filename);
205218 while ((filename = r_readdir(&dir))) {
206− if (!check_add_file(filename))
207− free((void*) filename);
219+ check_add_file(filename);
220+ free((void*) filename);
208221 }
209222 r_closedir(&dir);
210223 if (fileidx - start > 1)
211− qsort(filenames + start, fileidx - start, sizeof(char*), fncmp);
224+ qsort(files + start, fileidx - start, sizeof(fileinfo_t), fncmp);
212225 }
213226 }
214227 }
@@ -227,7 +240,7 @@ int main(int argc, char **argv) {
227240 if (options->thumbnails) {
228241 mode = MODE_THUMBS;
229242 tns_init(&tns, filecnt);
230− while (!tns_load(&tns, 0, filenames[0], 0))
243+ while (!tns_load(&tns, 0, &files[0], 0))
231244 remove_file(0, 0);
232245 tns.cnt = 1;
233246 } else {
M thumbs.c View
@@ -44,45 +44,34 @@ int tns_cache_enabled() {
4444 !access(cache_dir, W_OK);
4545 }
4646
47−char* tns_cache_filename(const char *filename) {
47+char* tns_cache_filepath(const char *filepath) {
4848 size_t len;
4949 char *cfile = NULL;
50− const char *abspath;
5150
52− if (!cache_dir || !filename)
51+ if (!cache_dir || !filepath || *filepath != '/')
5352 return NULL;
5453
55− if (*filename != '/') {
56− if (!(abspath = absolute_path(filename)))
57− return NULL;
58− } else {
59− abspath = filename;
60− }
61−
62− if (strncmp(abspath, cache_dir, strlen(cache_dir))) {
63− len = strlen(cache_dir) + strlen(abspath) + 6;
54+ if (strncmp(filepath, cache_dir, strlen(cache_dir))) {
55+ len = strlen(cache_dir) + strlen(filepath) + 6;
6456 cfile = (char*) s_malloc(len);
65− snprintf(cfile, len, "%s/%s.png", cache_dir, abspath + 1);
57+ snprintf(cfile, len, "%s/%s.png", cache_dir, filepath + 1);
6658 }
6759
68− if (abspath != filename)
69− free((void*) abspath);
70−
7160 return cfile;
7261 }
7362
74−Imlib_Image* tns_cache_load(const char *filename) {
63+Imlib_Image* tns_cache_load(const char *filepath) {
7564 char *cfile;
7665 struct stat cstats, fstats;
7766 Imlib_Image *im = NULL;
7867
79− if (!filename)
68+ if (!filepath)
8069 return NULL;
8170
82− if (stat(filename, &fstats))
71+ if (stat(filepath, &fstats))
8372 return NULL;
8473
85− if ((cfile = tns_cache_filename(filename))) {
74+ if ((cfile = tns_cache_filepath(filepath))) {
8675 if (!stat(cfile, &cstats) &&
8776 cstats.st_mtim.tv_sec == fstats.st_mtim.tv_sec &&
8877 cstats.st_mtim.tv_nsec / 1000 == fstats.st_mtim.tv_nsec / 1000)
@@ -101,13 +90,13 @@ void tns_cache_write(thumb_t *t, Bool force) {
10190 struct timeval times[2];
10291 Imlib_Load_Error err = 0;
10392
104− if (!t || !t->im || !t->filename)
93+ if (!t || !t->im || !t->file || !t->file->name || !t->file->path)
10594 return;
10695
107− if (stat(t->filename, &fstats))
96+ if (stat(t->file->path, &fstats))
10897 return;
10998
110− if ((cfile = tns_cache_filename(t->filename))) {
99+ if ((cfile = tns_cache_filepath(t->file->path))) {
111100 if (force || stat(cfile, &cstats) ||
112101 cstats.st_mtim.tv_sec != fstats.st_mtim.tv_sec ||
113102 cstats.st_mtim.tv_nsec / 1000 != fstats.st_mtim.tv_nsec / 1000)
@@ -125,7 +114,7 @@ void tns_cache_write(thumb_t *t, Bool force) {
125114 }
126115
127116 if (err) {
128− warn("could not cache thumbnail: %s", t->filename);
117+ warn("could not cache thumbnail: %s", t->file->name);
129118 } else {
130119 TIMESPEC_TO_TIMEVAL(&times[0], &fstats.st_atim);
131120 TIMESPEC_TO_TIMEVAL(&times[1], &fstats.st_mtim);
@@ -223,21 +212,21 @@ void tns_free(tns_t *tns) {
223212 }
224213 }
225214
226−int tns_load(tns_t *tns, int n, const char *filename, unsigned char silent) {
215+int tns_load(tns_t *tns, int n, const fileinfo_t *file, unsigned char silent) {
227216 int w, h;
228217 int use_cache, cached = 0;
229218 float z, zw, zh;
230219 thumb_t *t;
231220 Imlib_Image *im;
232221
233− if (!tns || !tns->thumbs || !filename)
222+ if (!tns || !tns->thumbs || !file || !file->name || !file->path)
234223 return 0;
235224
236225 if (n < 0 || n >= tns->cap)
237226 return 0;
238227
239228 t = &tns->thumbs[n];
240− t->filename = filename;
229+ t->file = file;
241230
242231 if (t->im) {
243232 imlib_context_set_image(t->im);
@@ -245,15 +234,15 @@ int tns_load(tns_t *tns, int n, const char *filename, unsigned char silent) {
245234 }
246235
247236 if ((use_cache = tns_cache_enabled())) {
248− if ((im = tns_cache_load(filename)))
237+ if ((im = tns_cache_load(file->path)))
249238 cached = 1;
250239 }
251240
252241 if (!cached &&
253− (access(filename, R_OK) || !(im = imlib_load_image(filename))))
242+ (access(file->path, R_OK) || !(im = imlib_load_image(file->path))))
254243 {
255244 if (!silent)
256− warn("could not open image: %s", filename);
245+ warn("could not open image: %s", file->name);
257246 return 0;
258247 }
259248
M thumbs.h View
@@ -26,7 +26,7 @@
2626
2727 typedef struct {
2828 Imlib_Image *im;
29− const char *filename;
29+ const fileinfo_t *file;
3030 int x;
3131 int y;
3232 int w;
@@ -51,7 +51,7 @@ void tns_clean_cache(tns_t*);
5151 void tns_init(tns_t*, int);
5252 void tns_free(tns_t*);
5353
54−int tns_load(tns_t*, int, const char*, unsigned char);
54+int tns_load(tns_t*, int, const fileinfo_t*, unsigned char);
5555
5656 void tns_render(tns_t*, win_t*);
5757 void tns_highlight(tns_t*, win_t*, int, Bool);
M types.h View
@@ -26,4 +26,9 @@ typedef enum {
2626 CURSOR_WATCH
2727 } cursor_t;
2828
29+typedef struct {
30+ const char *name;
31+ const char *path;
32+} fileinfo_t;
33+
2934 #endif /* TYPES_H */
M util.c View
@@ -47,6 +47,17 @@ void* s_realloc(void *ptr, size_t size) {
4747 return ptr;
4848 }
4949
50+char* s_strdup(char *s) {
51+ char *d = NULL;
52+
53+ if (s) {
54+ if (!(d = malloc(strlen(s) + 1)))
55+ die("could not allocate memory");
56+ strcpy(d, s);
57+ }
58+ return d;
59+}
60+
5061 void warn(const char* fmt, ...) {
5162 va_list args;
5263
M util.h View
@@ -55,6 +55,7 @@ typedef struct {
5555
5656 void* s_malloc(size_t);
5757 void* s_realloc(void*, size_t);
58+char* s_strdup(char*);
5859
5960 void warn(const char*, ...);
6061 void die(const char*, ...);