1 /*
2 * zphoto - a zooming photo album generator.
3 *
4 * Copyright (C) 2002-2004 Satoru Takabayashi <satoru@namazu.org>
5 * All rights reserved.
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 */
22
23 #include <assert.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <unistd.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <zphoto.h>
31 #include "config.h"
32
33 struct _ZphotoTemplate {
34 char *file_name;
35 char *content;
36 ZphotoAlist *alist;
37 };
38
39 static size_t
get_file_size(const char * file_name)40 get_file_size (const char *file_name)
41 {
42 struct stat s;
43 if (stat(file_name, &s) == -1)
44 zphoto_eprintf("%s:", file_name);
45 return s.st_size;
46 }
47
48 static char *
read_file(const char * file_name)49 read_file (const char *file_name)
50 {
51 FILE *fp;
52 char *content;
53 size_t file_size;
54
55 file_size = get_file_size(file_name);
56
57 fp = zphoto_efopen(file_name, "rb");
58 content = zphoto_emalloc(file_size + 1);
59
60 fread(content, sizeof(char), file_size, fp);
61 if (ferror(fp))
62 zphoto_eprintf("%s:", file_name);
63
64 content[file_size] = '\0';
65 fclose(fp);
66 return content;
67 }
68
69 static char *
substitute_region(ZphotoTemplate * template,const char * start,const char * end,FILE * fp)70 substitute_region (ZphotoTemplate *template,
71 const char *start,
72 const char *end,
73 FILE *fp)
74 {
75 int len;
76 char *key, *value;
77
78 len = end - start;
79 key = zphoto_emalloc(len + 1);
80 strncpy(key, start, len);
81 key[len] = '\0';
82
83 value = zphoto_alist_get(template->alist, key);
84 free(key);
85 return value;
86 }
87
88 static void
substituting_print(ZphotoTemplate * template,FILE * fp)89 substituting_print (ZphotoTemplate *template, FILE *fp)
90 {
91 const char *p = template->content;
92
93 while (*p != '\0') {
94 if (strncmp(p, "#{", 2) == 0) {
95 char *q, *value;
96 p += 2;
97 q = strchr(p, '}');
98 if (q == NULL)
99 zphoto_eprintf("%s: unclosed brace at %d",
100 template->file_name, p - template->content);
101
102 value = substitute_region(template, p, q, fp);
103 if (value)
104 fprintf(fp, "%s", value);
105 p = q + 1;
106 } else {
107 fputc(*p, fp);
108 p++;
109 }
110 }
111 }
112
113 void
zphoto_template_write(ZphotoTemplate * template,const char * output_file_name)114 zphoto_template_write (ZphotoTemplate *template, const char *output_file_name)
115 {
116 FILE *fp = zphoto_efopen(output_file_name, "wb");
117 substituting_print(template, fp);
118 fclose(fp);
119 }
120
121 void
zphoto_template_add_subst(ZphotoTemplate * template,const char * key,const char * value)122 zphoto_template_add_subst (ZphotoTemplate *template,
123 const char *key,
124 const char *value)
125 {
126 template->alist = zphoto_alist_add(template->alist, key, value);
127 }
128
129 ZphotoTemplate *
zphoto_template_new(const char * file_name)130 zphoto_template_new (const char *file_name)
131 {
132 ZphotoTemplate *template;
133
134 template = zphoto_emalloc(sizeof(ZphotoTemplate));
135 template->file_name = zphoto_strdup(file_name);
136 template->alist = NULL;
137 template->content = read_file(template->file_name);
138 return template;
139 }
140
141 void
zphoto_template_destroy(ZphotoTemplate * template)142 zphoto_template_destroy (ZphotoTemplate *template)
143 {
144 zphoto_alist_destroy(template->alist);
145 free(template->file_name);
146 free(template->content);
147 free(template);
148 }
149
150