@@ -139,60 +139,111 @@ int vcardtime_is_valid_time(const struct vcardtimetype t)
139
139
140
140
static int sprintf_date (const vcardtimetype t , char * buf , size_t size )
141
141
{
142
- /* 3 zero-padded numeric arguments by position + NUL */
143
- char fmt [19 ] = "" ;
142
+ /*
143
+ date = year [month day]
144
+ / year "-" month
145
+ / "--" month [day]
146
+ / "--" "-" day
147
+ */
148
+ const char * fmt ;
144
149
145
150
if (t .year != -1 ) {
146
- strcat (fmt , "%04d" );
151
+ if (t .month == -1 ) {
152
+ fmt = "%04d" ;
153
+ }
154
+ else if (t .day == -1 ) {
155
+ fmt = "%04d-%02d" ;
156
+ }
157
+ else {
158
+ fmt = "%04d%02d%02d" ;
159
+ }
147
160
148
- if (t .month != -1 ) {
149
- strcat (fmt , (t .day != -1 ) ? "%02d%02d" : "-%02d" );
161
+ return snprintf (buf , size , fmt , t .year , t .month , t .day );
162
+ }
163
+ else if (t .month != -1 ) {
164
+ if (t .day == -1 ) {
165
+ fmt = "--%02d" ;
150
166
}
167
+ else {
168
+ fmt = "--%02d%02d" ;
169
+ }
170
+
171
+ return snprintf (buf , size , fmt , t .month , t .day );
151
172
}
152
173
else {
153
- strcat (fmt , "--" );
154
-
155
- strcat (fmt , (t .month != -1 ) ? "%2$02d" : "-" );
156
-
157
- if (t .day != -1 ) {
158
- strcat (fmt , "%3$02d" );
159
- }
174
+ return snprintf (buf , size , "---%02d" , t .day );
160
175
}
161
-
162
- return snprintf (buf , size , fmt , t .year , t .month , t .day );
163
176
}
164
177
165
178
static int sprintf_time (const vcardtimetype t , int need_designator ,
166
179
char * buf , size_t size )
167
180
{
168
- /* "T" + sign + 5 zero-padded numeric arguments by position + NUL */
169
- char fmt [33 ] = "" ;
181
+ /*
182
+ time = ["T"] hour [minute [second]] [zone]
183
+ / ["T"] "-" minute [second]
184
+ / ["T"] "-" "-" second
185
+ */
186
+ const char * fmt ;
170
187
171
188
if (need_designator ) {
172
- strcat (fmt , "T" );
189
+ strncat (buf , "T" , size );
190
+ buf ++ ;
191
+ size -- ;
173
192
}
174
193
175
194
if (t .hour != -1 ) {
176
- strcat (fmt , "%02d" );
195
+ /* hour [minute [second]] [zone] */
196
+ int n ;
177
197
178
- if (t .minute != -1 ) {
179
- strcat (fmt , (t .second != -1 ) ? "%02d%02d" : "%02d" );
198
+ if (t .minute == -1 ) {
199
+ /* hour */
200
+ fmt = "%02d" ;
201
+ }
202
+ else if (t .second == -1 ) {
203
+ /* hour minute */
204
+ fmt = "%02d%02d" ;
205
+ }
206
+ else {
207
+ /* hour minute second */
208
+ fmt = "%02d%02d%02d" ;
180
209
}
181
210
211
+ n = snprintf (buf , size , fmt , t .hour , t .minute , t .second );
212
+
182
213
if (t .utcoffset != -1 ) {
183
- strcat (fmt , (t .utcoffset == 0 ) ? "Z" : "%4$+03d%5$02d" );
184
- }
185
- }
186
- else {
187
- strcat (fmt , (t .minute != -1 ) ? "-%2$02d" : "--" );
214
+ /* zone = "Z" / ( sign hour minute ) */
215
+ buf += n ;
216
+ size -= n ;
188
217
189
- if (t .second != -1 ) {
190
- strcat (fmt , "%3$02d" );
218
+ if (t .utcoffset == 0 ) {
219
+ strncpy (buf , "Z" , size );
220
+ n ++ ;
221
+ }
222
+ else {
223
+ n += snprintf (buf , size , "%+03d%02d" ,
224
+ t .utcoffset / 60 , abs (t .utcoffset % 60 ));
225
+ }
191
226
}
227
+
228
+ return n ;
192
229
}
230
+ else if (t .minute != -1 ) {
231
+ /* "-" minute [second] */
232
+ if (t .second == -1 ) {
233
+ /* "-" minute */
234
+ fmt = "-%02d" ;
235
+ }
236
+ else {
237
+ /* "-" minute second */
238
+ fmt = "-%02d%02d" ;
239
+ }
193
240
194
- return snprintf (buf , size , fmt , t .hour , t .minute , t .second ,
195
- t .utcoffset / 60 , abs (t .utcoffset % 60 ));
241
+ return snprintf (buf , size , fmt , t .minute , t .second );
242
+ }
243
+ else {
244
+ /* "-" "-" second */
245
+ return snprintf (buf , size , "--%02d" , t .second );
246
+ }
196
247
}
197
248
198
249
char * vcardtime_as_vcard_string_r (const vcardtimetype t ,
@@ -232,10 +283,15 @@ const char *vcardtime_as_vcard_string(const vcardtimetype t,
232
283
233
284
static const char * sscanf_date (const char * str , vcardtimetype * t )
234
285
{
235
- char fmt [TIME_BUF_SIZE ] = "" ; /* 4 numeric arguments by position + NUL */
286
+ /*
287
+ date = year [month day]
288
+ / year "-" month
289
+ / "--" month [day]
290
+ / "--" "-" day
291
+ */
236
292
const char * month ;
237
293
size_t ndig ;
238
- int nchar ;
294
+ int nchar = 0 ;
239
295
char * newstr ;
240
296
241
297
if (!str || !* str ) {
@@ -246,181 +302,171 @@ static const char *sscanf_date(const char *str, vcardtimetype *t)
246
302
month = str + 2 ;
247
303
248
304
if (* month == '-' ) {
249
- /* "--" "-" day */
250
305
ndig = num_digits (month + 1 );
251
306
252
307
if (ndig == 2 ) {
253
- strcpy ( fmt , "---%3$2u" );
308
+ sscanf ( str , "---%2u%n" , & t -> day , & nchar );
254
309
}
255
310
}
256
311
else {
257
- /* "--" month [day] */
258
312
ndig = num_digits (month );
259
313
260
314
if (ndig == 4 ) {
261
- /* month day */
262
- strcpy (fmt , "--%2$2u%3$2u" );
315
+ sscanf (str , "--%2u%2u%n" , & t -> month , & t -> day , & nchar );
263
316
}
264
317
else if (ndig == 2 ) {
265
- /* month */
266
- strcpy (fmt , "--%2$2u" );
318
+ sscanf (str , "--%2u%n" , & t -> month , & nchar );
267
319
}
268
320
}
269
321
}
270
322
else {
271
- /* year [ ("-" month) / (month day)] */
272
323
ndig = num_digits (str );
273
324
274
325
if (ndig == 8 ) {
275
- /* year month day */
276
- strcpy (fmt , "%1$4u%2$2u%3$2u" );
326
+ sscanf (str , "%4u%2u%2u%n" , & t -> year , & t -> month , & t -> day , & nchar );
277
327
}
278
328
else if (ndig == 4 ) {
279
329
month = str + 4 ;
280
330
281
331
if (!* month ) {
282
- /* year */
283
- strcpy (fmt , "%1$4u" );
332
+ sscanf (str , "%4u%n" , & t -> year , & nchar );
284
333
}
285
334
else if (* month == '-' ) {
286
- /* year "-" month [ "-" day ] */
287
335
ndig = num_digits (++ month );
288
336
289
337
if (ndig == 2 ) {
290
- strcpy (fmt , "%1$4u-%2$2u" );
291
-
292
338
if (month [2 ] == '-' ) {
293
- strcat (fmt , "-%3$2u" );
339
+ sscanf (str , "%4u-%2u-%2u%n" ,
340
+ & t -> year , & t -> month , & t -> day , & nchar );
341
+ }
342
+ else {
343
+ sscanf (str , "%4u-%2u%n" ,
344
+ & t -> year , & t -> month , & nchar );
294
345
}
295
346
}
296
347
}
297
348
}
298
349
}
299
350
300
- if (!* fmt ) {
351
+ if (!nchar ) {
301
352
/* invalid time */
302
353
return NULL ;
303
354
}
304
355
305
- strcat (fmt , "%4$n" );
306
- sscanf (str , fmt , & t -> year , & t -> month , & t -> day , & nchar );
307
-
308
356
newstr = (char * )str + nchar ;
309
357
return newstr ;
310
358
}
311
359
312
360
static const char * sscanf_zone (const char * str , vcardtimetype * t )
313
361
{
314
- char fmt [16 ] = "" ; /* 3 numeric arguments by position + NUL */
315
- int offset_h = 0 , offset_m = 0 , nchar ;
362
+ /*
363
+ zone = "Z"
364
+ / ( "+" / "-" ) hour [minute]
365
+ */
366
+ unsigned offset_h = 0 , offset_m = 0 ;
367
+ char sign [2 ] = "" ;
316
368
size_t ndig ;
317
369
char * newstr ;
370
+ int nchar = 0 ;
318
371
319
372
if (!str || !* str ) {
320
373
/* empty string */
321
374
return NULL ;
322
375
}
323
376
else if (* str == 'Z' ) {
324
- /* zone = utc-designator */
325
- strcpy (fmt , "Z" );
377
+ nchar = 1 ;
326
378
}
327
379
else if (strchr ("+-" , * str )) {
328
- /* zone = utc-offset = sign hour [minute] */
329
380
ndig = num_digits (str + 1 );
330
381
331
382
if (ndig == 4 ) {
332
- /* sign hour minute */
333
- strcpy (fmt , "%1$3d%2$2u" );
383
+ sscanf (str , "%1[+-]%2u%2u%n" , sign , & offset_h , & offset_m , & nchar );
334
384
}
335
385
else if (ndig == 2 ) {
336
- /* sign hour */
337
- strcpy (fmt , "%1$3d" );
386
+ sscanf (str , "%1[+-]%2u%n" , sign , & offset_h , & nchar );
338
387
}
339
388
}
340
389
341
- if (!* fmt ) {
390
+ if (!nchar ) {
342
391
/* invalid zone */
343
392
return NULL ;
344
393
}
345
394
346
- strcat (fmt , "%3$n" );
347
- sscanf (str , fmt , & offset_h , & offset_m , & nchar );
348
-
349
- t -> utcoffset = 60 * offset_h + ((offset_h < 0 ) ? - offset_m : offset_m );
395
+ t -> utcoffset = 60 * offset_h + offset_m ;
396
+ if (* sign == '-' ) t -> utcoffset = - t -> utcoffset ;
350
397
351
398
newstr = (char * )str + nchar ;
352
399
return newstr ;
353
400
}
354
401
355
402
static const char * sscanf_time (const char * str , vcardtimetype * t )
356
403
{
357
- char fmt [27 ] = "" ; /* "%1$2u:%2$2u:%3$2u.%4$u%5$n" + NUL */
404
+ /*
405
+ time = hour [ ":" minute ":" second [ "." secfrac ] ]
406
+ / hour [ minute [second]] [zone]
407
+ / "-" minute [second]
408
+ / "-" "-" second
409
+ */
358
410
unsigned secfrac ;
359
411
size_t ndig ;
360
- int nchar ;
412
+ int nchar = 0 ;
361
413
362
414
if (!str || !* str ) {
363
415
/* empty string */
364
416
return NULL ;
365
417
}
366
418
else if (* str == '-' ) {
367
419
if (str [1 ] == '-' ) {
368
- /* "-" "-" second */
369
420
ndig = num_digits (str + 2 );
370
421
371
422
if (ndig == 2 ) {
372
- strcpy ( fmt , "--%3$2u" );
423
+ sscanf ( str , "--%2u%n" , & t -> second , & nchar );
373
424
}
374
425
}
375
426
else {
376
- /* "-" minute [second] */
377
427
ndig = num_digits (str + 1 );
378
428
379
429
if (ndig == 4 ) {
380
- /* minute second */
381
- strcpy (fmt , "-%2$2u%3$2u" );
430
+ sscanf (str , "-%2u%2u%n" , & t -> minute , & t -> second , & nchar );
382
431
}
383
432
else if (ndig == 2 ) {
384
- /* minute */
385
- strcpy (fmt , "-%2$2u" );
433
+ sscanf (str , "-%2u%n" , & t -> minute , & nchar );
386
434
t -> second = 0 ;
387
435
}
388
436
}
389
437
}
390
438
else {
391
- /* hour [minute [second]] [zone] */
392
439
ndig = num_digits (str );
393
440
394
441
if (ndig == 6 ) {
395
- /* hour minute second */
396
- strcpy (fmt , "%1$2u%2$2u%3$2u" );
442
+ sscanf (str , "%2u%2u%2u%n" , & t -> hour , & t -> minute , & t -> second , & nchar );
397
443
}
398
444
else if (ndig == 4 ) {
399
- /* hour minute */
400
- strcpy (fmt , "%1$2u%2$2u" );
445
+ sscanf (str , "%2u%2u%n" , & t -> hour , & t -> minute , & nchar );
401
446
t -> second = 0 ;
402
447
}
403
448
else if (ndig == 2 ) {
404
- /* hour [ ":" minute ":" second [ "." secfrac ] ] */
405
- strcpy (fmt , "%1$2u" );
406
-
407
449
if (str [2 ] == ':' ) {
408
- strcat (fmt , ":%2$2u:%3$2u" );
409
-
410
450
if (str [8 ] == '.' ) {
411
- strcat (fmt , ".%4$u" );
451
+ sscanf (str , "%2u:%2u:%2u.%u%n" ,
452
+ & t -> hour , & t -> minute , & t -> second , & secfrac , & nchar );
412
453
}
454
+ else {
455
+ sscanf (str , "%2u:%2u:%2u%n" ,
456
+ & t -> hour , & t -> minute , & t -> second , & nchar );
457
+ }
458
+ }
459
+ else {
460
+ sscanf (str , "%2u%n" , & t -> hour , & nchar );
413
461
}
414
462
}
415
463
}
416
464
417
- if (!* fmt ) {
465
+ if (!nchar ) {
418
466
/* invalid time */
419
467
return NULL ;
420
468
}
421
469
422
- strcat (fmt , "%5$n" );
423
- sscanf (str , fmt , & t -> hour , & t -> minute , & t -> second , & secfrac , & nchar );
424
470
str += nchar ;
425
471
426
472
if (t -> hour != -1 && * str ) {
0 commit comments