summaryrefslogtreecommitdiffabout
path: root/libical/src/libical/icalduration.c
Side-by-side diff
Diffstat (limited to 'libical/src/libical/icalduration.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libical/src/libical/icalduration.c89
1 files changed, 49 insertions, 40 deletions
diff --git a/libical/src/libical/icalduration.c b/libical/src/libical/icalduration.c
index 4468e0f..821a3b7 100644
--- a/libical/src/libical/icalduration.c
+++ b/libical/src/libical/icalduration.c
@@ -1,323 +1,332 @@
/* -*- Mode: C -*-
======================================================================
FILE: icaltime.c
CREATOR: eric 02 June 2000
$Id$
$Locker$
(C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org
This program is free software; you can redistribute it and/or modify
it under the terms of either:
The LGPL as published by the Free Software Foundation, version
2.1, available at: http://www.fsf.org/copyleft/lesser.html
Or:
The Mozilla Public License Version 1.0. You may obtain a copy of
the License at http://www.mozilla.org/MPL/
The Original Code is eric. The Initial Developer of the Original
Code is Eric Busboom
======================================================================*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "icalduration.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
-#ifdef ICAL_NO_LIBICAL
-#define icalerror_set_errno(x)
-#define icalerror_check_arg_rv(x,y)
-#define icalerror_check_arg_re(x,y,z)
-#else
#include "icalerror.h"
#include "icalmemory.h"
-#endif
+#include "icalvalue.h"
/* From Seth Alves, <alves@hungry.com> */
struct icaldurationtype icaldurationtype_from_int(int t)
{
- struct icaldurationtype dur;
- int used = 0;
-
- dur = icaldurationtype_null_duration();
-
- if(t < 0){
- dur.is_neg = 1;
- t = -t;
- }
-
- if (t % (60 * 60 * 24 * 7) == 0) {
- dur.weeks = t / (60 * 60 * 24 * 7);
- } else {
- used += dur.weeks * (60 * 60 * 24 * 7);
- dur.days = (t - used) / (60 * 60 * 24);
- used += dur.days * (60 * 60 * 24);
- dur.hours = (t - used) / (60 * 60);
- used += dur.hours * (60 * 60);
- dur.minutes = (t - used) / (60);
- used += dur.minutes * (60);
- dur.seconds = (t - used);
- }
+ struct icaldurationtype dur;
+ int used = 0;
+
+ dur = icaldurationtype_null_duration();
+
+ if(t < 0){
+ dur.is_neg = 1;
+ t = -t;
+ }
+
+ if (t % (60 * 60 * 24 * 7) == 0) {
+ dur.weeks = t / (60 * 60 * 24 * 7);
+ } else {
+ used += dur.weeks * (60 * 60 * 24 * 7);
+ dur.days = (t - used) / (60 * 60 * 24);
+ used += dur.days * (60 * 60 * 24);
+ dur.hours = (t - used) / (60 * 60);
+ used += dur.hours * (60 * 60);
+ dur.minutes = (t - used) / (60);
+ used += dur.minutes * (60);
+ dur.seconds = (t - used);
+ }
- return dur;
+ return dur;
}
-#ifndef ICAL_NO_LIBICAL
-#include "icalvalue.h"
struct icaldurationtype icaldurationtype_from_string(const char* str)
{
int i;
int begin_flag = 0;
int time_flag = 0;
int date_flag = 0;
int week_flag = 0;
int digits=-1;
int scan_size = -1;
int size = strlen(str);
char p;
struct icaldurationtype d;
memset(&d, 0, sizeof(struct icaldurationtype));
for(i=0;i != size;i++){
p = str[i];
switch(p)
{
case '-': {
if(i != 0 || begin_flag == 1) goto error;
d.is_neg = 1;
break;
}
case 'P': {
if (i != 0 && i !=1 ) goto error;
begin_flag = 1;
break;
}
case 'T': {
time_flag = 1;
break;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
{
/* HACK. Skip any more digits if the l;ast one
read has not been assigned */
if(digits != -1){
break;
}
if (begin_flag == 0) goto error;
/* Get all of the digits, not one at a time */
- scan_size = sscanf((char*)(str+i),"%d",&digits);
+ scan_size = sscanf(&str[i],"%d",&digits);
if(scan_size == 0) goto error;
break;
}
case 'H': {
if (time_flag == 0||week_flag == 1||d.hours !=0||digits ==-1)
goto error;
d.hours = digits; digits = -1;
break;
}
case 'M': {
if (time_flag == 0||week_flag==1||d.minutes != 0||digits ==-1)
goto error;
d.minutes = digits; digits = -1;
break;
}
case 'S': {
if (time_flag == 0||week_flag==1||d.seconds!=0||digits ==-1)
goto error;
d.seconds = digits; digits = -1;
break;
}
case 'W': {
if (time_flag==1||date_flag==1||d.weeks!=0||digits ==-1)
goto error;
week_flag = 1;
d.weeks = digits; digits = -1;
break;
}
case 'D': {
if (time_flag==1||week_flag==1||d.days!=0||digits ==-1)
goto error;
date_flag = 1;
d.days = digits; digits = -1;
break;
}
default: {
goto error;
}
}
}
return d;
error:
icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
- memset(&d, 0, sizeof(struct icaldurationtype));
- return d;
-
+ return icaldurationtype_bad_duration();
}
#define TMP_BUF_SIZE 1024
+static
void append_duration_segment(char** buf, char** buf_ptr, size_t* buf_size,
char* sep, unsigned int value) {
char temp[TMP_BUF_SIZE];
sprintf(temp,"%d",value);
icalmemory_append_string(buf, buf_ptr, buf_size, temp);
icalmemory_append_string(buf, buf_ptr, buf_size, sep);
}
char* icaldurationtype_as_ical_string(struct icaldurationtype d)
{
char *buf, *output_line;
size_t buf_size = 256;
char* buf_ptr = 0;
int seconds;
buf = (char*)icalmemory_new_buffer(buf_size);
buf_ptr = buf;
seconds = icaldurationtype_as_int(d);
if(seconds !=0){
if(d.is_neg == 1){
icalmemory_append_char(&buf, &buf_ptr, &buf_size, '-');
}
icalmemory_append_char(&buf, &buf_ptr, &buf_size, 'P');
if (d.weeks != 0 ) {
append_duration_segment(&buf, &buf_ptr, &buf_size, "W", d.weeks);
}
if (d.days != 0 ) {
append_duration_segment(&buf, &buf_ptr, &buf_size, "D", d.days);
}
if (d.hours != 0 || d.minutes != 0 || d.seconds != 0) {
icalmemory_append_string(&buf, &buf_ptr, &buf_size, "T");
if (d.hours != 0 ) {
append_duration_segment(&buf, &buf_ptr, &buf_size, "H", d.hours);
}
if (d.minutes != 0 ) {
append_duration_segment(&buf, &buf_ptr, &buf_size, "M",
d.minutes);
}
if (d.seconds != 0 ) {
append_duration_segment(&buf, &buf_ptr, &buf_size, "S",
d.seconds);
}
}
} else {
- icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PTS0");
+ icalmemory_append_string(&buf, &buf_ptr, &buf_size, "PT0S");
}
output_line = icalmemory_tmp_copy(buf);
icalmemory_free_buffer(buf);
return output_line;
}
-#endif
-
/* From Russel Steinthal */
int icaldurationtype_as_int(struct icaldurationtype dur)
{
return (int)( (dur.seconds +
(60 * dur.minutes) +
(60 * 60 * dur.hours) +
(60 * 60 * 24 * dur.days) +
(60 * 60 * 24 * 7 * dur.weeks))
* (dur.is_neg==1? -1 : 1) ) ;
}
-struct icaldurationtype icaldurationtype_null_duration()
+struct icaldurationtype icaldurationtype_null_duration(void)
{
struct icaldurationtype d;
memset(&d,0,sizeof(struct icaldurationtype));
return d;
}
int icaldurationtype_is_null_duration(struct icaldurationtype d)
{
if(icaldurationtype_as_int(d) == 0){
return 1;
} else {
return 0;
}
}
+/* in icalvalue_new_from_string_with_error, we should not call
+ icaldurationtype_is_null_duration() to see if there is an error
+ condition. Null duration is perfectly valid for an alarm.
+ We cannot depend on the caller to check icalerrno either,
+ following the philosophy of unix errno. we set the is_neg
+ to -1 to indicate that this is a bad duration.
+*/
+struct icaldurationtype icaldurationtype_bad_duration()
+{
+ struct icaldurationtype d;
+ memset(&d,0,sizeof(struct icaldurationtype));
+ d.is_neg = -1;
+ return d;
+}
+
+int icaldurationtype_is_bad_duration(struct icaldurationtype d)
+{
+ return (d.is_neg == -1);
+}
struct icaltimetype icaltime_add(struct icaltimetype t,
struct icaldurationtype d)
{
int dt = icaldurationtype_as_int(d);
t.second += dt;
t = icaltime_normalize(t);
return t;
}
struct icaldurationtype icaltime_subtract(struct icaltimetype t1,
struct icaltimetype t2)
{
time_t t1t = icaltime_as_timet(t1);
time_t t2t = icaltime_as_timet(t2);
- return icaldurationtype_from_int(t1t-t2t);
+ return icaldurationtype_from_int((int)(t1t-t2t));
}