Image Demosaicking with Contour Stencils
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
temsub.c
Go to the documentation of this file.
1 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <time.h>
19 #include "temsub.h"
20 
22 #define LINE_BUFFER_SIZE 256
23 
24 
25 static void WriteSub(FILE *Output, char *Sub, int Column);
26 
44 int FillTemplate(const char *OutputFilename, const char *TemplateFilename,
45  char *Keys[], char *Subs[])
46 {
47  FILE *Template = NULL, *Output = NULL;
48  char *Token, *NextPos;
49  time_t CurrentTime;
50  struct tm *CurrentTimeInfo;
51  char TimeString[64], Line[LINE_BUFFER_SIZE];
52  int LineNumber = 0, Success = 0, k, Column;
53 
54  if(!(Template = fopen(TemplateFilename, "rt")))
55  {
56  fprintf(stderr, "Unable to open template \"%s\".\n",
57  TemplateFilename);
58  goto Catch;
59  }
60  else if(!(Output = fopen(OutputFilename, "wt")))
61  {
62  fprintf(stderr, "Unable to open \"%s\" for writing.\n",
63  OutputFilename);
64  goto Catch;
65  }
66 
67  /* Get the current time */
68  time(&CurrentTime);
69  CurrentTimeInfo = localtime (&CurrentTime);
70  strftime(TimeString, 64, "%Y-%m-%d %H:%M:%S", CurrentTimeInfo);
71 
72  /* Parse the template file line-by-line */
73  while(fgets(Line, LINE_BUFFER_SIZE, Template))
74  {
75  LineNumber++;
76  Token = Line;
77 
78  while((NextPos = strstr(Token, "${"))) /* Found "${" */
79  {
80  /* Write the text from Token to NextPos */
81  *NextPos = '\0';
82  fputs(Token, Output);
83 
84  Column = NextPos - Line;
85  Token = NextPos + 2;
86 
87  if(!(NextPos = strchr(Token, '}'))) /* Get matching '}' */
88  {
89  fprintf(stderr, "Line %d: Missing '}'.\n", LineNumber);
90  goto Catch;
91  }
92 
93  *NextPos = '\0';
94 
95  if(!strcmp(Token, "TIME"))
96  fputs(TimeString, Output);
97  else if(!strcmp(Token, "TEMPLATE_FILENAME"))
98  fputs(TemplateFilename, Output);
99  else if(!strcmp(Token, "OUTPUT_FILENAME"))
100  fputs(OutputFilename, Output);
101  else
102  /* Search for a key equal to Token */
103  for(k = 0;; k++)
104  if(!Keys[k] || !Subs[k])
105  {
106  fprintf(stderr, "Line %d: Unknown key \"%s\".\n",
107  LineNumber, Token);
108  goto Catch;
109  }
110  else if(!strcmp(Token, Keys[k]))
111  {
112  /* Write Subs[k] to the output file */
113  WriteSub(Output, Subs[k], Column);
114  break;
115  }
116 
117  Token = NextPos + 1;
118  }
119 
120  /* Write the remainder of the line */
121  fputs(Token, Output);
122  }
123 
124  if(ferror(Template))
125  {
126  fprintf(stderr, "Error reading \"%s\".\n", TemplateFilename);
127  goto Catch;
128  }
129  else if(ferror(Output))
130  {
131  fprintf(stderr, "Error writing \"%s\".\n", OutputFilename);
132  goto Catch;
133  }
134 
135  Success = 1;
136 Catch:
137  if(Output)
138  fclose(Output);
139  if(Template)
140  fclose(Template);
141  return Success;
142 }
143 
144 
154 static void WriteSub(FILE *Output, char *Sub, int Column)
155 {
156  char *Token = Sub;
157  char *NextPos;
158  int k;
159 
160  for(Token = Sub; (NextPos = strchr(Token, '\n')); Token = NextPos + 1)
161  {
162  /* Write the text from Token up to and including the next newline */
163  fwrite(Token, sizeof(char), NextPos - Token + 1, Output);
164 
165  /* Write Column number of spaces to indent the next line */
166  for(k = 0; k < Column; k++)
167  putc(' ', Output);
168  }
169 
170  /* Write the remaining text */
171  fputs(Token, Output);
172 }
173 
174 
186 char **AddPair(char **Keys[], char **Subs[], char *Key, char *SubFormat, ...)
187 {
188  va_list Args;
189  int i = 0;
190 
191  /* Search for Key in Keys */
192  if(*Keys && *Subs)
193  for(; (*Keys)[i]; i++)
194  if(!strcmp((*Keys)[i], Key))
195  goto Done;
196 
197  /* After the loop, i = current number of keys. Now we allocate
198  space for i+2 elements (= current keys + the new key + sentinel). */
199  if(!(*Keys = (char **)realloc(*Keys, sizeof(char *)*(i + 2)))
200  || !(*Subs = (char **)realloc(*Subs, sizeof(char *)*(i + 2)))
201  /* Allocate space to copy Key */
202  || !((*Keys)[i] = (char *)malloc(strlen(Key) + 1)))
203  {
204  fprintf(stderr, "Out of memory.");
205  exit(1);
206  }
207 
208  strcpy((*Keys)[i], Key); /* Copy Key */
209  (*Subs)[i] = NULL;
210  (*Keys)[i + 1] = NULL; /* Set null sentinel */
211  (*Subs)[i + 1] = NULL;
212 
213 Done:
214  va_start(Args, SubFormat);
215  VStringAppend(&(*Subs)[i], SubFormat, Args);
216  va_end(Args);
217  return &(*Subs)[i];
218 }
219 
220 
226 void StringAppend(char **Str, const char *Format, ...)
227 {
228  va_list Args;
229 
230  va_start(Args, Format);
231  VStringAppend(Str, Format, Args);
232  va_end(Args);
233 }
234 
235 
237 void VStringAppend(char **Str, const char *Format, va_list Args)
238 {
239  char *NewStr;
240  char Buffer[LINE_BUFFER_SIZE];
241 
242  vsprintf(Buffer, Format, Args);
243 
244  /* Reallocate string with enough space to hold the result */
245  if(!(NewStr = (char *)realloc(*Str,
246  ((*Str) ? strlen(*Str) : 0) + strlen(Buffer) + 1)))
247  {
248  fprintf(stderr, "Out of memory.");
249  exit(1);
250  }
251 
252  if(*Str)
253  strcat(NewStr, Buffer);
254  else
255  strcpy(NewStr, Buffer);
256 
257  *Str = NewStr;
258 }
259 
260 
265 void FreeStringArray(char *Strs[])
266 {
267  if(Strs)
268  {
269  int i;
270 
271  for(i = 0; Strs[i]; i++)
272  if(Strs[i])
273  free(Strs[i]);
274 
275  free(Strs);
276  }
277 }
278