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