104 files changed, 16402 insertions, 8085 deletions
diff --git a/bin/kdepim/kaddressbook/kaddressbook.png b/bin/kdepim/kaddressbook/kaddressbook.png Binary files differindex 87f6aa6..6b0dec6 100644 --- a/bin/kdepim/kaddressbook/kaddressbook.png +++ b/bin/kdepim/kaddressbook/kaddressbook.png diff --git a/bin/kdepim/kaddressbook/kaddressbook2.png b/bin/kdepim/kaddressbook/kaddressbook2.png Binary files differindex 6b0dec6..87f6aa6 100644 --- a/bin/kdepim/kaddressbook/kaddressbook2.png +++ b/bin/kdepim/kaddressbook/kaddressbook2.png diff --git a/kaddressbook/kabcore.cpp b/kaddressbook/kabcore.cpp index 3e578bc..70ab6b7 100644 --- a/kaddressbook/kabcore.cpp +++ b/kaddressbook/kabcore.cpp @@ -1,1571 +1,1599 @@ /* This file is part of KAddressbook. Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include "kabcore.h" #include <stdaddressbook.h> #include <klocale.h> #ifndef KAB_EMBEDDED #include <qclipboard.h> #include <qdir.h> #include <qfile.h> #include <qapplicaton.h> #include <qlayout.h> #include <qregexp.h> #include <qvbox.h> #include <kabc/addresseelist.h> #include <kabc/errorhandler.h> #include <kabc/resource.h> #include <kabc/vcardconverter.h> #include <kapplication.h> #include <kactionclasses.h> #include <kcmultidialog.h> #include <kdebug.h> #include <kdeversion.h> #include <kkeydialog.h> #include <kmessagebox.h> #include <kprinter.h> #include <kprotocolinfo.h> #include <kresources/selectdialog.h> #include <kstandarddirs.h> #include <ktempfile.h> #include <kxmlguiclient.h> #include <kaboutdata.h> #include <libkdepim/categoryselectdialog.h> #include "addresseeutil.h" #include "addresseeeditordialog.h" #include "extensionmanager.h" #include "kstdaction.h" #include "kaddressbookservice.h" #include "ldapsearchdialog.h" #include "printing/printingwizard.h" #else // KAB_EMBEDDED #include "KDGanttMinimizeSplitter.h" #include "kaddressbookmain.h" #include "kactioncollection.h" #include <qapp.h> #include <qmenubar.h> //#include <qtoolbar.h> #include <qmessagebox.h> #include <kdebug.h> #include <kiconloader.h> // needed for SmallIcon #include <kresources/kcmkresources.h> #include <ktoolbar.h> #include <kcmkabconfig.h> //US#include <qpe/resource.h> // needed for Resource::loadPixmap //#include <qlabel.h> #endif // KAB_EMBEDDED #include <kcmkabconfig.h> #include <kresources/selectdialog.h> #include <kmessagebox.h> #include <picture.h> #include <resource.h> //US#include <qsplitter.h> #include <qvbox.h> #include <qlayout.h> #include <qclipboard.h> #include <libkdepim/categoryselectdialog.h> #include "addresseeutil.h" #include "undocmds.h" #include "addresseeeditordialog.h" #include "viewmanager.h" #include "details/detailsviewcontainer.h" #include "kabprefs.h" #include "xxportmanager.h" #include "incsearchwidget.h" #include "jumpbuttonbar.h" #include "extensionmanager.h" #include "addresseeconfig.h" #include <kcmultidialog.h> #ifdef KAB_EMBEDDED KABCore::KABCore( KAddressBookMain *client, bool readWrite, QWidget *parent, const char *name ) : QWidget( parent, name ), mGUIClient( client ), mViewManager( 0 ), mExtensionManager( 0 ),mConfigureDialog( 0 ),/*US mLdapSearchDialog( 0 ),*/ mReadWrite( readWrite ), mModified( false ), mMainWindow(client) #else //KAB_EMBEDDED KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent, const char *name ) : QWidget( parent, name ), mGUIClient( client ), mViewManager( 0 ), mExtensionManager( 0 ), mConfigureDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ), mModified( false ) #endif //KAB_EMBEDDED { #ifdef KAB_EMBEDDED //US we define here our own global actioncollection. //mActionCollection = new KActionCollection(this); #endif //KAB_EMBEDDED - + mExtensionBarSplitter = 0; mIsPart = !parent->inherits( "KAddressBookMain" ); mAddressBook = KABC::StdAddressBook::self(); KABC::StdAddressBook::setAutomaticSave( true ); #ifndef KAB_EMBEDDED mAddressBook->setErrorHandler( new KABC::GUIErrorHandler ); #endif //KAB_EMBEDDED connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook * ) ), SLOT( addressBookChanged() ) ); mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization, "X-Department", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization, "X-Profession", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization, "X-AssistantsName", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization, "X-ManagersName", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Spouse's Name" ), KABC::Field::Personal, "X-SpousesName", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal, "X-Office", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal, "X-IMAddress", "KADDRESSBOOK" ); mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal, "X-Anniversary", "KADDRESSBOOK" ); initGUI(); mIncSearchWidget->setFocus(); connect( mViewManager, SIGNAL( selected( const QString& ) ), SLOT( setContactSelected( const QString& ) ) ); connect( mViewManager, SIGNAL( executed( const QString& ) ), SLOT( editContact( const QString& ) ) ); connect( mViewManager, SIGNAL( deleteRequest( ) ), SLOT( deleteContacts( ) ) ); connect( mViewManager, SIGNAL( modified() ), SLOT( setModified() ) ); connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ), this, SLOT( extensionModified( const KABC::Addressee::List& ) ) ); connect( mXXPortManager, SIGNAL( modified() ), SLOT( setModified() ) ); connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ), SLOT( incrementalSearch( const QString& ) ) ); connect( mIncSearchWidget, SIGNAL( fieldChanged() ), mJumpButtonBar, SLOT( recreateButtons() ) ); #ifndef KAB_EMBEDDED connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ), mXXPortManager, SLOT( importVCard( const KURL& ) ) ); connect( mDetails, SIGNAL( sendEmail( const QString& ) ), SLOT( sendMail( const QString& ) ) ); connect( mDetails, SIGNAL( browse( const QString& ) ), SLOT( browse( const QString& ) ) ); mAddressBookService = new KAddressBookService( this ); #endif //KAB_EMBEDDED setModified( false ); } KABCore::~KABCore() { // save(); //saveSettings(); //KABPrefs::instance()->writeConfig(); delete AddresseeConfig::instance(); mAddressBook = 0; KABC::StdAddressBook::close(); #ifdef KAB_EMBEDDED //US we define here our own global actioncollection. // delete mActionCollection; #endif //KAB_EMBEDDED } void KABCore::restoreSettings() { bool state = KABPrefs::instance()->mJumpButtonBarVisible; mActionJumpBar->setChecked( state ); setJumpButtonBarVisible( state ); state = KABPrefs::instance()->mDetailsPageVisible; mActionDetails->setChecked( state ); setDetailsVisible( state ); - QValueList<int> splitterSize = KABPrefs::instance()->mExtensionsSplitter; + QValueList<int> splitterSize = KABPrefs::instance()->mDetailsSplitter; if ( splitterSize.count() == 0 ) { splitterSize.append( width() / 2 ); splitterSize.append( width() / 2 ); } mMiniSplitter->setSizes( splitterSize ); + if ( mExtensionBarSplitter ) { + splitterSize = KABPrefs::instance()->mExtensionsSplitter; + if ( splitterSize.count() == 0 ) { + splitterSize.append( width() / 2 ); + splitterSize.append( width() / 2 ); + } + mExtensionBarSplitter->setSizes( splitterSize ); + + } #ifndef KAB_EMBEDDED QValueList<int> splitterSize = KABPrefs::instance()->mExtensionsSplitter; if ( splitterSize.count() == 0 ) { splitterSize.append( width() / 2 ); splitterSize.append( width() / 2 ); } mExtensionBarSplitter->setSizes( splitterSize ); splitterSize = KABPrefs::instance()->mDetailsSplitter; if ( splitterSize.count() == 0 ) { splitterSize.append( height() / 2 ); splitterSize.append( height() / 2 ); } mDetailsSplitter->setSizes( splitterSize ); mExtensionManager->restoreSettings(); #endif //KAB_EMBEDDED mIncSearchWidget->setCurrentItem( KABPrefs::instance()->mCurrentIncSearchField ); mViewManager->restoreSettings(); mExtensionManager->restoreSettings(); } void KABCore::saveSettings() { KABPrefs::instance()->mJumpButtonBarVisible = mActionJumpBar->isChecked(); - KABPrefs::instance()->mExtensionsSplitter = mMiniSplitter->sizes(); + if ( mExtensionBarSplitter ) + KABPrefs::instance()->mExtensionsSplitter = mExtensionBarSplitter->sizes(); KABPrefs::instance()->mDetailsPageVisible = mActionDetails->isChecked(); - + KABPrefs::instance()->mDetailsSplitter = mMiniSplitter->sizes(); #ifndef KAB_EMBEDDED KABPrefs::instance()->mExtensionsSplitter = mExtensionBarSplitter->sizes(); KABPrefs::instance()->mDetailsSplitter = mDetailsSplitter->sizes(); #endif //KAB_EMBEDDED mExtensionManager->saveSettings(); mViewManager->saveSettings(); KABPrefs::instance()->mCurrentIncSearchField = mIncSearchWidget->currentItem(); } KABC::AddressBook *KABCore::addressBook() const { return mAddressBook; } KConfig *KABCore::config() { #ifndef KAB_EMBEDDED return KABPrefs::instance()->config(); #else //KAB_EMBEDDED return KABPrefs::instance()->getConfig(); #endif //KAB_EMBEDDED } KActionCollection *KABCore::actionCollection() const { return mGUIClient->actionCollection(); } KABC::Field *KABCore::currentSearchField() const { if (mIncSearchWidget) return mIncSearchWidget->currentField(); else return 0; } QStringList KABCore::selectedUIDs() const { return mViewManager->selectedUids(); } KABC::Resource *KABCore::requestResource( QWidget *parent ) { QPtrList<KABC::Resource> kabcResources = addressBook()->resources(); QPtrList<KRES::Resource> kresResources; QPtrListIterator<KABC::Resource> resIt( kabcResources ); KABC::Resource *resource; while ( ( resource = resIt.current() ) != 0 ) { ++resIt; if ( !resource->readOnly() ) { KRES::Resource *res = static_cast<KRES::Resource*>( resource ); if ( res ) kresResources.append( res ); } } KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent ); return static_cast<KABC::Resource*>( res ); } #ifndef KAB_EMBEDDED KAboutData *KABCore::createAboutData() #else //KAB_EMBEDDED void KABCore::createAboutData() #endif //KAB_EMBEDDED { #ifndef KAB_EMBEDDED KAboutData *about = new KAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ), "3.1", I18N_NOOP( "The KDE Address Book" ), KAboutData::License_GPL_V2, I18N_NOOP( "(c) 1997-2003, The KDE PIM Team" ) ); about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer " ), "tokoe@kde.org" ); about->addAuthor( "Don Sanders", I18N_NOOP( "Original author " ) ); about->addAuthor( "Cornelius Schumacher", I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export " ), "schumacher@kde.org" ); about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign " ), "mpilone@slac.com" ); about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) ); about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) ); about->addAuthor( "Michel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup\n" ), "michel@klaralvdalens-datakonsult.se" ); about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup " ), "hansen@kde.org" ); return about; #endif //KAB_EMBEDDED QString version; #include <../version> QMessageBox::about( this, "About KAddressbook/Pi", "KAddressbook/Platform-independent\n" "(KA/Pi) " +version + " - " + #ifdef DESKTOP_VERSION "Desktop Edition\n" #else "PDA-Edition\n" "for: Zaurus 5500 / 7x0 / 8x0\n" #endif "(c) 2004 Ulf Schenk\n" "(c) 1997-2003, The KDE PIM Team\n" "Tobias Koenig Current maintainer tokoe@kde.org\n" "Don Sanders Original author\n" "Cornelius Schumacher Co-maintainer schumacher@kde.org\n" "Mike Pilone GUI and framework redesign mpilone@slac.com\n" "Greg Stern DCOP interface\n" "Mark Westcot Contact pinning\n" "Michel Boyer de la Giroday LDAP Lookup\n" "michel@klaralvdalens-datakonsult.se\n" "Steffen Hansen LDAP Lookup hansen@kde.org\n" ); } void KABCore::setContactSelected( const QString &uid ) { KABC::Addressee addr = mAddressBook->findByUid( uid ); if ( !mDetails->isHidden() ) mDetails->setAddressee( addr ); if ( !addr.isEmpty() ) { emit contactSelected( addr.formattedName() ); KABC::Picture pic = addr.photo(); if ( pic.isIntern() ) { //US emit contactSelected( pic.data() ); //US instead use: QPixmap px; if (pic.data().isNull() != true) { px.convertFromImage(pic.data()); } emit contactSelected( px ); } } mExtensionManager->setSelectionChanged(); // update the actions bool selected = !uid.isEmpty(); if ( mReadWrite ) { mActionCut->setEnabled( selected ); mActionPaste->setEnabled( selected ); } mActionCopy->setEnabled( selected ); mActionDelete->setEnabled( selected ); mActionEditAddressee->setEnabled( selected ); mActionMail->setEnabled( selected ); mActionMailVCard->setEnabled( selected ); mActionWhoAmI->setEnabled( selected ); mActionCategories->setEnabled( selected ); } void KABCore::sendMail() { #ifndef KAB_EMBEDDED sendMail( mViewManager->selectedEmails().join( ", " ) ); #else //KAB_EMBEDDED qDebug("KABCore::sendMail() ust be fixed"); #endif //KAB_EMBEDDED } void KABCore::sendMail( const QString& email ) { #ifndef KAB_EMBEDDED kapp->invokeMailer( email, "" ); #else //KAB_EMBEDDED qDebug("KABCore::sendMail(const QString& email) ust be fixed"); #endif //KAB_EMBEDDED } void KABCore::mailVCard() { #ifndef KAB_EMBEDDED QStringList uids = mViewManager->selectedUids(); if ( !uids.isEmpty() ) mailVCard( uids ); #else //KAB_EMBEDDED qDebug("KABCore::mailVCard() must be fixed"); #endif //KAB_EMBEDDED } void KABCore::mailVCard( const QStringList& uids ) { #ifndef KAB_EMBEDDED QStringList urls; // Create a temp dir, so that we can put the files in it with proper names KTempFile tempDir; if ( tempDir.status() != 0 ) { kdWarning() << strerror( tempDir.status() ) << endl; return; } QString dirName = tempDir.name(); tempDir.unlink(); QDir().mkdir( dirName, true ); for( QStringList::ConstIterator it = uids.begin(); it != uids.end(); ++it ) { KABC::Addressee a = mAddressBook->findByUid( *it ); if ( a.isEmpty() ) continue; QString name = a.givenName() + "_" + a.familyName() + ".vcf"; QString fileName = dirName + "/" + name; QFile outFile(fileName); if ( outFile.open(IO_WriteOnly) ) { // file opened successfully KABC::VCardConverter converter; QString vcard; converter.addresseeToVCard( a, vcard ); QTextStream t( &outFile ); // use a text stream t.setEncoding( QTextStream::UnicodeUTF8 ); t << vcard; outFile.close(); urls.append( fileName ); } } kapp->invokeMailer( QString::null, QString::null, QString::null, QString::null, // subject QString::null, // body QString::null, urls ); // attachments #else //KAB_EMBEDDED qDebug("KABCore::mailVCard( must be fixed"); #endif //KAB_EMBEDDED } void KABCore::browse( const QString& url ) { #ifndef KAB_EMBEDDED kapp->invokeBrowser( url ); #else //KAB_EMBEDDED qDebug("KABCore::browse must be fixed"); #endif //KAB_EMBEDDED } void KABCore::selectAllContacts() { mViewManager->setSelected( QString::null, true ); } void KABCore::deleteContacts() { QStringList uidList = mViewManager->selectedUids(); deleteContacts( uidList ); } void KABCore::deleteContacts( const QStringList &uids ) { if ( uids.count() > 0 ) { PwDeleteCommand *command = new PwDeleteCommand( mAddressBook, uids ); UndoStack::instance()->push( command ); RedoStack::instance()->clear(); // now if we deleted anything, refresh setContactSelected( QString::null ); setModified( true ); } } void KABCore::copyContacts() { KABC::Addressee::List addrList = mViewManager->selectedAddressees(); QString clipText = AddresseeUtil::addresseesToClipboard( addrList ); kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl; QClipboard *cb = QApplication::clipboard(); cb->setText( clipText ); } void KABCore::cutContacts() { QStringList uidList = mViewManager->selectedUids(); //US if ( uidList.size() > 0 ) { if ( uidList.count() > 0 ) { PwCutCommand *command = new PwCutCommand( mAddressBook, uidList ); UndoStack::instance()->push( command ); RedoStack::instance()->clear(); setModified( true ); } } void KABCore::pasteContacts() { QClipboard *cb = QApplication::clipboard(); KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() ); pasteContacts( list ); } void KABCore::pasteContacts( KABC::Addressee::List &list ) { KABC::Resource *resource = requestResource( this ); KABC::Addressee::List::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) (*it).setResource( resource ); PwPasteCommand *command = new PwPasteCommand( this, list ); UndoStack::instance()->push( command ); RedoStack::instance()->clear(); setModified( true ); } void KABCore::setWhoAmI() { KABC::Addressee::List addrList = mViewManager->selectedAddressees(); if ( addrList.count() > 1 ) { KMessageBox::sorry( this, i18n( "Please select only one contact." ) ); return; } QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) ); if ( KMessageBox::questionYesNo( this, text.arg( addrList[ 0 ].assembledName() ) ) == KMessageBox::Yes ) static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self() )->setWhoAmI( addrList[ 0 ] ); } void KABCore::setCategories() { KPIM::CategorySelectDialog dlg( KABPrefs::instance(), this, "", true ); if ( !dlg.exec() ) return; bool merge = false; QString msg = i18n( "Merge with existing categories?" ); if ( KMessageBox::questionYesNo( this, msg ) == KMessageBox::Yes ) merge = true; QStringList categories = dlg.selectedCategories(); QStringList uids = mViewManager->selectedUids(); QStringList::Iterator it; for ( it = uids.begin(); it != uids.end(); ++it ) { KABC::Addressee addr = mAddressBook->findByUid( *it ); if ( !addr.isEmpty() ) { if ( !merge ) addr.setCategories( categories ); else { QStringList addrCategories = addr.categories(); QStringList::Iterator catIt; for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) { if ( !addrCategories.contains( *catIt ) ) addrCategories.append( *catIt ); } addr.setCategories( addrCategories ); } mAddressBook->insertAddressee( addr ); } } if ( uids.count() > 0 ) setModified( true ); } void KABCore::setSearchFields( const KABC::Field::List &fields ) { mIncSearchWidget->setFields( fields ); } void KABCore::incrementalSearch( const QString& text ) { mViewManager->setSelected( QString::null, false ); if ( !text.isEmpty() ) { KABC::Field *field = mIncSearchWidget->currentField(); QString pattern = text.lower(); #if KDE_VERSION >= 319 KABC::AddresseeList list( mAddressBook->allAddressees() ); if ( field ) { list.sortByField( field ); KABC::AddresseeList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { if ( field->value( *it ).lower().startsWith( pattern ) ) { mViewManager->setSelected( (*it).uid(), true ); return; } } } else { KABC::AddresseeList::Iterator it; for ( it = list.begin(); it != list.end(); ++it ) { KABC::Field::List fieldList = mIncSearchWidget->fields(); KABC::Field::List::ConstIterator fieldIt; for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) { if ( (*fieldIt)->value( *it ).lower().startsWith( pattern ) ) { mViewManager->setSelected( (*it).uid(), true ); return; } } } } #else KABC::AddressBook::Iterator it; for ( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) { if ( field ) { if ( field->value( *it ).lower().startsWith( pattern ) ) { mViewManager->setSelected( (*it).uid(), true ); return; } } else { KABC::Field::List fieldList = mIncSearchWidget->fields(); KABC::Field::List::ConstIterator fieldIt; for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) { if ( (*fieldIt)->value( *it ).lower().startsWith( pattern ) ) { mViewManager->setSelected( (*it).uid(), true ); return; } } } } #endif } } void KABCore::setModified() { setModified( true ); } void KABCore::setModifiedWOrefresh() { // qDebug("KABCore::setModifiedWOrefresh() "); mModified = true; mActionSave->setEnabled( mModified ); #ifdef DESKTOP_VERSION mDetails->refreshView(); #endif } void KABCore::setModified( bool modified ) { mModified = modified; mActionSave->setEnabled( mModified ); if ( modified ) mJumpButtonBar->recreateButtons(); mViewManager->refreshView(); mDetails->refreshView(); } bool KABCore::modified() const { return mModified; } void KABCore::contactModified( const KABC::Addressee &addr ) { Command *command = 0; QString uid; // check if it exists already KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() ); if ( origAddr.isEmpty() ) command = new PwNewCommand( mAddressBook, addr ); else { command = new PwEditCommand( mAddressBook, origAddr, addr ); uid = addr.uid(); } UndoStack::instance()->push( command ); RedoStack::instance()->clear(); setModified( true ); } void KABCore::newContact() { AddresseeEditorDialog *dialog = 0; QPtrList<KABC::Resource> kabcResources = mAddressBook->resources(); QPtrList<KRES::Resource> kresResources; QPtrListIterator<KABC::Resource> it( kabcResources ); KABC::Resource *resource; while ( ( resource = it.current() ) != 0 ) { ++it; if ( !resource->readOnly() ) { KRES::Resource *res = static_cast<KRES::Resource*>( resource ); if ( res ) kresResources.append( res ); } } KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, this ); resource = static_cast<KABC::Resource*>( res ); if ( resource ) { KABC::Addressee addr; addr.setResource( resource ); dialog = createAddresseeEditorDialog( this ); dialog->setAddressee( addr ); } else return; mEditorDict.insert( dialog->addressee().uid(), dialog ); dialog->show(); } void KABCore::addEmail( QString aStr ) { #ifndef KAB_EMBEDDED QString fullName, email; KABC::Addressee::parseEmailAddress( aStr, fullName, email ); // Try to lookup the addressee matching the email address bool found = false; QStringList emailList; KABC::AddressBook::Iterator it; for ( it = mAddressBook->begin(); !found && (it != mAddressBook->end()); ++it ) { emailList = (*it).emails(); if ( emailList.contains( email ) > 0 ) { found = true; (*it).setNameFromString( fullName ); editContact( (*it).uid() ); } } if ( !found ) { KABC::Addressee addr; addr.setNameFromString( fullName ); addr.insertEmail( email, true ); mAddressBook->insertAddressee( addr ); mViewManager->refreshView( addr.uid() ); editContact( addr.uid() ); } #else //KAB_EMBEDDED qDebug("KABCore::addEmail finsih method"); #endif //KAB_EMBEDDED } void KABCore::importVCard( const KURL &url, bool showPreview ) { mXXPortManager->importVCard( url, showPreview ); } void KABCore::importVCard( const QString &vCard, bool showPreview ) { mXXPortManager->importVCard( vCard, showPreview ); } //US added a second method without defaultparameter void KABCore::editContact2() { editContact( QString::null ); } void KABCore::editContact( const QString &uid ) { if ( mExtensionManager->isQuickEditVisible() ) return; // First, locate the contact entry QString localUID = uid; if ( localUID.isNull() ) { QStringList uidList = mViewManager->selectedUids(); if ( uidList.count() > 0 ) localUID = *( uidList.at( 0 ) ); } KABC::Addressee addr = mAddressBook->findByUid( localUID ); if ( !addr.isEmpty() ) { AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() ); if ( !dialog ) { dialog = createAddresseeEditorDialog( this ); mEditorDict.insert( addr.uid(), dialog ); dialog->setAddressee( addr ); } dialog->raise(); dialog->show(); } } void KABCore::save() { if ( !mModified ) return; QString text = i18n( "There was an error while attempting to save\n the " "address book. Please check that some \nother application is " "not using it. " ); statusMessage(i18n("Saving addressbook ... ")); #ifndef KAB_EMBEDDED KABC::StdAddressBook *b = dynamic_cast<KABC::StdAddressBook*>( mAddressBook ); if ( !b || !b->save() ) { KMessageBox::error( this, text, i18n( "Unable to Save" ) ); } #else //KAB_EMBEDDED KABC::StdAddressBook *b = (KABC::StdAddressBook*)( mAddressBook ); if ( !b || !b->save() ) { QMessageBox::critical( this, i18n( "Unable to Save" ), text, i18n("Ok")); } #endif //KAB_EMBEDDED statusMessage(i18n("Addressbook saved!")); setModified( false ); } void KABCore::statusMessage(QString mess , int time ) { //topLevelWidget()->setCaption( mess ); // pending setting timer to revome message } void KABCore::undo() { UndoStack::instance()->undo(); // Refresh the view mViewManager->refreshView(); } void KABCore::redo() { RedoStack::instance()->redo(); // Refresh the view mViewManager->refreshView(); } void KABCore::setJumpButtonBarVisible( bool visible ) { if ( visible ) mJumpButtonBar->show(); else mJumpButtonBar->hide(); } void KABCore::setDetailsToState() { setDetailsVisible( mActionDetails->isChecked() ); } void KABCore::setDetailsVisible( bool visible ) { if ( visible ) mDetails->show(); else mDetails->hide(); } void KABCore::extensionModified( const KABC::Addressee::List &list ) { if ( list.count() != 0 ) { KABC::Addressee::List::ConstIterator it; for ( it = list.begin(); it != list.end(); ++it ) mAddressBook->insertAddressee( *it ); if ( list.count() > 1 ) setModified(); else setModifiedWOrefresh(); } if ( list.count() == 0 ) mViewManager->refreshView(); else mViewManager->refreshView( list[ 0 ].uid() ); } QString KABCore::getNameByPhone( const QString &phone ) { #ifndef KAB_EMBEDDED QRegExp r( "[/*/-/ ]" ); QString localPhone( phone ); bool found = false; QString ownerName = ""; KABC::AddressBook::Iterator iter; KABC::PhoneNumber::List::Iterator phoneIter; KABC::PhoneNumber::List phoneList; for ( iter = mAddressBook->begin(); !found && ( iter != mAddressBook->end() ); ++iter ) { phoneList = (*iter).phoneNumbers(); for ( phoneIter = phoneList.begin(); !found && ( phoneIter != phoneList.end() ); ++phoneIter) { // Get rid of separator chars so just the numbers are compared. if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) { ownerName = (*iter).formattedName(); found = true; } } } return ownerName; #else //KAB_EMBEDDED qDebug("KABCore::getNameByPhone finsih method"); return ""; #endif //KAB_EMBEDDED } void KABCore::openConfigDialog() { KCMultiDialog* ConfigureDialog = new KCMultiDialog( "PIM", this ,"kabconfigdialog", true ); KCMKabConfig* kabcfg = new KCMKabConfig( ConfigureDialog->getNewVBoxPage(i18n( "Addressbook")) , "KCMKabConfig" ); ConfigureDialog->addModule(kabcfg ); connect( ConfigureDialog, SIGNAL( applyClicked() ), this, SLOT( configurationChanged() ) ); connect( ConfigureDialog, SIGNAL( okClicked() ), this, SLOT( configurationChanged() ) ); saveSettings(); ConfigureDialog->exec(); delete ConfigureDialog; } void KABCore::openLDAPDialog() { #ifndef KAB_EMBEDDED if ( !mLdapSearchDialog ) { mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this ); connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), mViewManager, SLOT( refreshView() ) ); connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), this, SLOT( setModified() ) ); } else mLdapSearchDialog->restoreSettings(); if ( mLdapSearchDialog->isOK() ) mLdapSearchDialog->exec(); #else //KAB_EMBEDDED qDebug("KABCore::openLDAPDialog() finsih method"); #endif //KAB_EMBEDDED } void KABCore::print() { #ifndef KAB_EMBEDDED KPrinter printer; if ( !printer.setup( this ) ) return; KABPrinting::PrintingWizard wizard( &printer, mAddressBook, mViewManager->selectedUids(), this ); wizard.exec(); #else //KAB_EMBEDDED qDebug("KABCore::print() finsih method"); #endif //KAB_EMBEDDED } void KABCore::addGUIClient( KXMLGUIClient *client ) { if ( mGUIClient ) mGUIClient->insertChildClient( client ); else KMessageBox::error( this, "no KXMLGUICLient"); } void KABCore::configurationChanged() { mExtensionManager->reconfigure(); } void KABCore::addressBookChanged() { #ifndef KAB_EMBEDDED QDictIterator<AddresseeEditorDialog> it( mEditorDict ); while ( it.current() ) { if ( it.current()->dirty() ) { QString text = i18n( "Data has been changed externally. Unsaved " "changes will be lost." ); KMessageBox::information( this, text ); } it.current()->setAddressee( mAddressBook->findByUid( it.currentKey() ) ); ++it; } mViewManager->refreshView(); #else //KAB_EMBEDDED qDebug("KABCore::addressBookChanged() finsih method"); #endif //KAB_EMBEDDED } AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent, const char *name ) { AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent, name ? name : "editorDialog" ); //US dialog->setMaximumSize( 640, 480 ); dialog->showMaximized(); connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ), SLOT( contactModified( const KABC::Addressee& ) ) ); connect( dialog, SIGNAL( editorDestroyed( const QString& ) ), SLOT( slotEditorDestroyed( const QString& ) ) ); return dialog; } void KABCore::slotEditorDestroyed( const QString &uid ) { mEditorDict.remove( uid ); } void KABCore::initGUI() { #ifndef KAB_EMBEDDED QHBoxLayout *topLayout = new QHBoxLayout( this ); topLayout->setSpacing( KDialogBase::spacingHint() ); mExtensionBarSplitter = new QSplitter( this ); mExtensionBarSplitter->setOrientation( Qt::Vertical ); mDetailsSplitter = new QSplitter( mExtensionBarSplitter ); QVBox *viewSpace = new QVBox( mDetailsSplitter ); mIncSearchWidget = new IncSearchWidget( viewSpace ); connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ), SLOT( incrementalSearch( const QString& ) ) ); mViewManager = new ViewManager( this, viewSpace ); viewSpace->setStretchFactor( mViewManager, 1 ); mDetails = new ViewContainer( mDetailsSplitter ); mJumpButtonBar = new JumpButtonBar( this, this ); mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter ); topLayout->addWidget( mExtensionBarSplitter ); topLayout->setStretchFactor( mExtensionBarSplitter, 100 ); topLayout->addWidget( mJumpButtonBar ); topLayout->setStretchFactor( mJumpButtonBar, 1 ); mXXPortManager = new XXPortManager( this, this ); #else //KAB_EMBEDDED //US initialize viewMenu before settingup viewmanager. // Viewmanager needs this menu to plugin submenues. viewMenu = new QPopupMenu( this ); settingsMenu = new QPopupMenu( this ); //filterMenu = new QPopupMenu( this ); ImportMenu = new QPopupMenu( this ); ExportMenu = new QPopupMenu( this ); //US since we have no splitter for the embedded system, setup // a layout with two frames. One left and one right. QBoxLayout *topLayout; // = new QHBoxLayout( this ); // QBoxLayout *topLayout = (QBoxLayout*)layout(); // QWidget *mainBox = new QWidget( this ); // QBoxLayout * mainBoxLayout = new QHBoxLayout(mainBox); - +#ifdef DESKTOP_VERSION + topLayout = new QHBoxLayout( this ); + + + mMiniSplitter = new KDGanttMinimizeSplitter( Qt::Horizontal, this); + mMiniSplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Right ); + + topLayout->addWidget(mMiniSplitter ); + + mExtensionBarSplitter = new KDGanttMinimizeSplitter( Qt::Vertical,mMiniSplitter ); + mExtensionBarSplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Down ); + mViewManager = new ViewManager( this, mExtensionBarSplitter ); + mDetails = new ViewContainer( mMiniSplitter ); + mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter ); +#else if ( QApplication::desktop()->width() > 480 ) { topLayout = new QHBoxLayout( this ); mMiniSplitter = new KDGanttMinimizeSplitter( Qt::Horizontal, this); mMiniSplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Right ); } else { topLayout = new QVBoxLayout( this ); mMiniSplitter = new KDGanttMinimizeSplitter( Qt::Vertical, this); mMiniSplitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Down ); } topLayout->addWidget(mMiniSplitter ); mViewManager = new ViewManager( this, mMiniSplitter ); mDetails = new ViewContainer( mMiniSplitter ); mExtensionManager = new ExtensionManager( this, mMiniSplitter ); - +#endif //eh->hide(); // topLayout->addWidget(mExtensionManager ); /*US #ifndef KAB_NOSPLITTER QHBoxLayout *topLayout = new QHBoxLayout( this ); //US topLayout->setSpacing( KDialogBase::spacingHint() ); topLayout->setSpacing( 10 ); mDetailsSplitter = new QSplitter( this ); QVBox *viewSpace = new QVBox( mDetailsSplitter ); mViewManager = new ViewManager( this, viewSpace ); viewSpace->setStretchFactor( mViewManager, 1 ); mDetails = new ViewContainer( mDetailsSplitter ); topLayout->addWidget( mDetailsSplitter ); topLayout->setStretchFactor( mDetailsSplitter, 100 ); #else //KAB_NOSPLITTER QHBoxLayout *topLayout = new QHBoxLayout( this ); //US topLayout->setSpacing( KDialogBase::spacingHint() ); topLayout->setSpacing( 10 ); // mDetailsSplitter = new QSplitter( this ); QVBox *viewSpace = new QVBox( this ); mViewManager = new ViewManager( this, viewSpace ); viewSpace->setStretchFactor( mViewManager, 1 ); mDetails = new ViewContainer( this ); topLayout->addWidget( viewSpace ); // topLayout->setStretchFactor( mDetailsSplitter, 100 ); topLayout->addWidget( mDetails ); #endif //KAB_NOSPLITTER */ #endif //KAB_EMBEDDED initActions(); #ifdef KAB_EMBEDDED addActionsManually(); //US make sure the export and import menues are initialized before creating the xxPortManager. mXXPortManager = new XXPortManager( this, this ); // LR mIncSearchWidget = new IncSearchWidget( mMainWindow->getIconToolBar() ); //mMainWindow->toolBar()->insertWidget(-1, 4, mIncSearchWidget); // mActionQuit->plug ( mMainWindow->toolBar()); //mIncSearchWidget = new IncSearchWidget( mMainWindow->toolBar() ); //mMainWindow->toolBar()->insertWidget(-1, 0, mIncSearchWidget); // mIncSearchWidget->hide(); connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ), SLOT( incrementalSearch( const QString& ) ) ); mJumpButtonBar = new JumpButtonBar( this, this ); topLayout->addWidget( mJumpButtonBar ); //US topLayout->setStretchFactor( mJumpButtonBar, 10 ); // mMainWindow->getIconToolBar()->raise(); #endif //KAB_EMBEDDED } void KABCore::initActions() { //US qDebug("KABCore::initActions(): mIsPart %i", mIsPart); #ifndef KAB_EMBEDDED connect( QApplication::clipboard(), SIGNAL( dataChanged() ), SLOT( clipboardDataChanged() ) ); #endif //KAB_EMBEDDED // file menu if ( mIsPart ) { mActionMail = new KAction( i18n( "&Mail" ), "mail_generic", 0, this, SLOT( sendMail() ), actionCollection(), "kaddressbook_mail" ); mActionPrint = new KAction( i18n( "&Print" ), "fileprint", CTRL + Key_P, this, SLOT( print() ), actionCollection(), "kaddressbook_print" ); } else { mActionMail = KStdAction::mail( this, SLOT( sendMail() ), actionCollection() ); mActionPrint = KStdAction::print( this, SLOT( print() ), actionCollection() ); } mActionSave = new KAction( i18n( "&Save" ), "filesave", CTRL+Key_S, this, SLOT( save() ), actionCollection(), "file_sync" ); mActionNewContact = new KAction( i18n( "&New Contact..." ), "filenew", CTRL+Key_N, this, SLOT( newContact() ), actionCollection(), "file_new_contact" ); mActionMailVCard = new KAction(i18n("Mail &vCard..."), "mail_post_to", 0, this, SLOT( mailVCard() ), actionCollection(), "file_mail_vcard"); mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0, this, SLOT( editContact2() ), actionCollection(), "file_properties" ); #ifdef KAB_EMBEDDED // mActionQuit = KStdAction::quit( mMainWindow, SLOT( exit() ), actionCollection() ); mActionQuit = new KAction( i18n( "&Exit" ), "exit", 0, mMainWindow, SLOT( exit() ), actionCollection(), "quit" ); #endif //KAB_EMBEDDED // edit menu if ( mIsPart ) { mActionCopy = new KAction( i18n( "&Copy" ), "editcopy", CTRL + Key_C, this, SLOT( copyContacts() ), actionCollection(), "kaddressbook_copy" ); mActionCut = new KAction( i18n( "Cu&t" ), "editcut", CTRL + Key_X, this, SLOT( cutContacts() ), actionCollection(), "kaddressbook_cut" ); mActionPaste = new KAction( i18n( "&Paste" ), "editpaste", CTRL + Key_V, this, SLOT( pasteContacts() ), actionCollection(), "kaddressbook_paste" ); mActionSelectAll = new KAction( i18n( "Select &All" ), CTRL + Key_A, this, SLOT( selectAllContacts() ), actionCollection(), "kaddressbook_select_all" ); mActionUndo = new KAction( i18n( "&Undo" ), "undo", CTRL + Key_Z, this, SLOT( undo() ), actionCollection(), "kaddressbook_undo" ); mActionRedo = new KAction( i18n( "Re&do" ), "redo", CTRL + SHIFT + Key_Z, this, SLOT( redo() ), actionCollection(), "kaddressbook_redo" ); } else { mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() ); mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() ); mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() ); mActionSelectAll = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() ); mActionUndo = KStdAction::undo( this, SLOT( undo() ), actionCollection() ); mActionRedo = KStdAction::redo( this, SLOT( redo() ), actionCollection() ); } mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete", Key_Delete, this, SLOT( deleteContacts() ), actionCollection(), "edit_delete" ); mActionUndo->setEnabled( false ); mActionRedo->setEnabled( false ); // settings menu #ifdef KAB_EMBEDDED //US special menuentry to configure the addressbook resources. On KDE // you do that through the control center !!! mActionConfigResources = new KAction( i18n( "Configure &Resources..." ), "configure_resources", 0, this, SLOT( configureResources() ), actionCollection(), "kaddressbook_configure_resources" ); #endif //KAB_EMBEDDED if ( mIsPart ) { mActionConfigKAddressbook = new KAction( i18n( "&Configure KAddressBook..." ), "configure", 0, this, SLOT( openConfigDialog() ), actionCollection(), "kaddressbook_configure" ); mActionConfigShortcuts = new KAction( i18n( "Configure S&hortcuts..." ), "configure_shortcuts", 0, this, SLOT( configureKeyBindings() ), actionCollection(), "kaddressbook_configure_shortcuts" ); #ifdef KAB_EMBEDDED mActionConfigureToolbars = KStdAction::configureToolbars( this, SLOT( mMainWindow->configureToolbars() ), actionCollection() ); #endif //KAB_EMBEDDED } else { mActionConfigKAddressbook = KStdAction::preferences( this, SLOT( openConfigDialog() ), actionCollection() ); mActionKeyBindings = KStdAction::keyBindings( this, SLOT( configureKeyBindings() ), actionCollection() ); } mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), 0, 0, actionCollection(), "options_show_jump_bar" ); connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) ); mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0, actionCollection(), "options_show_details" ); connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) ); // misc // only enable LDAP lookup if we can handle the protocol #ifndef KAB_EMBEDDED if ( KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) { new KAction( i18n( "&Lookup Addresses in Directory" ), "find", 0, this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" ); } #else //KAB_EMBEDDED //qDebug("KABCore::initActions() LDAP has to be implemented"); #endif //KAB_EMBEDDED mActionWhoAmI = new KAction( i18n( "Set Who Am I" ), "personal", 0, this, SLOT( setWhoAmI() ), actionCollection(), "set_personal" ); mActionCategories = new KAction( i18n( "Set Categories" ), 0, this, SLOT( setCategories() ), actionCollection(), "edit_set_categories" ); #ifdef KAB_EMBEDDED mActionAboutKAddressbook = new KAction( i18n( "&About KAddressBook" ), "kaddressbook2", 0, this, SLOT( createAboutData() ), actionCollection(), "kaddressbook_about_data" ); #endif //KAB_EMBEDDED clipboardDataChanged(); connect( UndoStack::instance(), SIGNAL( changed() ), SLOT( updateActionMenu() ) ); connect( RedoStack::instance(), SIGNAL( changed() ), SLOT( updateActionMenu() ) ); } //US we need this function, to plug all actions into the correct menues. // KDE uses a XML format to plug the actions, but we work her without this overhead. void KABCore::addActionsManually() { //US qDebug("KABCore::initActions(): mIsPart %i", mIsPart); #ifdef KAB_EMBEDDED QPopupMenu *fileMenu = new QPopupMenu( this ); QPopupMenu *editMenu = new QPopupMenu( this ); QPopupMenu *helpMenu = new QPopupMenu( this ); KToolBar* tb = mMainWindow->toolBar(); #ifdef DESKTOP_VERSION QMenuBar* mb = mMainWindow->menuBar(); //US setup menubar. //Disable the following block if you do not want to have a menubar. mb->insertItem( "&File", fileMenu ); mb->insertItem( "&Edit", editMenu ); mb->insertItem( "&View", viewMenu ); mb->insertItem( "&Settings", settingsMenu ); mb->insertItem( "&Help", helpMenu ); mIncSearchWidget = new IncSearchWidget( tb ); // tb->insertWidget(-1, 0, mIncSearchWidget); #else //US setup toolbar QMenuBar *menuBarTB = new QMenuBar( tb ); QPopupMenu *popupBarTB = new QPopupMenu( this ); menuBarTB->insertItem( "ME", popupBarTB); tb->insertWidget(-1, 0, menuBarTB); mIncSearchWidget = new IncSearchWidget( tb ); tb->enableMoving(false); popupBarTB->insertItem( "&File", fileMenu ); popupBarTB->insertItem( "&Edit", editMenu ); popupBarTB->insertItem( "&View", viewMenu ); popupBarTB->insertItem( "&Settings", settingsMenu ); mViewManager->getFilterAction()->plug ( popupBarTB); popupBarTB->insertItem( "&Help", helpMenu ); if (QApplication::desktop()->width() > 320 ) { // mViewManager->getFilterAction()->plug ( tb); } #endif // mActionQuit->plug ( mMainWindow->toolBar()); //US Now connect the actions with the menue entries. mActionPrint->plug( fileMenu ); mActionMail->plug( fileMenu ); fileMenu->insertSeparator(); mActionNewContact->plug( fileMenu ); mActionNewContact->plug( tb ); mActionEditAddressee->plug( fileMenu ); fileMenu->insertSeparator(); mActionSave->plug( fileMenu ); fileMenu->insertItem( "&Import", ImportMenu ); fileMenu->insertItem( "&Emport", ExportMenu ); fileMenu->insertSeparator(); mActionMailVCard->plug( fileMenu ); fileMenu->insertSeparator(); mActionQuit->plug( fileMenu ); // edit menu mActionUndo->plug( editMenu ); mActionRedo->plug( editMenu ); editMenu->insertSeparator(); mActionCut->plug( editMenu ); mActionCopy->plug( editMenu ); mActionPaste->plug( editMenu ); mActionDelete->plug( editMenu ); editMenu->insertSeparator(); mActionSelectAll->plug( editMenu ); // settings menu //US special menuentry to configure the addressbook resources. On KDE // you do that through the control center !!! mActionConfigResources->plug( settingsMenu ); settingsMenu->insertSeparator(); mActionConfigKAddressbook->plug( settingsMenu ); if ( mIsPart ) { mActionConfigShortcuts->plug( settingsMenu ); mActionConfigureToolbars->plug( settingsMenu ); } else { mActionKeyBindings->plug( settingsMenu ); } settingsMenu->insertSeparator(); mActionJumpBar->plug( settingsMenu ); mActionDetails->plug( settingsMenu ); settingsMenu->insertSeparator(); mActionWhoAmI->plug( settingsMenu ); mActionCategories->plug( settingsMenu ); mActionAboutKAddressbook->plug( helpMenu ); + if (QApplication::desktop()->width() > 320 ) { mActionEditAddressee->plug( tb ); mActionSave->plug( tb ); mViewManager->getFilterAction()->plug ( tb); - if (QApplication::desktop()->width() > 480 ) - mActionDelete->plug( tb ); + if (QApplication::desktop()->width() > 480 ) { + mActionUndo->plug( tb ); + mActionDelete->plug( tb ); + mActionRedo->plug( tb ); + } } - mActionQuit->plug ( tb ); + //mActionQuit->plug ( tb ); // tb->insertWidget(-1, 0, mIncSearchWidget, 6); //US link the searchwidget first to this. // The real linkage to the toolbar happens later. //US mIncSearchWidget->reparent(tb, 0, QPoint(50,0), TRUE); //US tb->insertItem( mIncSearchWidget ); /*US mIncSearchWidget = new IncSearchWidget( tb ); connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ), SLOT( incrementalSearch( const QString& ) ) ); mJumpButtonBar = new JumpButtonBar( this, this ); //US topLayout->addWidget( mJumpButtonBar ); this->layout()->add( mJumpButtonBar ); */ #endif //KAB_EMBEDDED } void KABCore::clipboardDataChanged() { if ( mReadWrite ) mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() ); } void KABCore::updateActionMenu() { UndoStack *undo = UndoStack::instance(); RedoStack *redo = RedoStack::instance(); if ( undo->isEmpty() ) mActionUndo->setText( i18n( "Undo" ) ); else mActionUndo->setText( i18n( "Undo %1" ).arg( undo->top()->name() ) ); mActionUndo->setEnabled( !undo->isEmpty() ); if ( !redo->top() ) mActionRedo->setText( i18n( "Redo" ) ); else mActionRedo->setText( i18n( "Redo %1" ).arg( redo->top()->name() ) ); mActionRedo->setEnabled( !redo->isEmpty() ); } void KABCore::configureKeyBindings() { #ifndef KAB_EMBEDDED KKeyDialog::configure( actionCollection(), true ); #else //KAB_EMBEDDED qDebug("KABCore::configureKeyBindings() not implemented"); #endif //KAB_EMBEDDED } #ifdef KAB_EMBEDDED void KABCore::configureResources() { KRES::KCMKResources dlg( this, "" , 0 ); if ( !dlg.exec() ) return; } #endif //KAB_EMBEDDED #ifndef KAB_EMBEDDED #include "kabcore.moc" #endif //KAB_EMBEDDED diff --git a/kaddressbook/kabcore.h b/kaddressbook/kabcore.h index edf98c2..b84ec22 100644 --- a/kaddressbook/kabcore.h +++ b/kaddressbook/kabcore.h @@ -1,421 +1,421 @@ /* This file is part of KAddressbook. Copyright (c) 2003 Tobias Koenig <tokoe@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef KABCORE_H #define KABCORE_H #include <kabc/field.h> #ifndef KAB_EMBEDDED #endif //KAB_EMBEDDED #include <qdict.h> #include <qwidget.h> #include <qpopupmenu.h> namespace KABC { class AddressBook; } #ifndef KAB_EMBEDDED class KAboutData; class KConfig; class KAddressBookService; class LDAPSearchDialog; #else //KAB_EMBEDDED class KAddressBookMain; //US class QAction; #endif //KAB_EMBEDDED class KCMultiDialog; class KXMLGUIClient; class ExtensionManager; class XXPortManager; class JumpButtonBar; class IncSearchWidget; class KDGanttMinimizeSplitter; class KAction; class KActionCollection; class KToggleAction; class QAction; class QMenuBar; class QSplitter; class ViewContainer; class ViewManager; class AddresseeEditorDialog; class KABCore : public QWidget { Q_OBJECT public: KABCore( KAddressBookMain *client, bool readWrite, QWidget *parent, const char *name = 0 ); ~KABCore(); #ifdef KAB_EMBEDDED //US added functionality QPopupMenu* getViewMenu() {return viewMenu;} QPopupMenu* getFilterMenu() {return filterMenu;} QPopupMenu* getSettingsMenu() {return settingsMenu;} void addActionsManually(); #endif //KAB_EMBEDDED /** Restores the global settings. */ void restoreSettings(); /** Saves the global settings. */ void saveSettings(); /** Returns a pointer to the StdAddressBook of the application. */ KABC::AddressBook *addressBook() const; /** Returns a pointer to the KConfig object of the application. */ static KConfig *config(); /** Returns a pointer to the global KActionCollection object. So other classes can register their actions easily. */ KActionCollection *actionCollection() const; /** Returns the current search field of the Incremental Search Widget. */ KABC::Field *currentSearchField() const; /** Returns the uid list of the currently selected contacts. */ QStringList selectedUIDs() const; /** Displays the ResourceSelectDialog and returns the selected resource or a null pointer if no resource was selected by the user. */ KABC::Resource *requestResource( QWidget *parent ); #ifndef KAB_EMBEDDED static KAboutData *createAboutData(); #endif //KAB_EMBEDDED #ifdef KAB_EMBEDDED inline QPopupMenu* getImportMenu() { return ImportMenu;} inline QPopupMenu* getExportMenu() { return ExportMenu;} #endif //KAB_EMBEDDED public slots: #ifdef KAB_EMBEDDED void createAboutData(); #endif //KAB_EMBEDDED void statusMessage(QString, int time = 0 ); /** Is called whenever a contact is selected in the view. */ void setContactSelected( const QString &uid ); /** Opens the preferred mail composer with all selected contacts as arguments. */ void sendMail(); /** Opens the preferred mail composer with the given contacts as arguments. */ void sendMail( const QString& email ); void mailVCard(); void mailVCard(const QStringList& uids); /** Starts the preferred web browser with the given URL as argument. */ void browse( const QString& url ); /** Select all contacts in the view. */ void selectAllContacts(); /** Deletes all selected contacts from the address book. */ void deleteContacts(); /** Deletes given contacts from the address book. @param uids The uids of the contacts, which shall be deleted. */ void deleteContacts( const QStringList &uids ); /** Copys the selected contacts into clipboard for later pasting. */ void copyContacts(); /** Cuts the selected contacts and stores them for later pasting. */ void cutContacts(); /** Paste contacts from clipboard into the address book. */ void pasteContacts(); /** Paste given contacts into the address book. @param list The list of addressee, which shall be pasted. */ void pasteContacts( KABC::Addressee::List &list ); /** Sets the whoAmI contact, that is used by many other programs to get personal information about the current user. */ void setWhoAmI(); /** Displays the category dialog and applies the result to all selected contacts. */ void setCategories(); /** Sets the field list of the Incremental Search Widget. */ void setSearchFields( const KABC::Field::List &fields ); /** Search with the current search field for a contact, that matches the given text, and selects it in the view. */ void incrementalSearch( const QString& text ); /** Marks the address book as modified. */ void setModified(); /** Marks the address book as modified without refreshing the view. */ void setModifiedWOrefresh(); /** Marks the address book as modified concerning the argument. */ void setModified( bool modified ); /** Returns whether the address book is modified. */ bool modified() const; /** Called whenever an contact is modified in the contact editor dialog or the quick edit. */ void contactModified( const KABC::Addressee &addr ); /** DCOP METHODS. */ void addEmail( QString addr ); void importVCard( const KURL& url, bool showPreview ); void importVCard( const QString& vCard, bool showPreview ); void newContact(); QString getNameByPhone( const QString& phone ); /** END DCOP METHODS */ /** Saves the contents of the AddressBook back to disk. */ void save(); /** Undos the last command using the undo stack. */ void undo(); /** Redos the last command that was undone, using the redo stack. */ void redo(); /** Shows the edit dialog for the given uid. If the uid is QString::null, the method will try to find a selected addressee in the view. */ void editContact( const QString &uid /*US = QString::null*/ ); //US added a second method without defaultparameter void editContact2(); /** Launches the configuration dialog. */ void openConfigDialog(); /** Launches the ldap search dialog. */ void openLDAPDialog(); /** Creates a KAddressBookPrinter, which will display the print dialog and do the printing. */ void print(); /** Registers a new GUI client, so plugins can register its actions. */ void addGUIClient( KXMLGUIClient *client ); signals: void contactSelected( const QString &name ); void contactSelected( const QPixmap &pixmap ); public slots: void setDetailsVisible( bool visible ); void setDetailsToState(); private slots: void setJumpButtonBarVisible( bool visible ); void extensionModified( const KABC::Addressee::List &list ); void clipboardDataChanged(); void updateActionMenu(); void configureKeyBindings(); #ifdef KAB_EMBEDDED void configureResources(); #endif //KAB_EMBEDDED void slotEditorDestroyed( const QString &uid ); void configurationChanged(); void addressBookChanged(); private: void initGUI(); void initActions(); AddresseeEditorDialog *createAddresseeEditorDialog( QWidget *parent, const char *name = 0 ); KXMLGUIClient *mGUIClient; KABC::AddressBook *mAddressBook; ViewManager *mViewManager; // QSplitter *mDetailsSplitter; - //QSplitter *mExtensionBarSplitter; + KDGanttMinimizeSplitter *mExtensionBarSplitter; ViewContainer *mDetails; KDGanttMinimizeSplitter* mMiniSplitter; XXPortManager *mXXPortManager; JumpButtonBar *mJumpButtonBar; IncSearchWidget *mIncSearchWidget; ExtensionManager *mExtensionManager; KCMultiDialog *mConfigureDialog; #ifndef KAB_EMBEDDED KCMultiDialog *mConfigureDialog; LDAPSearchDialog *mLdapSearchDialog; #endif //KAB_EMBEDDED QDict<AddresseeEditorDialog> mEditorDict; bool mReadWrite; bool mModified; bool mIsPart; //US file menu KAction *mActionMail; KAction* mActionPrint; KAction* mActionNewContact; KAction *mActionSave; KAction *mActionEditAddressee; KAction *mActionMailVCard; KAction *mActionQuit; //US edit menu KAction *mActionCopy; KAction *mActionCut; KAction *mActionPaste; KAction *mActionSelectAll; KAction *mActionUndo; KAction *mActionRedo; KAction *mActionDelete; //US settings menu KAction *mActionConfigResources; KAction *mActionConfigKAddressbook; KAction *mActionConfigShortcuts; KAction *mActionConfigureToolbars; KAction *mActionKeyBindings; KToggleAction *mActionJumpBar; KToggleAction *mActionDetails; KAction *mActionWhoAmI; KAction *mActionCategories; KAction *mActionAboutKAddressbook; KAction *mActionDeleteView; QPopupMenu *viewMenu; QPopupMenu *filterMenu; QPopupMenu *settingsMenu; //US QAction *mActionSave; QPopupMenu *ImportMenu; QPopupMenu *ExportMenu; #ifndef KAB_EMBEDDED KAddressBookService *mAddressBookService; #endif //KAB_EMBEDDED class KABCorePrivate; KABCorePrivate *d; #ifdef KAB_EMBEDDED KAddressBookMain *mMainWindow; // should be the same like mGUIClient #endif //KAB_EMBEDDED }; #endif diff --git a/kaddressbook/kaddressbookmain.cpp b/kaddressbook/kaddressbookmain.cpp index 92c32ca..8ebb93a 100644 --- a/kaddressbook/kaddressbookmain.cpp +++ b/kaddressbook/kaddressbookmain.cpp @@ -1,293 +1,276 @@ /* This file is part of KAddressbook. Copyright (c) 1999 Don Sanders <dsanders@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifdef KAB_EMBEDDED #include "kabprefs.h" #include <kglobal.h> #include <qmessagebox.h> #include <qtoolbar.h> #include <qapplication.h> #else //KAB_EMBEDDED #include <kedittoolbar.h> #include <kkeydialog.h> #include <kmessagebox.h> #include <kstatusbar.h> #endif //KAB_EMBEDDED #include <klocale.h> #include "kabcore.h" #include "kaddressbookmain.h" #include "kactioncollection.h" #ifdef KAB_EMBEDDED KAddressBookMain::KAddressBookMain() : KMainWindow( 0, "adrressbook" ) #else //KAB_EMBEDDED //MOC_SKIP_BEGIN KAddressBookMain::KAddressBookMain() : DCOPObject( "KAddressBookIface" ), KMainWindow( 0 ) //MOC_SKIP_END #endif //KAB_EMBEDDED { setIcon(SmallIcon( "ka24" ) ); #if 0 //US for embedded systems, create the toolbar before we initiate KABCore. // KABCore will fill the toolbar with menues and icons QMainWindow::ToolBarDock tbd; tbd = Top; iconToolBar = new QToolBar( this ); addToolBar (iconToolBar , tbd ); iconToolBar->setHorizontalStretchable(true); //US iconToolBar->setWidth(300); #endif // 0 mCore = new KABCore( this, true, this ); #ifdef KAB_EMBEDDED setCaption( i18n( "KAddressbook/Pi" ) ); #else //KAB_EMBEDDED setCaption( i18n( "Address Book Browser" ) ); #endif //KAB_EMBEDDED //mCore->restoreSettings(); initActions(); setCentralWidget( mCore ); //US statusBar()->show(); #ifndef KAB_EMBEDDED setStandardToolBarMenuEnabled(true); createGUI( "kaddressbookui.rc", false ); #endif //KAB_EMBEDDED setAutoSaveSettings(); qApp->processEvents(); mCore->restoreSettings(); } KAddressBookMain::~KAddressBookMain() { // mCore->saveSettings(); } -#ifndef DESKTOP_VERSION -void KAddressBookMain::show () -{ - static bool block = false; - if( block ) { - QWidget::show(); - return; - } else { - block = true ; - QWidget::showFullScreen(); - } - int min = 20; - if ( QApplication::desktop()->width() > 320 ) - min += 20; - setGeometry( 0,0,QApplication::desktop()->width(), QApplication::desktop()->height() - min ); - block = false; -} -#endif + void KAddressBookMain::showMinimized () { QWidget::showMinimized () ; } void KAddressBookMain::addEmail( QString addr ) { mCore->addEmail( addr ); } #ifndef KAB_EMBEDDED ASYNC KAddressBookMain::showContactEditor( QString uid ) { mCore->editContact( uid ); } #endif //KAB_EMBEDDED void KAddressBookMain::newContact() { mCore->newContact(); } QString KAddressBookMain::getNameByPhone( QString phone ) { return mCore->getNameByPhone( phone ); } void KAddressBookMain::save() { mCore->save(); } void KAddressBookMain::exit() { close( ); } void KAddressBookMain::saveProperties( KConfig* ) { } void KAddressBookMain::readProperties( KConfig* ) { } void KAddressBookMain::initActions() { #ifndef KAB_EMBEDDED KStdAction::quit( this, SLOT( close() ), actionCollection() ); KStdAction::configureToolbars( this, SLOT( configureToolbars() ), actionCollection() ); #else //KAB_EMBEDDED //US: transfered the setup of the actions into KABCore #endif //KAB_EMBEDDED } //US new method to setup menues and toolbars on embedded systems #ifdef KAB_EMBEDDED /* QToolBar * KAddressBookMain::getIconToolBar() { return iconToolBar; } */ void KAddressBookMain::createGUI() { } #endif //KAB_EMBEDDED void KAddressBookMain::configureToolbars() { #ifndef KAB_EMBEDDED saveMainWindowSettings( KGlobal::config(), "MainWindow" ); KEditToolbar dlg( factory() ); connect( &dlg, SIGNAL( newToolbarConfig() ), SLOT( slotNewToolbarConfig() ) ); dlg.exec(); #else //KAB_EMBEDDED qDebug("KAddressBookMain::configureToolbars() not implemented by ulf" ); #endif //KAB_EMBEDDED } void KAddressBookMain::slotNewToolbarConfig() { #ifndef KAB_EMBEDDED applyMainWindowSettings( KGlobal::config(), "MainWindow" ); #else //KAB_EMBEDDED qDebug("KAddressBookMain::slotNewToolbarConfig() not implemented by ulf" ); #endif //KAB_EMBEDDED } void KAddressBookMain::configureKeys() { #ifndef KAB_EMBEDDED KKeyDialog::configureKeys( actionCollection(), xmlFile(), true, this ); #else //KAB_EMBEDDED qDebug("KAddressBookMain::configureKeys() not implemented by ulf" ); #endif //KAB_EMBEDDED } void KAddressBookMain::closeEvent( QCloseEvent* ce ) { QString mess = i18n( "Close KA/Pi?"); if ( mCore->modified() ) mess += i18n( "\n\nChanges will be saved!"); else mess += i18n( "\n\nNo unsaved changes detected!\nNothing will be saved!"); switch( QMessageBox::information( this, "KA/Pi", mess , i18n("Yes!"), i18n("No"), 0, 0 ) ) { case 0: break; case 1: return; break; case 2: return; break; default: return; break; } #if 0 if ( mCore->modified() ) { QString text = i18n( "The address book has been modified.\nDo you want to save your changes?" ); #ifndef KAB_EMBEDDED int ret = KMessageBox::warningYesNoCancel( this, text, "", KStdGuiItem::yes(), KStdGuiItem::no(), "AskForSave" ); switch ( ret ) { case KMessageBox::Yes: save(); break; case KMessageBox::No: return true; break; default: //cancel return ; break; } #else //KAB_EMBEDDED switch( QMessageBox::information( this, "KA/Pi", text, i18n("Yes!"), i18n("No"), 0, 0 ) ) { case 0: save(); break; case 1: break; case 2: return; default: return; break; } #endif //KAB_EMBEDDED } #endif save(); mCore->saveSettings(); KABPrefs::instance()->writeConfig(); ce->accept(); } #ifndef KAB_EMBEDDED #include "kaddressbookmain.moc" #endif //KAB_EMBEDDED diff --git a/kaddressbook/kaddressbookmain.h b/kaddressbook/kaddressbookmain.h index 81ae09c..cf6f899 100644 --- a/kaddressbook/kaddressbookmain.h +++ b/kaddressbook/kaddressbookmain.h @@ -1,126 +1,122 @@ /* This file is part of KAddressbook. Copyright (c) 1999 Don Sanders <dsanders@kde.org> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #ifndef KADDRESSBOOKMAIN_H #define KADDRESSBOOKMAIN_H #include <qptrlist.h> #ifdef KAB_EMBEDDED class QToolBar; #include <qaction.h> //#include <qmainwindow.h> #include <kmainwindow.h> #else //KAB_EMBEDDED #include <kaction.h> #include <kapplication.h> #include <kmainwindow.h> #include "kaddressbookiface.h" #endif //KAB_EMBEDDED class KABCore; class KConfig; /** This class serves as the main window for KAddressBook. It handles the menus, toolbars, and status bars. @short Main window class @author Don Sanders <dsanders@kde.org> @version 0.1 */ #ifdef KAB_EMBEDDED class KAddressBookMain : public KMainWindow #else //KAB_EMBEDDED //MOC_SKIP_BEGIN class KAddressBookMain : public KMainWindow, virtual public KAddressBookIface //MOC_SKIP_END #endif //KAB_EMBEDDED { Q_OBJECT public: KAddressBookMain(); virtual ~KAddressBookMain(); #ifdef KAB_EMBEDDED // QPEToolBar * getIconToolBar(); // QToolBar * getIconToolBar(); #endif //KAB_EMBEDDED public slots: -#ifndef DESKTOP_VERSION - void show(); -#endif - void showMinimized () ; virtual void addEmail( QString addr ); #ifndef KAB_EMBEDDED //MOC_SKIP_BEGIN virtual ASYNC showContactEditor( QString uid ); //MOC_SKIP_END #endif //KAB_EMBEDDED virtual void newContact(); virtual QString getNameByPhone( QString phone ); virtual void save(); virtual void exit(); protected: void initActions(); #ifdef KAB_EMBEDDED //US new method to setup menues and toolbars on embedded systems void createGUI(); #endif //KAB_EMBEDDED /** This function is called when it is time for the app to save its properties for session management purposes. */ void saveProperties( KConfig* ); /** This function is called when this app is restored. The KConfig object points to the session management config file that was saved with @ref saveProperties */ void readProperties( KConfig* ); void closeEvent( QCloseEvent* ce ); protected slots: void configureToolbars(); void configureKeys(); void slotNewToolbarConfig(); private: KABCore *mCore; #ifdef KAB_EMBEDDED // QToolBar *iconToolBar; #endif //KAB_EMBEDDED }; #endif diff --git a/kaddressbook/mainembedded.cpp b/kaddressbook/mainembedded.cpp index ffa37a5..3f6f69d 100644 --- a/kaddressbook/mainembedded.cpp +++ b/kaddressbook/mainembedded.cpp @@ -1,208 +1,204 @@ #ifndef DESKTOP_VERSION #include <qpe/qpeapplication.h> #include <qpe/global.h> #include <stdlib.h> #else #include <qapplication.h> #include <qwindowsstyle.h> #include <qplatinumstyle.h> #include <qmainwindow.h> #endif #include <kstandarddirs.h> #include <kglobal.h> #include <stdio.h> #include <qdir.h> #include "kaddressbookmain.h" int main( int argc, char **argv ) { #ifndef DESKTOP_VERSION QPEApplication a( argc, argv ); a.setKeepRunning (); #else QApplication a( argc, argv ); QApplication::setStyle( new QPlatinumStyle ()); #endif bool exitHelp = false; if ( argc > 1 ) { QString command = argv[1]; if ( command == "-help" ){ printf("KA/E command line commands:\n"); printf(" no command: Start KA/E in usual way\n"); printf(" -help: This output\n"); printf(" KA/E is exiting now. Bye!\n"); exitHelp = true; } } if ( ! exitHelp ) { KGlobal::setAppName( "kaddressbook" ); #ifndef DESKTOP_VERSION KStandardDirs::setAppDir( Global::applicationFileName( "kaddressbook", "" ) ); KGlobal::iconLoader()->setIconPath(QString(getenv("QPEDIR"))+"/pics/kdepim/kaddressbook/icons16/"); #else QString fileName ; #ifndef _WIN32_ fileName = qApp->applicationDirPath () + "/kdepim/kaddressbook/icons16/"; #else fileName = qApp->applicationDirPath () + "\\kdepim\\kaddressbook\\icons16\\"; #endif KGlobal::iconLoader()->setIconPath(fileName); QString appdir = QDir::homeDirPath(); if ( appdir.right(1) == "\\" || appdir.right(1) == "/" ) appdir += "kaddressbook"; else appdir += "/kaddressbook"; KStandardDirs::setAppDir( QDir::convertSeparators( appdir )); // qDebug(" %s ",KStandardDirs::appDir().latin1() ); #endif // desktop QDir app_dir; if ( !app_dir.exists(KStandardDirs::appDir()) ) app_dir.mkdir (KStandardDirs::appDir()); KAddressBookMain* m = new KAddressBookMain(); //US MainWindow m; //US QObject::connect( &a, SIGNAL (appMessage ( const QCString &, const QByteArray & )),&m, SLOT(recieve( const QCString&, const QByteArray& ))); #ifndef DESKTOP_VERSION a.showMainWidget(m ); - m->showFullScreen(); - int min = 20; - if ( QApplication::desktop()->width() > 320 ) - min += 20; - m->setGeometry( 0,0,QApplication::desktop()->width(), QApplication::desktop()->height() - min ); - + m->showMaximized(); + #else a.setMainWidget(m ); m->show(); //m->resize( 640, 480 ); #endif a.exec(); } qDebug("KA: Bye! "); } /* #include <stdlib.h> #include <qstring.h> #include <kabc/stdaddressbook.h> #include <kaboutdata.h> #include <kcmdlineargs.h> #include <kcrash.h> #include <kdebug.h> #include <klocale.h> #include <kstartupinfo.h> #include <kuniqueapplication.h> #include <kwin.h> #include "kaddressbookmain.h" #include "kabcore.h" extern "C" { void crashHandler( int ) { KABC::StdAddressBook::handleCrash(); ::exit( 0 ); } } class KAddressBookApp : public KUniqueApplication { public: KAddressBookApp() : mMainWin( 0 ) {} ~KAddressBookApp() {} int newInstance(); private: KAddressBookMain *mMainWin; }; int KAddressBookApp::newInstance() { if ( isRestored() ) { // There can only be one main window if ( KMainWindow::canBeRestored( 1 ) ) { mMainWin = new KAddressBookMain; mMainWin->show(); mMainWin->restore( 1 ); } } else { KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); QCString addrStr = args->getOption( "addr" ); QCString uidStr = args->getOption( "uid" ); QString addr; QString uid; if ( !addrStr.isEmpty() ) addr = QString::fromLocal8Bit( addrStr ); if ( !uidStr.isEmpty() ) uid = QString::fromLocal8Bit( uidStr ); if ( args->isSet( "editor-only" ) ) { if ( !mMainWin ) mMainWin = new KAddressBookMain; KStartupInfo::appStarted(); mMainWin->hide(); } else { if ( mMainWin ) { mMainWin->show(); KWin::setActiveWindow( mMainWin->winId() ); } else { mMainWin = new KAddressBookMain; mMainWin->show(); } } // Can not see why anyone would pass both a uid and an email address, so I'll leave it that two contact editors will show if they do if ( !addr.isEmpty() ) mMainWin->addEmail( addr ); if ( !uid.isEmpty() ) mMainWin->showContactEditor( uid ); if ( args->isSet( "new-contact" ) ) { mMainWin->newContact(); } } KCrash::setEmergencySaveFunction( crashHandler ); return 0; } // the dummy argument is required, because KMail apparently sends an empty // argument. static KCmdLineOptions kmoptions[] = { { "a", 0 , 0 }, { "addr <email>", I18N_NOOP( "Shows contact editor with given email address" ), 0 }, { "uid <uid>", I18N_NOOP( "Shows contact editor with given uid" ), 0 }, { "editor-only", I18N_NOOP( "Launches in editor only mode" ), 0 }, { "new-contact", I18N_NOOP( "Launches editor for the new contact" ), 0 }, { "+[argument]", I18N_NOOP( "dummy argument" ), 0}, { 0, 0, 0} }; int main( int argc, char *argv[] ) { KLocale::setMainCatalogue( "kaddressbook" ); KCmdLineArgs::init( argc, argv, KABCore::createAboutData() ); KCmdLineArgs::addCmdLineOptions( kmoptions ); KUniqueApplication::addCmdLineOptions(); if ( !KAddressBookApp::start() ) exit( 0 ); KAddressBookApp app; KGlobal::locale()->insertCatalogue( "libkdepim" ); return app.exec(); } */ diff --git a/kdepim.control b/kdepim.control index 116bfef..7098d34 100644 --- a/kdepim.control +++ b/kdepim.control @@ -1,14 +1,14 @@ Files: bin/kopi bin/db2file bin/kapi apps/Pim/korganizer.desktop apps/Pim/kaddressbook.desktop pics/kdepim/* lib/libmicro* Priority: optional Section: qpe/pim Maintainer: Lutz Rogowski <lutz@pi-sync.net> Architecture: arm -Version: 1.9.1 +Version: 1.9.2 License: GPL Depends: Description: KOrganizer/Pi and Kaddressbook/Pi The embedded version of KOrganizer/Platform-independend, the KDE calendar and scheduling program optimized for 640x480 and 320x240 resolution on Zaurus PDA diff --git a/korganizer/calendarview.cpp b/korganizer/calendarview.cpp index 7292dcd..7ac5b11 100644 --- a/korganizer/calendarview.cpp +++ b/korganizer/calendarview.cpp @@ -477,2353 +477,2353 @@ CalendarView::~CalendarView() void CalendarView::timerAlarm() { //qDebug("CalendarView::timerAlarm() "); computeAlarm(mAlarmNotification ); } void CalendarView::suspendAlarm() { //qDebug(" CalendarView::suspendAlarm() "); computeAlarm(mSuspendAlarmNotification ); } void CalendarView::startAlarm( QString mess , QString filename) { mAlarmDialog->eventNotification( mess, KOPrefs::instance()->mAlarmPlayBeeps, filename, true,KOPrefs::instance()->mAlarmBeepInterval ,KOPrefs::instance()->mAlarmSuspendCount ); } void CalendarView::computeAlarm( QString msg ) { QString mess = msg; QString mAlarmMessage = mess.mid( 9 ); QString filename = MainWindow::resourcePath(); filename += "koalarm.wav"; QString tempfilename; if ( mess.left( 13 ) == "suspend_alarm") { bool error = false; int len = mess.mid( 13 ).find("+++"); if ( len < 2 ) error = true; else { tempfilename = mess.mid( 13, len ); if ( !QFile::exists( tempfilename ) ) error = true; } if ( ! error ) { filename = tempfilename; } mAlarmMessage = mess.mid( 13+len+3 ); //qDebug("suspend file %s ",tempfilename.latin1() ); startAlarm( mAlarmMessage, filename); return; } if ( mess.left( 11 ) == "timer_alarm") { //mTimerTime = 0; startAlarm( mess.mid( 11 ), filename ); return; } if ( mess.left( 10 ) == "proc_alarm") { bool error = false; int len = mess.mid( 10 ).find("+++"); if ( len < 2 ) error = true; else { tempfilename = mess.mid( 10, len ); if ( !QFile::exists( tempfilename ) ) error = true; } if ( error ) { mAlarmMessage = "Procedure Alarm\nError - File not found\n"; mAlarmMessage += mess.mid( 10+len+3+9 ); } else { //QCopEnvelope e("QPE/Application/kopi", "-writeFileSilent"); //qDebug("-----system command %s ",tempfilename.latin1() ); #ifndef _WIN32_ if ( vfork () == 0 ) { execl ( tempfilename.latin1(), 0 ); return; } #else QProcess* p = new QProcess(); p->addArgument( tempfilename.latin1() ); p->start(); return; #endif return; } //qDebug("+++++++system command %s ",tempfilename.latin1() ); } if ( mess.left( 11 ) == "audio_alarm") { bool error = false; int len = mess.mid( 11 ).find("+++"); if ( len < 2 ) error = true; else { tempfilename = mess.mid( 11, len ); if ( !QFile::exists( tempfilename ) ) error = true; } if ( ! error ) { filename = tempfilename; } mAlarmMessage = mess.mid( 11+len+3+9 ); //qDebug("audio file command %s ",tempfilename.latin1() ); } if ( mess.left( 9 ) == "cal_alarm") { mAlarmMessage = mess.mid( 9 ) ; } startAlarm( mAlarmMessage, filename ); } void CalendarView::addSuspendAlarm(const QDateTime &qdt, const QString ¬i ) { //qDebug("+++++addSUSPENDAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); mSuspendAlarmNotification = noti; int ms = QDateTime::currentDateTime().secsTo( qdt )*1000; //qDebug("Suspend Alarm timer started with secs: %d ", ms/1000); mSuspendTimer->start( ms , true ); } void CalendarView::addAlarm(const QDateTime &qdt, const QString ¬i ) { //qDebug("+++++addAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { #ifndef DESKTOP_VERSION AlarmServer::addAlarm ( qdt,"koalarm", noti.latin1() ); #endif return; } mAlarmNotification = noti; int ms = QDateTime::currentDateTime().secsTo( qdt )*1000; //qDebug("Alarm timer started with secs: %d ", ms/1000); mAlarmTimer->start( ms , true ); } void CalendarView::removeAlarm(const QDateTime &qdt, const QString ¬i ) { //qDebug("-----removeAlarm %s %s ", qdt.toString().latin1() , noti.latin1() ); if ( ! KOPrefs::instance()->mUseInternalAlarmNotification ) { #ifndef DESKTOP_VERSION AlarmServer::deleteAlarm (qdt ,"koalarm" ,noti.latin1() ); #endif return; } mAlarmTimer->stop(); } void CalendarView::selectWeekNum ( int num ) { dateNavigator()->selectWeek( num ); mViewManager->showWeekView(); } KOViewManager *CalendarView::viewManager() { return mViewManager; } KODialogManager *CalendarView::dialogManager() { return mDialogManager; } QDate CalendarView::startDate() { DateList dates = mNavigator->selectedDates(); return dates.first(); } QDate CalendarView::endDate() { DateList dates = mNavigator->selectedDates(); return dates.last(); } void CalendarView::createPrinter() { #ifndef KORG_NOPRINTER if (!mCalPrinter) { mCalPrinter = new CalPrinter(this, mCalendar); connect(this, SIGNAL(configChanged()), mCalPrinter, SLOT(updateConfig())); } #endif } void CalendarView::confSync() { static KOSyncPrefsDialog* sp = 0; if ( ! sp ) { sp = new KOSyncPrefsDialog( this, "syncprefs", true ); } sp->usrReadConfig(); #ifndef DESKTOP_VERSION sp->showMaximized(); #else sp->show(); #endif sp->exec(); } //KOPrefs::instance()->mWriteBackFile //KOPrefs::instance()->mWriteBackExistingOnly // 0 syncPrefsGroup->addRadio(i18n("Take local entry on conflict")); // 1 syncPrefsGroup->addRadio(i18n("Take remote entry on conflict")); // 2 syncPrefsGroup->addRadio(i18n("Take newest entry on conflict")); // 3 syncPrefsGroup->addRadio(i18n("Ask for every entry on conflict")); // 4 syncPrefsGroup->addRadio(i18n("Force take local entry always")); // 5 syncPrefsGroup->addRadio(i18n("Force take remote entry always")); int CalendarView::takeEvent( Incidence* local, Incidence* remote, int mode , bool full ) { //void setZaurusId(int id); // int zaurusId() const; // void setZaurusUid(int id); // int zaurusUid() const; // void setZaurusStat(int id); // int zaurusStat() const; // 0 equal // 1 take local // 2 take remote // 3 cancel QDateTime lastSync = mLastCalendarSync; if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { bool remCh, locCh; remCh = ( remote->zaurusUid() != local->zaurusUid() ); locCh = ( local->zaurusStat() != local->revision() ); //qDebug("locCh %d remCh %d locuid %d remuid %d", locCh, remCh,local->zaurusUid(), remote->zaurusUid() ); if ( !remCh && ! locCh ) { //qDebug("both not changed "); lastSync = local->lastModified().addDays(1); } else { if ( locCh ) { //qDebug("loc changed %d %d", local->zaurusStat(), local->revision() ); lastSync = local->lastModified().addDays( -1 ); if ( !remCh ) remote->setLastModified( lastSync.addDays( -1 ) ); } else { //qDebug(" not loc changed "); lastSync = local->lastModified().addDays( 1 ); if ( remCh ) remote->setLastModified( lastSync.addDays( 1 ) ); } } full = true; if ( mode < 3 ) mode = 3; } else { if ( local->lastModified() == remote->lastModified() ) if ( local->revision() == remote->revision() ) return 0; } // qDebug(" %d %d conflict on %s %s ", mode, full, local->summary().latin1(), remote->summary().latin1() ); //qDebug("%s %d %s %d", local->lastModified().toString().latin1() , local->revision(), remote->lastModified().toString().latin1(), remote->revision()); //qDebug("%d %d %d %d ", local->lastModified().time().second(), local->lastModified().time().msec(), remote->lastModified().time().second(), remote->lastModified().time().msec() ); //full = true; //debug only if ( full ) { bool equ = false; if ( local->type() == "Event" ) { equ = (*((Event*) local) == *((Event*) remote)); } else if ( local->type() =="Todo" ) equ = (*((Todo*) local) == (*(Todo*) remote)); else if ( local->type() =="Journal" ) equ = (*((Journal*) local) == *((Journal*) remote)); if ( equ ) { //qDebug("equal "); if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { local->setZaurusUid( remote->zaurusUid() ); } if ( mode < 4 ) return 0; }//else //debug only //qDebug("not equal %s %s ", local->summary().latin1(), remote->summary().latin1()); } int result; bool localIsNew; if ( full && mode < 2 ) mode = 3; switch( mode ) { case 0: if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; return 1; break; case 1: if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; return 2; break; case 2: if ( local->lastModified() > remote->lastModified() ) return 1; else return 2; break; case 3: //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); if ( lastSync > remote->lastModified() ) return 1; if ( lastSync > local->lastModified() ) return 2; //qDebug("lsy %s --- lo %s --- re %s ", lastSync.toString().latin1(), local->lastModified().toString().latin1(), remote->lastModified().toString().latin1() ); localIsNew = local->lastModified() > remote->lastModified(); if ( localIsNew ) getEventViewerDialog()->setColorMode( 1 ); else getEventViewerDialog()->setColorMode( 2 ); getEventViewerDialog()->setIncidence(local); if ( localIsNew ) getEventViewerDialog()->setColorMode( 2 ); else getEventViewerDialog()->setColorMode( 1 ); getEventViewerDialog()->addIncidence(remote); getEventViewerDialog()->setColorMode( 0 ); //qDebug("local %d remote %d ",local->relatedTo(),remote->relatedTo() ); getEventViewerDialog()->setCaption( mCurrentSyncDevice +i18n(" : Conflict! Please choose entry!")); getEventViewerDialog()->showMe(); result = getEventViewerDialog()->executeS( localIsNew ); return result; break; case 4: return 1; break; case 5: return 2; break; default: break; } return 0; } Event* CalendarView::getLastSyncEvent() { Event* lse; //qDebug("CurrentSyncDevice %s ",mCurrentSyncDevice .latin1() ); lse = mCalendar->event( "last-syncEvent-device-"+mCurrentSyncDevice ); if (!lse) { lse = new Event(); lse->setUid( "last-syncEvent-device-"+mCurrentSyncDevice ); lse->setSummary(mCurrentSyncDevice + i18n(" - sync event")); lse->setDtStart( mLastCalendarSync ); lse->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); lse->setCategories( i18n("SyncEvent") ); lse->setReadOnly( true ); mCalendar->addEvent( lse ); } return lse; } void CalendarView::checkSharpEvent( Event* lastSync, Incidence* toDelete ) { if ( ! lastSync ) return; if ( toDelete->zaurusId() < 0 ) return; if ( toDelete->type() == "Journal" ) return; QString des = lastSync->description(); QString pref = "e"; if ( toDelete->type() == "Todo" ) pref = "t"; des += pref+ QString::number ( toDelete->zaurusId() ) + ","; lastSync->setReadOnly( false ); lastSync->setDescription( des ); lastSync->setReadOnly( true ); } bool CalendarView::synchronizeCalendar( Calendar* local, Calendar* remote, int mode ) { bool syncOK = true; int addedEvent = 0; int addedEventR = 0; int deletedEventR = 0; int deletedEventL = 0; int changedLocal = 0; int changedRemote = 0; //QPtrList<Event> el = local->rawEvents(); Event* eventR; QString uid; int take; Event* eventL; Event* eventRSync; Event* eventLSync; Event* eventRSyncSharp = remote->event( "last-syncEvent-device-Sharp-DTM"); Event* eventLSyncSharp = local->event( "last-syncEvent-device-Sharp-DTM"); bool fullDateRange = false; mLastCalendarSync = QDateTime::currentDateTime(); QDateTime modifiedCalendar = mLastCalendarSync;; eventR = remote->event("last-syncEvent-device-"+mCurrentSyncName ); if ( eventR ) { eventRSync = (Event*) eventR->clone(); remote->deleteEvent(eventR ); } else { fullDateRange = true; eventRSync = new Event(); eventRSync->setSummary(mCurrentSyncName + i18n(" - sync event")); eventRSync->setUid("last-syncEvent-device-"+mCurrentSyncName ); eventRSync->setDtStart( mLastCalendarSync ); eventRSync->setDtEnd( mLastCalendarSync.addSecs( 7200 ) ); eventRSync->setCategories( i18n("SyncEvent") ); } eventLSync = getLastSyncEvent(); if ( eventLSync->dtStart() == mLastCalendarSync ) fullDateRange = true; if ( ! fullDateRange ) { if ( eventLSync->dtStart() != eventRSync->dtStart() ) { // qDebug("set fulldate to true %s %s" ,eventLSync->dtStart().toString().latin1(), eventRSync->dtStart().toString().latin1() ); //qDebug("%d %d %d %d ", eventLSync->dtStart().time().second(), eventLSync->dtStart().time().msec() , eventRSync->dtStart().time().second(), eventRSync->dtStart().time().msec()); fullDateRange = true; } } if ( fullDateRange ) mLastCalendarSync = QDateTime::currentDateTime().addDays( -100*365); else mLastCalendarSync = eventLSync->dtStart(); // for resyncing if own file has changed if ( mCurrentSyncDevice == "deleteaftersync" ) { mLastCalendarSync = loadedFileVersion; qDebug("setting mLastCalendarSync "); } //qDebug("*************************** "); qDebug("mLastCalendarSync %s ",mLastCalendarSync.toString().latin1() ); QPtrList<Incidence> er = remote->rawIncidences(); Incidence* inR = er.first(); Incidence* inL; QProgressBar bar( er.count(),0 ); bar.setCaption (i18n("Syncing - close to abort!") ); int w = 300; if ( QApplication::desktop()->width() < 320 ) w = 220; int h = bar.sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); bar.show(); int modulo = (er.count()/10)+1; int incCounter = 0; while ( inR ) { if ( ! bar.isVisible() ) return false; if ( incCounter % modulo == 0 ) bar.setProgress( incCounter ); ++incCounter; uid = inR->uid(); bool skipIncidence = false; if ( uid.left(21) == QString("last-syncEvent-device") ) skipIncidence = true; qApp->processEvents(); if ( !skipIncidence ) { inL = local->incidence( uid ); if ( inL ) { // maybe conflict - same uid in both calendars int maxrev = inL->revision(); if ( maxrev < inR->revision() ) maxrev = inR->revision(); if ( (take = takeEvent( inL, inR, mode, fullDateRange )) > 0 ) { //qDebug("take %d %s ", take, inL->summary().latin1()); if ( take == 3 ) return false; if ( take == 1 ) {// take local inL->setZaurusUid( inR->zaurusUid() ); remote->deleteIncidence( inR ); if ( inL->revision() < maxrev ) inL->setRevision( maxrev ); remote->addIncidence( inL->clone() ); ++changedRemote; } else { if ( inR->revision() < maxrev ) inR->setRevision( maxrev ); local->deleteIncidence( inL ); local->addIncidence( inR->clone() ); ++changedLocal; } } } else { // no conflict if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { QString des = eventLSync->description(); QString pref = "e"; if ( inR->type() == "Todo" ) pref = "t"; if ( des.find(pref+QString::number( inR->zaurusId() ) +"," ) >= 0 && mode != 5) { // delete it inR->setZaurusStat( -3 ); //remote->deleteIncidence( inR ); ++deletedEventR; } else { inR->setLastModified( modifiedCalendar ); local->addIncidence( inR->clone() ); ++addedEvent; } } else { if ( inR->lastModified() > mLastCalendarSync || mode == 5 ) { inR->setLastModified( modifiedCalendar ); local->addIncidence( inR->clone() ); ++addedEvent; } else { checkSharpEvent(eventRSyncSharp, inR); remote->deleteIncidence( inR ); ++deletedEventR; } } } } inR = er.next(); } QPtrList<Incidence> el = local->rawIncidences(); inL = el.first(); modulo = (el.count()/10)+1; bar.setCaption (i18n("Add / remove events") ); bar.setTotalSteps ( el.count() ) ; bar.show(); incCounter = 0; while ( inL ) { qApp->processEvents(); if ( ! bar.isVisible() ) return false; if ( incCounter % modulo == 0 ) bar.setProgress( incCounter ); ++incCounter; uid = inL->uid(); bool skipIncidence = false; if ( uid.left(21) == QString("last-syncEvent-device") ) skipIncidence = true; if ( mGlobalSyncMode == SYNC_MODE_SHARP && inL->type() == "Journal" ) skipIncidence = true; if ( !skipIncidence ) { inR = remote->incidence( uid ); if ( ! inR ) { if ( mGlobalSyncMode == SYNC_MODE_SHARP ) { if ( inL->zaurusId() >= 0 && mode != 4 ) { local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { inL->setZaurusId( -1 ); ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } else { if ( inL->lastModified() < mLastCalendarSync && mode != 4 ) { checkSharpEvent(eventLSyncSharp, inL); local->deleteIncidence( inL ); ++deletedEventL; } else { if ( ! KOPrefs::instance()->mWriteBackExistingOnly ) { ++addedEventR; inL->setLastModified( modifiedCalendar ); remote->addIncidence( inL->clone() ); } } } } } inL = el.next(); } bar.hide(); mLastCalendarSync = QDateTime::currentDateTime().addSecs( 1 ); eventLSync->setReadOnly( false ); eventLSync->setDtStart( mLastCalendarSync ); eventRSync->setDtStart( mLastCalendarSync ); eventLSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); eventRSync->setDtEnd( mLastCalendarSync.addSecs( 3600 ) ); eventRSync->setLocation( i18n("Remote from: ")+mCurrentSyncName ) ; eventLSync->setLocation(i18n("Local from: ") + mCurrentSyncName ); eventLSync->setReadOnly( true ); if ( mGlobalSyncMode == SYNC_MODE_NORMAL) remote->addEvent( eventRSync ); QString mes; mes .sprintf( i18n("Synchronization summary:\n\n %d items added to local\n %d items added to remote\n %d items updated on local\n %d items updated on remote\n %d items deleted on local\n %d items deleted on remote\n"),addedEvent, addedEventR, changedLocal, changedRemote, deletedEventL, deletedEventR ); if ( KOPrefs::instance()->mShowSyncSummary ) { KMessageBox::information(this, mes, i18n("KO/Pi Synchronization") ); } qDebug( mes ); mCalendar->checkAlarmForIncidence( 0, true ); return syncOK; } void CalendarView::setSyncDevice( QString s ) { mCurrentSyncDevice= s; } void CalendarView::setSyncName( QString s ) { mCurrentSyncName= s; } bool CalendarView::syncCalendar(QString filename, int mode) { mGlobalSyncMode = SYNC_MODE_NORMAL; CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); FileStorage* storage = new FileStorage( calendar ); bool syncOK = false; storage->setFileName( filename ); // qDebug("loading ... "); if ( storage->load(KOPrefs::instance()->mUseQuicksave) ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, mode ); getEventViewerDialog()->setSyncMode( false ); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { storage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); storage->save(); } } setModified( true ); } delete storage; delete calendar; if ( syncOK ) updateView(); return syncOK; } void CalendarView::syncSharp() { #ifndef DESKTOP_VERSION mGlobalSyncMode = SYNC_MODE_SHARP; //mCurrentSyncDevice = "sharp-DTM"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; SharpFormat sharpFormat; if ( sharpFormat.load( calendar, mCalendar ) ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { QPtrList<Incidence> iL = mCalendar->rawIncidences(); Incidence* inc = iL.first(); while ( inc ) { inc->setZaurusStat( inc->revision () ); inc = iL.next(); } // pending: clean last sync event description sharpFormat.save(calendar); iL = calendar->rawIncidences(); inc = iL.first(); Incidence* loc; while ( inc ) { if ( inc->zaurusStat() == -4 ) { loc = mCalendar->incidence(inc->uid() ); if ( loc ) { loc->setZaurusId( inc->zaurusId() ); loc->setZaurusUid( inc->zaurusUid() ); } } inc = iL.next(); } Incidence* lse = getLastSyncEvent(); if ( lse ) { lse->setReadOnly( false ); lse->setDescription( "" ); lse->setReadOnly( true ); } } } setModified( true ); } else { QString question = i18n("Sorry, the database access\ncommand failed!\n\nNothing synced!\n") ; QMessageBox::information( 0, i18n("KO/Pi Import - ERROR"), question, i18n("Ok")) ; } delete calendar; updateView(); return ;//syncOK; #endif } #include <kabc/stdaddressbook.h> bool CalendarView::importBday() { KABC::StdAddressBook* AddressBook = KABC::StdAddressBook::self( true ); KABC::AddressBook::Iterator it; int count = 0; for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { ++count; } QProgressBar bar(count,0 ); int w = 300; if ( QApplication::desktop()->width() < 320 ) w = 220; int h = bar.sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); bar.setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); bar.show(); bar.setCaption (i18n("Reading addressbook - close to abort!") ); qApp->processEvents(); count = 0; int addCount = 0; KCal::Attendee* a = 0; for( it = AddressBook->begin(); it != AddressBook->end(); ++it ) { if ( ! bar.isVisible() ) return false; bar.setProgress( count++ ); qApp->processEvents(); //qDebug("add BDay %s %s", (*it).realName().latin1(),(*it).birthday().date().toString().latin1() ); if ( (*it).birthday().date().isValid() ){ a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; if ( addAnniversary( (*it).birthday().date(), (*it).assembledName(), a, true ) ) ++addCount; } QDate anni = KGlobal::locale()->readDate( (*it).custom("KADDRESSBOOK", "X-Anniversary" ), "%Y-%m-%d"); if ( anni.isValid() ){ a = new KCal::Attendee( (*it).realName(), (*it).preferredEmail(),false,KCal::Attendee::NeedsAction,KCal::Attendee::ReqParticipant,(*it).uid()) ; if ( addAnniversary( anni, (*it).assembledName(), a, false ) ) ++addCount; } } updateView(); topLevelWidget()->setCaption(QString::number( addCount )+ i18n(" birthdays/anniversaries added!")); return true; } bool CalendarView::addAnniversary( QDate date, QString name, KCal::Attendee* a, bool birthday) { //qDebug("addAnni "); Event * ev = new Event(); if ( a ) { ev->addAttendee( a ); } QString kind; if ( birthday ) kind = i18n( "Birthday" ); else kind = i18n( "Anniversary" ); ev->setSummary( name + " - " + kind ); ev->setOrganizer( "nobody@nowhere" ); ev->setCategories( kind ); ev->setDtStart( QDateTime(date) ); ev->setDtEnd( QDateTime(date) ); ev->setFloats( true ); Recurrence * rec = ev->recurrence(); rec->setYearly(Recurrence::rYearlyMonth,1,-1); rec->addYearlyNum( date.month() ); - if ( !mCalendar->addEventNoDup( ev ) ) { + if ( !mCalendar->addAnniversaryNoDup( ev ) ) { delete ev; return false; } return true; } bool CalendarView::importQtopia( const QString &categories, const QString &datebook, const QString &todolist ) { QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); if ( !categories.isEmpty() ) qtopiaFormat.load( mCalendar, categories ); if ( !datebook.isEmpty() ) qtopiaFormat.load( mCalendar, datebook ); if ( !todolist.isEmpty() ) qtopiaFormat.load( mCalendar, todolist ); updateView(); return true; #if 0 mGlobalSyncMode = SYNC_MODE_QTOPIA; mCurrentSyncDevice = "qtopia-XML"; if ( KOPrefs::instance()->mAskForPreferences ) edit_sync_options(); qApp->processEvents(); CalendarLocal* calendar = new CalendarLocal(); calendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); bool syncOK = false; QtopiaFormat qtopiaFormat; qtopiaFormat.setCategoriesList ( &(KOPrefs::instance()->mCustomCategories)); bool loadOk = true; if ( !categories.isEmpty() ) loadOk = qtopiaFormat.load( calendar, categories ); if ( loadOk && !datebook.isEmpty() ) loadOk = qtopiaFormat.load( calendar, datebook ); if ( loadOk && !todolist.isEmpty() ) loadOk = qtopiaFormat.load( calendar, todolist ); if ( loadOk ) { getEventViewerDialog()->setSyncMode( true ); syncOK = synchronizeCalendar( mCalendar, calendar, KOPrefs::instance()->mSyncAlgoPrefs ); getEventViewerDialog()->setSyncMode( false ); qApp->processEvents(); if ( syncOK ) { if ( KOPrefs::instance()->mWriteBackFile ) { // write back XML file } setModified( true ); } } else { QString question = i18n("Sorry, the file loading\ncommand failed!\n\nNothing synced!\n") ; QMessageBox::information( 0, i18n("KO/Pi Sync - ERROR"), question, i18n("Ok")) ; } delete calendar; updateView(); return syncOK; #endif } void CalendarView::setSyncEventsReadOnly() { Event * ev; QPtrList<Event> eL = mCalendar->rawEvents(); ev = eL.first(); while ( ev ) { if ( ev->uid().left(21) == QString("last-syncEvent-device") ) ev->setReadOnly( true ); ev = eL.next(); } } bool CalendarView::openCalendar(QString filename, bool merge) { if (filename.isEmpty()) { return false; } if (!QFile::exists(filename)) { KMessageBox::error(this,i18n("File does not exist:\n '%1'.").arg(filename)); return false; } globalFlagBlockAgenda = 1; if (!merge) mCalendar->close(); mStorage->setFileName( filename ); if ( mStorage->load(KOPrefs::instance()->mUseQuicksave) ) { if ( merge ) ;//setModified( true ); else { //setModified( true ); mViewManager->setDocumentId( filename ); mDialogManager->setDocumentId( filename ); mTodoList->setDocumentId( filename ); } globalFlagBlockAgenda = 2; // if ( getLastSyncEvent() ) // getLastSyncEvent()->setReadOnly( true ); mCalendar->reInitAlarmSettings(); setSyncEventsReadOnly(); updateUnmanagedViews(); updateView(); if ( filename != MainWindow::defaultFileName() ) saveCalendar( MainWindow::defaultFileName() ); loadedFileVersion = QDateTime::currentDateTime(); return true; } else { // while failing to load, the calendar object could // have become partially populated. Clear it out. if ( !merge ) mCalendar->close(); KMessageBox::error(this,i18n("Couldn't load calendar\n '%1'.").arg(filename)); globalFlagBlockAgenda = 2; updateView(); } return false; } void CalendarView::setLoadedFileVersion(QDateTime dt) { loadedFileVersion = dt; } bool CalendarView::checkFileChanged(QString fn) { QFileInfo finf ( fn ); if ( !finf.exists() ) return true; QDateTime dt = finf.lastModified (); if ( dt <= loadedFileVersion ) return false; return true; } bool CalendarView::checkFileVersion(QString fn) { QFileInfo finf ( fn ); if ( !finf.exists() ) return true; QDateTime dt = finf.lastModified (); //qDebug("loaded file version %s",loadedFileVersion.toString().latin1()); //qDebug("file on disk version %s",dt.toString().latin1()); if ( dt <= loadedFileVersion ) return true; int km = KMessageBox::warningYesNoCancel(this, i18n("\nThe file on disk has changed!\nFile size: %1 bytes.\nLast modified: %2\nDo you want to:\n\n - Save and overwrite file?\n - Sync with file, then save?\n - Cancel without saving? \n").arg( QString::number( finf.size())).arg( KGlobal::locale()->formatDateTime(finf.lastModified (), true, false)) , i18n("KO/Pi Warning"),i18n("Overwrite"), i18n("Sync+save")); if ( km == KMessageBox::Cancel ) return false; if ( km == KMessageBox::Yes ) return true; setSyncDevice("deleteaftersync" ); KOPrefs::instance()->mAskForPreferences = true; KOPrefs::instance()->mSyncAlgoPrefs = 3; KOPrefs::instance()->mWriteBackFile = false; KOPrefs::instance()->mWriteBackExistingOnly = false; KOPrefs::instance()->mShowSyncSummary = false; syncCalendar( fn, 3 ); Event * e = getLastSyncEvent(); mCalendar->deleteEvent ( e ); updateView(); return true; } bool CalendarView::saveCalendar( QString filename ) { // Store back all unsaved data into calendar object // qDebug("file %s %d ", filename.latin1() , mViewManager->currentView() ); if ( mViewManager->currentView() ) mViewManager->currentView()->flushView(); //mStorage->setFileName( filename ); mStorage->setSaveFormat( new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); mStorage->setFileName( filename ); bool success; success = mStorage->save(); if ( !success ) { return false; } return true; } void CalendarView::closeCalendar() { // child windows no longer valid emit closingDown(); mCalendar->close(); setModified(false); updateView(); } void CalendarView::archiveCalendar() { mDialogManager->showArchiveDialog(); } void CalendarView::readSettings() { // mViewManager->showAgendaView(); QString str; //qDebug("CalendarView::readSettings() "); // read settings from the KConfig, supplying reasonable // defaults where none are to be found KConfig *config = KOGlobals::config(); #ifndef KORG_NOSPLITTER config->setGroup("KOrganizer Geometry"); QValueList<int> sizes = config->readIntListEntry("Separator1"); if (sizes.count() != 2) { sizes << mDateNavigator->minimumSizeHint().width(); sizes << 300; } mPanner->setSizes(sizes); sizes = config->readIntListEntry("Separator2"); if ( ( mResourceView && sizes.count() == 4 ) || ( !mResourceView && sizes.count() == 3 ) ) { mLeftSplitter->setSizes(sizes); } #endif globalFlagBlockAgenda = 1; mViewManager->showAgendaView(); //mViewManager->readSettings( config ); mTodoList->restoreLayout(config,QString("Todo Layout")); readFilterSettings(config); config->setGroup( "Views" ); int dateCount = config->readNumEntry( "ShownDatesCount", 7 ); if ( dateCount == 5 ) mNavigator->selectWorkWeek(); else if ( dateCount == 7 ) mNavigator->selectWeek(); else mNavigator->selectDates( dateCount ); // mViewManager->readSettings( config ); updateConfig(); globalFlagBlockAgenda = 2; mViewManager->readSettings( config ); #ifdef DESKTOP_VERSION config->setGroup("WidgetLayout"); QStringList list; list = config->readListEntry("MainLayout"); int x,y,w,h; if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); topLevelWidget()->setGeometry(x,y,w,h); } else { topLevelWidget()->setGeometry( 40 ,40 , 640, 440); } list = config->readListEntry("EditEventLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); mEventEditor->setGeometry(x,y,w,h); } list = config->readListEntry("EditTodoLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); mTodoEditor->setGeometry(x,y,w,h); } list = config->readListEntry("ViewerLayout"); if ( ! list.isEmpty() ) { x = list[0].toInt(); y = list[1].toInt(); w = list[2].toInt(); h = list[3].toInt(); getEventViewerDialog()->setGeometry(x,y,w,h); } #endif // pending read sync settings; mSyncProfileNames.clear(); mSyncProfileNames << "Profile_1"; mSyncProfileNames << "Profile_2"; mSyncProfileNames << "Profile_3"; mSyncProfileNames << "Profile_4"; mSyncProfileNames << "Profile_5"; KSyncProfile* temp = new KSyncProfile (); temp->setName("Profile_1" ); mSyncProfiles.append( temp ); temp = new KSyncProfile (); temp->setName("Profile_2" ); mSyncProfiles.append( temp ); temp = new KSyncProfile (); temp->setName("Profile_3" ); mSyncProfiles.append( temp ); temp = new KSyncProfile (); temp->setName("Profile_4" ); mSyncProfiles.append( temp ); temp = new KSyncProfile (); temp->setName("Profile_5" ); mSyncProfiles.append( temp ); } void CalendarView::writeSettings() { // kdDebug() << "CalendarView::writeSettings" << endl; KConfig *config = KOGlobals::config(); #ifndef KORG_NOSPLITTER config->setGroup("KOrganizer Geometry"); QValueList<int> list = mPanner->sizes(); config->writeEntry("Separator1",list); list = mLeftSplitter->sizes(); config->writeEntry("Separator2",list); #endif mViewManager->writeSettings( config ); mTodoList->saveLayout(config,QString("Todo Layout")); mDialogManager->writeSettings( config ); //KOPrefs::instance()->usrWriteConfig(); KOPrefs::instance()->writeConfig(); writeFilterSettings(config); config->setGroup( "Views" ); config->writeEntry( "ShownDatesCount", mNavigator->selectedDates().count() ); #ifdef DESKTOP_VERSION config->setGroup("WidgetLayout"); QStringList list ;//= config->readListEntry("MainLayout"); int x,y,w,h; QWidget* wid; wid = topLevelWidget(); x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("MainLayout",list ); wid = mEventEditor; x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("EditEventLayout",list ); wid = mTodoEditor; x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("EditTodoLayout",list ); wid = getEventViewerDialog(); x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("ViewerLayout",list ); wid = mDialogManager->getSearchDialog(); if ( wid ) { x = wid->geometry().x(); y = wid->geometry().y(); w = wid->width(); h = wid->height(); list.clear(); list << QString::number( x ); list << QString::number( y ); list << QString::number( w ); list << QString::number( h ); config->writeEntry("SearchLayout",list ); } #endif config->sync(); } void CalendarView::readFilterSettings(KConfig *config) { // kdDebug() << "CalendarView::readFilterSettings()" << endl; mFilters.clear(); config->setGroup("General"); QStringList filterList = config->readListEntry("CalendarFilters"); QStringList::ConstIterator it = filterList.begin(); QStringList::ConstIterator end = filterList.end(); while(it != end) { // kdDebug() << " filter: " << (*it) << endl; CalFilter *filter; filter = new CalFilter(*it); config->setGroup("Filter_" + (*it)); //qDebug("readFilterSettings %d ",config->readNumEntry("Criteria",0) ); filter->setCriteria(config->readNumEntry("Criteria",0)); filter->setCategoryList(config->readListEntry("CategoryList")); mFilters.append(filter); ++it; } if (mFilters.count() == 0) { CalFilter *filter = new CalFilter(i18n("Default")); mFilters.append(filter); } mFilterView->updateFilters(); config->setGroup("FilterView"); mFilterView->blockSignals(true); mFilterView->setFiltersEnabled(config->readBoolEntry("FilterEnabled")); mFilterView->setSelectedFilter(config->readEntry("Current Filter")); mFilterView->blockSignals(false); // We do it manually to avoid it being done twice by the above calls updateFilter(); } void CalendarView::writeFilterSettings(KConfig *config) { // kdDebug() << "CalendarView::writeFilterSettings()" << endl; QStringList filterList; CalFilter *filter = mFilters.first(); while(filter) { // kdDebug() << " fn: " << filter->name() << endl; filterList << filter->name(); config->setGroup("Filter_" + filter->name()); config->writeEntry("Criteria",filter->criteria()); config->writeEntry("CategoryList",filter->categoryList()); filter = mFilters.next(); } config->setGroup("General"); config->writeEntry("CalendarFilters",filterList); config->setGroup("FilterView"); config->writeEntry("FilterEnabled",mFilterView->filtersEnabled()); config->writeEntry("Current Filter",mFilterView->selectedFilter()->name()); } void CalendarView::goToday() { mNavigator->selectToday(); } void CalendarView::goNext() { mNavigator->selectNext(); } void CalendarView::goPrevious() { mNavigator->selectPrevious(); } void CalendarView::goNextMonth() { mNavigator->selectNextMonth(); } void CalendarView::goPreviousMonth() { mNavigator->selectPreviousMonth(); } void CalendarView::writeLocale() { KGlobal::locale()->setHore24Format( !KOPrefs::instance()->mPreferredTime ); KGlobal::locale()->setWeekStartMonday( !KOPrefs::instance()->mWeekStartsOnSunday ); KGlobal::locale()->setIntDateFormat( KOPrefs::instance()->mPreferredDate ); KGlobal::locale()->setLanguage( KOPrefs::instance()->mPreferredLanguage ); QString dummy = KOPrefs::instance()->mUserDateFormatLong; KGlobal::locale()->setDateFormat(dummy.replace( QRegExp("K"), QString(",") )); dummy = KOPrefs::instance()->mUserDateFormatShort; KGlobal::locale()->setDateFormatShort(dummy.replace( QRegExp("K"), QString(",") )); KGlobal::locale()->setDaylightSaving( KOPrefs::instance()->mUseDaylightsaving, KOPrefs::instance()->mDaylightsavingStart, KOPrefs::instance()->mDaylightsavingEnd ); KGlobal::locale()->setTimezone( KOPrefs::instance()->mTimeZoneId ); } void CalendarView::updateConfig() { writeLocale(); if ( KOPrefs::instance()->mUseAppColors ) QApplication::setPalette( QPalette (KOPrefs::instance()->mAppColor1, KOPrefs::instance()->mAppColor2), true ); emit configChanged(); mTodoList->updateConfig(); // mDateNavigator->setFont ( KOPrefs::instance()->mDateNavigatorFont); mCalendar->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); // To make the "fill window" configurations work //mViewManager->raiseCurrentView(); } void CalendarView::eventChanged(Event *event) { changeEventDisplay(event,KOGlobals::EVENTEDITED); //updateUnmanagedViews(); } void CalendarView::eventAdded(Event *event) { changeEventDisplay(event,KOGlobals::EVENTADDED); } void CalendarView::eventToBeDeleted(Event *) { kdDebug() << "CalendarView::eventToBeDeleted(): to be implemented" << endl; } void CalendarView::eventDeleted() { changeEventDisplay(0,KOGlobals::EVENTDELETED); } void CalendarView::changeTodoDisplay(Todo *which, int action) { changeIncidenceDisplay((Incidence *)which, action); } void CalendarView::checkZaurusId( int id, bool todo ) { if ( id >= 0 ) { Incidence* lse = mCalendar->event( "last-syncEvent-device-Sharp-DTM"); if ( lse ) { QString des = lse->description(); QString pref = "e"; if ( todo ) pref = "t"; des += pref+ QString::number ( id ) + ","; lse->setReadOnly( false ); lse->setDescription( des ); lse->setReadOnly( true ); } } } void CalendarView::changeIncidenceDisplay(Incidence *which, int action) { updateUnmanagedViews(); //qDebug(" CalendarView::changeIncidenceDisplay++++++++++++++++++++++++++ %d %d ",which, action ); if ( action == KOGlobals::EVENTDELETED ) { //delete mCalendar->checkAlarmForIncidence( 0, true ); if ( mEventViewerDialog ) mEventViewerDialog->hide(); } else mCalendar->checkAlarmForIncidence( which , false ); } // most of the changeEventDisplays() right now just call the view's // total update mode, but they SHOULD be recoded to be more refresh-efficient. void CalendarView::changeEventDisplay(Event *which, int action) { // kdDebug() << "CalendarView::changeEventDisplay" << endl; changeIncidenceDisplay((Incidence *)which, action); mDateNavigator->updateView(); //mDialogManager->updateSearchDialog(); if (which) { // If there is an event view visible update the display mViewManager->currentView()->changeEventDisplay(which,action); // TODO: check, if update needed // if (which->getTodoStatus()) { mTodoList->updateView(); // } } else { mViewManager->currentView()->updateView(); } } void CalendarView::updateTodoViews() { mTodoList->updateView(); mViewManager->currentView()->updateView(); } void CalendarView::updateView(const QDate &start, const QDate &end) { mTodoList->updateView(); mViewManager->updateView(start, end); //mDateNavigator->updateView(); } void CalendarView::updateView() { DateList tmpList = mNavigator->selectedDates(); // We assume that the navigator only selects consecutive days. updateView( tmpList.first(), tmpList.last() ); } void CalendarView::updateUnmanagedViews() { mDateNavigator->updateDayMatrix(); } int CalendarView::msgItemDelete() { return KMessageBox::warningContinueCancel(this, i18n("This item will be\npermanently deleted."), i18n("KO/Pi Confirmation"),i18n("Delete")); } void CalendarView::edit_cut() { Event *anEvent=0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } DndFactory factory( mCalendar ); factory.cutEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); } void CalendarView::edit_copy() { Event *anEvent=0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } DndFactory factory( mCalendar ); factory.copyEvent(anEvent); } void CalendarView::edit_paste() { QDate date = mNavigator->selectedDates().first(); DndFactory factory( mCalendar ); Event *pastedEvent = factory.pasteEvent( date ); changeEventDisplay( pastedEvent, KOGlobals::EVENTADDED ); } void CalendarView::edit_options() { mDialogManager->showOptionsDialog(); //writeSettings(); } void CalendarView::edit_sync_options() { //mDialogManager->showSyncOptions(); //KOPrefs::instance()->mSyncAlgoPrefs QDialog dia( this, "dia", true ); dia.setCaption( i18n("Device: " ) +mCurrentSyncDevice ); QButtonGroup gr ( 1, Qt::Horizontal, i18n("Sync preferences"), &dia); QVBoxLayout lay ( &dia ); lay.setSpacing( 2 ); lay.setMargin( 3 ); lay.addWidget(&gr); QRadioButton loc ( i18n("Take local entry on conflict"), &gr ); QRadioButton rem ( i18n("Take remote entry on conflict"), &gr ); QRadioButton newest( i18n("Take newest entry on conflict"), &gr ); QRadioButton ask( i18n("Ask for every entry on conflict"), &gr ); QRadioButton f_loc( i18n("Force: Take local entry always"), &gr ); QRadioButton f_rem( i18n("Force: Take remote entry always"), &gr ); //QRadioButton both( i18n("Take both on conflict"), &gr ); QPushButton pb ( "OK", &dia); lay.addWidget( &pb ); connect(&pb, SIGNAL( clicked() ), &dia, SLOT ( accept() ) ); switch ( KOPrefs::instance()->mSyncAlgoPrefs ) { case 0: loc.setChecked( true); break; case 1: rem.setChecked( true ); break; case 2: newest.setChecked( true); break; case 3: ask.setChecked( true); break; case 4: f_loc.setChecked( true); break; case 5: f_rem.setChecked( true); break; case 6: // both.setChecked( true); break; default: break; } if ( dia.exec() ) { KOPrefs::instance()->mSyncAlgoPrefs = rem.isChecked()*1+newest.isChecked()*2+ ask.isChecked()*3+ f_loc.isChecked()*4+ f_rem.isChecked()*5;//+ both.isChecked()*6 ; } } void CalendarView::slotSelectPickerDate( QDate d) { mDateFrame->hide(); if ( mDatePickerMode == 1 ) { mNavigator->slotDaySelect( d ); } else if ( mDatePickerMode == 2 ) { if ( mMoveIncidence->type() == "Todo" ) { Todo * to = (Todo *) mMoveIncidence; QTime tim; if ( to->hasDueDate() ) tim = to->dtDue().time(); else { tim = QTime ( 0,0,0 ); to->setFloats( true ); to->setHasDueDate( true ); } QDateTime dt ( d,tim ); to->setDtDue( dt ); todoChanged( to ); } else { QTime tim = mMoveIncidence->dtStart().time(); int secs = mMoveIncidence->dtStart().secsTo( mMoveIncidence->dtEnd()); QDateTime dt ( d,tim ); mMoveIncidence->setDtStart( dt ); ((Event*)mMoveIncidence)->setDtEnd( dt.addSecs( secs ) ); changeEventDisplay((Event*)mMoveIncidence, KOGlobals::EVENTEDITED); } mMoveIncidence->setRevision( mMoveIncidence->revision()+1 ); } } void CalendarView::removeCategories() { QPtrList<Incidence> incList = mCalendar->rawIncidences(); QStringList catList = KOPrefs::instance()->mCustomCategories; QStringList catIncList; QStringList newCatList; Incidence* inc = incList.first(); int i; int count = 0; while ( inc ) { newCatList.clear(); - catIncList = QStringList::split (",", inc->categoriesStr() ); + catIncList = inc->categories() ; for( i = 0; i< catIncList.count(); ++i ) { if ( catList.contains (catIncList[i])) newCatList.append( catIncList[i] ); } newCatList.sort(); inc->setCategories( newCatList.join(",") ); inc = incList.next(); } } int CalendarView::addCategories() { QPtrList<Incidence> incList = mCalendar->rawIncidences(); QStringList catList = KOPrefs::instance()->mCustomCategories; QStringList catIncList; Incidence* inc = incList.first(); int i; int count = 0; while ( inc ) { - catIncList = QStringList::split (",", inc->categoriesStr() ); + catIncList = inc->categories() ; for( i = 0; i< catIncList.count(); ++i ) { if ( !catList.contains (catIncList[i])) { catList.append( catIncList[i] ); //qDebug("add cat %s ", catIncList[i].latin1()); ++count; } } inc = incList.next(); } catList.sort(); KOPrefs::instance()->mCustomCategories = catList; return count; } void CalendarView::manageCategories() { KOCatPrefs* cp = new KOCatPrefs(); cp->show(); int w =cp->sizeHint().width() ; int h = cp->sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); cp->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); if ( !cp->exec() ) { delete cp; return; } int count = 0; if ( cp->addCat() ) { count = addCategories(); if ( count ) { topLevelWidget()->setCaption(QString::number( count )+ i18n(" Categories added to list! ")); writeSettings(); } } else { removeCategories(); updateView(); } delete cp; } void CalendarView::beamIncidence(Incidence * Inc) { QPtrList<Incidence> delSel ; delSel.append(Inc); beamIncidenceList( delSel ); } void CalendarView::beamCalendar() { QPtrList<Incidence> delSel = mCalendar->rawIncidences(); //qDebug("beamCalendar() "); beamIncidenceList( delSel ); } void CalendarView::beamFilteredCalendar() { QPtrList<Incidence> delSel = mCalendar->incidences(); //qDebug("beamFilteredCalendar() "); beamIncidenceList( delSel ); } void CalendarView::beamIncidenceList(QPtrList<Incidence> delSel ) { if ( beamDialog->exec () == QDialog::Rejected ) return; QString fn = "/tmp/kopibeamfile"; QString mes; bool createbup = true; if ( createbup ) { QString description = "\n"; CalendarLocal* cal = new CalendarLocal(); if ( beamDialog->beamLocal() ) cal->setLocalTime(); else cal->setTimeZoneId(KOPrefs::instance()->mTimeZoneId); Incidence *incidence = delSel.first(); bool addText = false; if ( delSel.count() < 10 ) addText = true; else { description.sprintf(i18n(" %d items?"),delSel.count() ); } while ( incidence ) { Incidence *in = incidence->clone(); if ( addText ) description += in->summary() + "\n"; cal->addIncidence( in ); incidence = delSel.next(); } if ( beamDialog->beamVcal() ) { fn += ".vcs"; FileStorage storage( cal, fn, new VCalFormat ); storage.save(); } else { fn += ".ics"; FileStorage storage( cal, fn, new ICalFormat( KOPrefs::instance()->mUseQuicksave) ); storage.save(); } delete cal; mes = i18n("KO/Pi: Ready for beaming"); setCaption(mes); #ifndef DESKTOP_VERSION Ir *ir = new Ir( this ); connect( ir, SIGNAL( done( Ir * ) ), this, SLOT( beamDone( Ir * ) ) ); ir->send( fn, description, "text/x-vCalendar" ); #endif } } void CalendarView::beamDone( Ir *ir ) { #ifndef DESKTOP_VERSION delete ir; #endif } void CalendarView::moveIncidence(Incidence * inc ) { if ( !inc ) return; // qDebug("showDatePickerForIncidence( ) "); if ( mDateFrame->isVisible() ) mDateFrame->hide(); else { int w =mDatePicker->sizeHint().width()+2*mDateFrame->lineWidth() ; int h = mDatePicker->sizeHint().height()+2*mDateFrame->lineWidth() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); mDateFrame->show(); } mDatePickerMode = 2; mMoveIncidence = inc ; QDate da; if ( mMoveIncidence->type() == "Todo" ) { Todo * to = (Todo *) mMoveIncidence; if ( to->hasDueDate() ) da = to->dtDue().date(); else da = QDate::currentDate(); } else { da = mMoveIncidence->dtStart().date(); } mDatePicker->setDate( da ); } void CalendarView::showDatePicker( ) { //qDebug("CalendarView::showDatePicker( ) "); if ( mDateFrame->isVisible() ) mDateFrame->hide(); else { int w =mDatePicker->sizeHint().width() ; int h = mDatePicker->sizeHint().height() ; int dw = QApplication::desktop()->width(); int dh = QApplication::desktop()->height(); mDateFrame->setGeometry( (dw-w)/2, (dh - h )/2 ,w,h ); mDateFrame->show(); } mDatePickerMode = 1; mDatePicker->setDate( mNavigator->selectedDates().first() ); } void CalendarView::showEventEditor() { #ifdef DESKTOP_VERSION mEventEditor->show(); #else mEventEditor->showMaximized(); #endif } void CalendarView::showTodoEditor() { #ifdef DESKTOP_VERSION mTodoEditor->show(); #else mTodoEditor->showMaximized(); #endif } void CalendarView::cancelIncidence(Incidence * inc ) { inc->setCancelled( ! inc->cancelled() ); changeIncidenceDisplay( inc,KOGlobals::EVENTEDITED ); updateView(); } void CalendarView::cloneIncidence(Incidence * orgInc ) { Incidence * newInc = orgInc->clone(); newInc->recreate(); if ( newInc->type() == "Todo" ) { Todo* t = (Todo*) newInc; mTodoEditor->editTodo( t ); showTodoEditor(); if ( mTodoEditor->exec() ) { mCalendar->addTodo( t ); updateView(); } else { delete t; } } else { Event* e = (Event*) newInc; mEventEditor->editEvent( e ); showEventEditor(); if ( mEventEditor->exec() ) { mCalendar->addEvent( e ); updateView(); } else { delete e; } } } void CalendarView::newEvent() { // TODO: Replace this code by a common eventDurationHint of KOBaseView. KOAgendaView *aView = mViewManager->agendaView(); if (aView) { if (aView->selectionStart().isValid()) { if (aView->selectedIsAllDay()) { newEvent(aView->selectionStart(),aView->selectionEnd(),true); } else { newEvent(aView->selectionStart(),aView->selectionEnd()); } return; } } QDate date = mNavigator->selectedDates().first(); QDateTime current = QDateTime::currentDateTime(); if ( date <= current.date() ) { int hour = current.time().hour() +1; newEvent( QDateTime( current.date(), QTime( hour, 0, 0 ) ), QDateTime( current.date(), QTime( hour+ KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); } else newEvent( QDateTime( date, QTime( KOPrefs::instance()->mStartTime, 0, 0 ) ), QDateTime( date, QTime( KOPrefs::instance()->mStartTime + KOPrefs::instance()->mDefaultDuration, 0, 0 ) ) ); } void CalendarView::newEvent(QDateTime fh) { newEvent(fh, QDateTime(fh.addSecs(3600*KOPrefs::instance()->mDefaultDuration))); } void CalendarView::newEvent(QDate dt) { newEvent(QDateTime(dt, QTime(0,0,0)), QDateTime(dt, QTime(0,0,0)), true); } void CalendarView::newEvent(QDateTime fromHint, QDateTime toHint, bool allDay) { mEventEditor->newEvent(fromHint,toHint,allDay); if ( mFilterView->filtersEnabled() ) { CalFilter *filter = mFilterView->selectedFilter(); if (filter && filter->showCategories()) { mEventEditor->setCategories(filter->categoryList().join(",") ); } if ( filter ) mEventEditor->setSecrecy( filter->getSecrecy() ); } showEventEditor(); } void CalendarView::todoAdded(Todo * t) { changeTodoDisplay ( t ,KOGlobals::EVENTADDED); updateTodoViews(); } void CalendarView::todoChanged(Todo * t) { emit todoModified( t, 4 ); // updateTodoViews(); } void CalendarView::todoToBeDeleted(Todo *) { //qDebug("todoToBeDeleted(Todo *) "); updateTodoViews(); } void CalendarView::todoDeleted() { //qDebug(" todoDeleted()"); updateTodoViews(); } void CalendarView::newTodo() { mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),0,true); if ( mFilterView->filtersEnabled() ) { CalFilter *filter = mFilterView->selectedFilter(); if (filter && filter->showCategories()) { mTodoEditor->setCategories(filter->categoryList().join(",") ); } if ( filter ) mTodoEditor->setSecrecy( filter->getSecrecy() ); } showTodoEditor(); } void CalendarView::newSubTodo() { Todo *todo = selectedTodo(); if ( todo ) newSubTodo( todo ); } void CalendarView::newSubTodo(Todo *parentEvent) { mTodoEditor->newTodo(QDateTime::currentDateTime().addDays(7),parentEvent,true); showTodoEditor(); } void CalendarView::newFloatingEvent() { DateList tmpList = mNavigator->selectedDates(); QDate date = tmpList.first(); newEvent( QDateTime( date, QTime( 12, 0, 0 ) ), QDateTime( date, QTime( 12, 0, 0 ) ), true ); } void CalendarView::editEvent( Event *event ) { if ( !event ) return; if ( event->isReadOnly() ) { showEvent( event ); return; } mEventEditor->editEvent( event , mFlagEditDescription); showEventEditor(); } void CalendarView::editJournal( Journal *jour ) { if ( !jour ) return; mDialogManager->hideSearchDialog(); mViewManager->showJournalView(); mNavigator->slotDaySelect( jour->dtStart().date() ); } void CalendarView::editTodo( Todo *todo ) { if ( !todo ) return; if ( todo->isReadOnly() ) { showTodo( todo ); return; } mTodoEditor->editTodo( todo ,mFlagEditDescription); showTodoEditor(); } KOEventViewerDialog* CalendarView::getEventViewerDialog() { if ( !mEventViewerDialog ) { mEventViewerDialog = new KOEventViewerDialog(this); connect( mEventViewerDialog, SIGNAL( editIncidence( Incidence* )), this, SLOT(editIncidence( Incidence* ) ) ); connect( this, SIGNAL(configChanged()), mEventViewerDialog, SLOT(updateConfig())); connect( mEventViewerDialog, SIGNAL(jumpToTime( const QDate &)), dateNavigator(), SLOT( selectWeek( const QDate & ) ) ); connect( mEventViewerDialog, SIGNAL(showAgendaView( bool ) ), viewManager(), SLOT( showAgendaView( bool ) ) ); mEventViewerDialog->resize( 640, 480 ); } return mEventViewerDialog; } void CalendarView::showEvent(Event *event) { getEventViewerDialog()->setEvent(event); getEventViewerDialog()->showMe(); } void CalendarView::showTodo(Todo *event) { getEventViewerDialog()->setTodo(event); getEventViewerDialog()->showMe(); } void CalendarView::showJournal( Journal *jour ) { getEventViewerDialog()->setJournal(jour); getEventViewerDialog()->showMe(); } // void CalendarView::todoModified (Todo *event, int changed) // { // // if (mDialogList.find (event) != mDialogList.end ()) { // // kdDebug() << "Todo modified and open" << endl; // // KOTodoEditor* temp = (KOTodoEditor *) mDialogList[event]; // // temp->modified (changed); // // } // mViewManager->updateView(); // } void CalendarView::appointment_show() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } showEvent(anEvent); } void CalendarView::appointment_edit() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } editEvent(anEvent); } void CalendarView::appointment_delete() { Event *anEvent = 0; Incidence *incidence = mViewManager->currentView()->selectedIncidences().first(); if (mViewManager->currentView()->isEventView()) { if ( incidence && incidence->type() == "Event" ) { anEvent = static_cast<Event *>(incidence); } } if (!anEvent) { KNotifyClient::beep(); return; } deleteEvent(anEvent); } void CalendarView::todo_unsub(Todo *anTodo ) { // Todo *anTodo = selectedTodo(); if (!anTodo) return; if (!anTodo->relatedTo()) return; anTodo->relatedTo()->removeRelation(anTodo); anTodo->setRelatedTo(0); anTodo->updated(); anTodo->setRelatedToUid(""); setModified(true); updateView(); } void CalendarView::deleteTodo(Todo *todo) { if (!todo) { KNotifyClient::beep(); return; } if (KOPrefs::instance()->mConfirm) { switch (msgItemDelete()) { case KMessageBox::Continue: // OK if (!todo->relations().isEmpty()) { KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), i18n("Delete To-Do")); } else { checkZaurusId( todo->zaurusId(), true ); calendar()->deleteTodo(todo); changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); updateView(); } break; } // switch } else { if (!todo->relations().isEmpty()) { KMessageBox::sorry(this,i18n("Cannot delete To-Do\nwhich has children."), i18n("Delete To-Do")); } else { checkZaurusId( todo->zaurusId(), true ); mCalendar->deleteTodo(todo); changeTodoDisplay( todo,KOGlobals::EVENTDELETED ); updateView(); } } emit updateSearchDialog(); } void CalendarView::deleteJournal(Journal *jour) { if (!jour) { KNotifyClient::beep(); return; } if (KOPrefs::instance()->mConfirm) { switch (msgItemDelete()) { case KMessageBox::Continue: // OK calendar()->deleteJournal(jour); updateView(); break; } // switch } else { calendar()->deleteJournal(jour);; updateView(); } emit updateSearchDialog(); } void CalendarView::deleteEvent(Event *anEvent) { if (!anEvent) { KNotifyClient::beep(); return; } if (anEvent->recurrence()->doesRecur()) { QDate itemDate = mViewManager->currentSelectionDate(); int km; if (!itemDate.isValid()) { //kdDebug() << "Date Not Valid" << endl; if (KOPrefs::instance()->mConfirm) { km = KMessageBox::warningContinueCancel(this,anEvent->summary() + i18n("\nThis event recurs\nover multiple dates.\nAre you sure you want\nto delete this event\nand all its recurrences?"), i18n("KO/Pi Confirmation"),i18n("Delete All")); if ( km == KMessageBox::Continue ) km = KMessageBox::No; // No = all below } else km = KMessageBox::No; } else { km = KMessageBox::warningYesNoCancel(this,anEvent->summary() + i18n("\nThis event recurs\nover multiple dates.\nDo you want to delete\nall it's recurrences,\nor only the current one on:\n")+ KGlobal::locale()->formatDate(itemDate)+i18n(" ?\n\nDelete:\n"), i18n("KO/Pi Confirmation"),i18n("Current"), i18n("All")); } switch(km) { case KMessageBox::No: // Continue // all //qDebug("KMessageBox::No "); if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkZaurusId( anEvent->zaurusId()); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent,KOGlobals::EVENTDELETED); break; // Disabled because it does not work //#if 0 case KMessageBox::Yes: // just this one //QDate qd = mNavigator->selectedDates().first(); //if (!qd.isValid()) { // kdDebug() << "no date selected, or invalid date" << endl; // KNotifyClient::beep(); // return; //} //while (!anEvent->recursOn(qd)) qd = qd.addDays(1); if (itemDate!=QDate(1,1,1) || itemDate.isValid()) { anEvent->addExDate(itemDate); int duration = anEvent->recurrence()->duration(); if ( duration > 0 ) { anEvent->recurrence()->setDuration( duration - 1 ); } changeEventDisplay(anEvent, KOGlobals::EVENTEDITED); } break; //#endif } // switch } else { if (KOPrefs::instance()->mConfirm) { switch (KMessageBox::warningContinueCancel(this,anEvent->summary() + i18n("\nAre you sure you want\nto delete this event?"), i18n("KO/Pi Confirmation"),i18n("Delete"))) { case KMessageBox::Continue: // OK if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkZaurusId( anEvent->zaurusId()); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); break; } // switch } else { if (anEvent->organizer()==KOPrefs::instance()->email() && anEvent->attendeeCount()>0) schedule(Scheduler::Cancel,anEvent); checkZaurusId( anEvent->zaurusId()); mCalendar->deleteEvent(anEvent); changeEventDisplay(anEvent, KOGlobals::EVENTDELETED); } } // if-else emit updateSearchDialog(); } bool CalendarView::deleteEvent(const QString &uid) { Event *ev = mCalendar->event(uid); if (ev) { deleteEvent(ev); return true; } else { return false; } } /*****************************************************************************/ void CalendarView::action_mail() { #ifndef KORG_NOMAIL KOMailClient mailClient; Incidence *incidence = currentSelection(); if (!incidence) { KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); return; } if(incidence->attendeeCount() == 0 ) { KMessageBox::sorry(this, i18n("Can't generate mail:\nNo attendees defined.\n")); return; } CalendarLocal cal_tmp; Event *event = 0; Event *ev = 0; if ( incidence && incidence->type() == "Event" ) { event = static_cast<Event *>(incidence); ev = new Event(*event); cal_tmp.addEvent(ev); } ICalFormat mForm( KOPrefs::instance()->mUseQuicksave); QString attachment = mForm.toString( &cal_tmp ); if (ev) delete(ev); mailClient.mailAttendees(currentSelection(), attachment); #endif #if 0 Event *anEvent = 0; if (mViewManager->currentView()->isEventView()) { anEvent = dynamic_cast<Event *>((mViewManager->currentView()->selectedIncidences()).first()); } if (!anEvent) { KMessageBox::sorry(this,i18n("Can't generate mail:\nNo event selected.")); return; } if(anEvent->attendeeCount() == 0 ) { KMessageBox::sorry(this, i18n("Can't generate mail:\nNo attendees defined.\n")); return; } mailobject.emailEvent(anEvent); #endif } void CalendarView::schedule_publish(Incidence *incidence) { Event *event = 0; Todo *todo = 0; if (incidence == 0) { incidence = mViewManager->currentView()->selectedIncidences().first(); if (incidence == 0) { incidence = mTodoList->selectedIncidences().first(); } } if ( incidence && incidence->type() == "Event" ) { event = static_cast<Event *>(incidence); } else { if ( incidence && incidence->type() == "Todo" ) { todo = static_cast<Todo *>(incidence); } } if (!event && !todo) { KMessageBox::sorry(this,i18n("No event selected.")); return; } PublishDialog *publishdlg = new PublishDialog(); if (incidence->attendeeCount()>0) { QPtrList<Attendee> attendees = incidence->attendees(); attendees.first(); while ( attendees.current()!=0 ) { publishdlg->addAttendee(attendees.current()); attendees.next(); } } bool send = true; if ( KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail ) { if ( publishdlg->exec() != QDialog::Accepted ) send = false; } if ( send ) { OutgoingDialog *dlg = mDialogManager->outgoingDialog(); if ( event ) { Event *ev = new Event(*event); ev->registerObserver(0); ev->clearAttendees(); if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { delete(ev); } } else { if ( todo ) { Todo *ev = new Todo(*todo); ev->registerObserver(0); ev->clearAttendees(); if (!dlg->addMessage(ev,Scheduler::Publish,publishdlg->addresses())) { delete(ev); } } } } delete publishdlg; } void CalendarView::schedule_request(Incidence *incidence) { schedule(Scheduler::Request,incidence); } void CalendarView::schedule_refresh(Incidence *incidence) { schedule(Scheduler::Refresh,incidence); } void CalendarView::schedule_cancel(Incidence *incidence) { schedule(Scheduler::Cancel,incidence); } void CalendarView::schedule_add(Incidence *incidence) { schedule(Scheduler::Add,incidence); } void CalendarView::schedule_reply(Incidence *incidence) { schedule(Scheduler::Reply,incidence); } void CalendarView::schedule_counter(Incidence *incidence) { schedule(Scheduler::Counter,incidence); } diff --git a/libical/src/libical/astime.h b/libical/src/libical/astime.h new file mode 100644 index 0000000..6962c06 --- a/dev/null +++ b/libical/src/libical/astime.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1986-2000, Hiram Clawson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * Neither name of The Museum of Hiram nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @file astime.h + * @brief contains definitions of structures used for time calculations. + */ + +#ifndef _astime_h_ +#define _astime_h_ + +typedef struct ut_instant { + double j_date; /**< julian decimal date, 0 = 01 Jan 4713 BC 12 HR UT */ + long year; /**< year, valid range [-4,713, +2,147,483,647] */ + int month; /**< [1-12] */ + int day; /**< [1-31] */ + int i_hour; /**< [0-23] */ + int i_minute; /**< [0-59] */ + int i_second; /**< [0-59] */ + double d_hour; /**< [0.0-23.9999] includes minute and second */ + double d_minute; /**< [0.0-59.9999] includes second */ + double d_second; /**< [0.0-59.9999] */ + int weekday; /**< [0-6] */ + int day_of_year; /**< [1-366] */ +} UTinstant, * UTinstantPtr; + +/* Functions in caldate.c */ + +long caldat( UTinstantPtr ); /** converts julian date to year,mo,da */ +double juldat( UTinstantPtr ); /** returns julian day from year,mo,da */ + +#endif /* _astime_h_ */ diff --git a/libical/src/libical/caldate.c b/libical/src/libical/caldate.c new file mode 100644 index 0000000..f5554f6 --- a/dev/null +++ b/libical/src/libical/caldate.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 1986-2000, Hiram Clawson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * Redistributions in binary form must reproduce the + * above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * Neither name of The Museum of Hiram nor the names of + * its contributors may be used to endorse or promote products + * derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "astime.h" /* time structures */ + +/** + * caldat computes the day of the week, the day of the year + * the gregorian (or julian) calendar date and the universal + * time from the julian decimal date. + * for astronomical purposes, The Gregorian calendar reform occurred + * on 15 Oct. 1582. This is 05 Oct 1582 by the julian calendar. + + * Input: a ut_instant structure pointer, where the j_date element + * has been set. ( = 0 for 01 Jan 4713 B.C. 12 HR UT ) + * + * output: will set all the other elements of the structure. + * As a convienence, the function will also return the year. + * + * Reference: Astronomial formulae for calculators, meeus, p 23 + * from fortran program by F. Espenak - April 1982 Page 277, + * 50 Year canon of solar eclipses: 1986-2035 + * + */ + +long caldat( date ) +struct ut_instant * date; +{ + double frac; + long jd; + long ka; + long kb; + long kc; + long kd; + long ke; + long ialp; + + jd = (long) (date->j_date + 0.5); /* integer julian date */ + frac = date->j_date + 0.5 - (double) jd + 1.0e-10; /* day fraction */ + ka = (long) jd; + if ( jd >= 2299161L ) + { + ialp = ( (double) jd - 1867216.25 ) / ( 36524.25 ); + ka = jd + 1L + ialp - ( ialp >> 2 ); + } + kb = ka + 1524L; + kc = ( (double) kb - 122.1 ) / 365.25; + kd = (double) kc * 365.25; + ke = (double) ( kb - kd ) / 30.6001; + date->day = kb - kd - ((long) ( (double) ke * 30.6001 )); + if ( ke > 13L ) + date->month = ke - 13L; + else + date->month = ke - 1L; + if ( (date->month == 2) && (date->day > 28) ) + date->day = 29; + if ( (date->month == 2) && (date->day == 29) && (ke == 3L) ) + date->year = kc - 4716L; + else if ( date->month > 2 ) + date->year = kc - 4716L; + else + date->year = kc - 4715L; + date->i_hour = date->d_hour = frac * 24.0; /* hour */ + date->i_minute = date->d_minute = + ( date->d_hour - (double) date->i_hour ) * 60.0; /* minute */ + date->i_second = date->d_second = + ( date->d_minute - (double) date->i_minute ) * 60.0;/* second */ + date->weekday = (jd + 1L) % 7L; /* day of week */ + if ( date->year == ((date->year >> 2) << 2) ) + date->day_of_year = + ( ( 275 * date->month ) / 9) + - ((date->month + 9) / 12) + + date->day - 30; + else + date->day_of_year = + ( ( 275 * date->month ) / 9) + - (((date->month + 9) / 12) << 1) + + date->day - 30; + return( date->year ); +} + +/** + * juldat computes the julian decimal date (j_date) from + * the gregorian (or Julian) calendar date. + * for astronomical purposes, The Gregorian calendar reform occurred + * on 15 Oct. 1582. This is 05 Oct 1582 by the julian calendar. + * Input: a ut_instant structure pointer where Day, Month, Year and + * i_hour, i_minute, d_second have been set for the date + * in question. + * + * Output: the j_date and weekday elements of the structure will be set. + * Also, the return value of the function will be the j_date too. + * + * Reference: Astronomial formulae for calculators, meeus, p 23 + * from fortran program by F. Espenak - April 1982 Page 276, + * 50 Year canon of solar eclipses: 1986-2035 + */ + +double juldat( date ) +struct ut_instant * date; +{ + double frac, gyr; + long iy0, im0; + long ia, ib; + long jd; + + /* decimal day fraction */ + frac = (( double)date->i_hour/ 24.0) + + ((double) date->i_minute / 1440.0) + + (date->d_second / 86400.0); + /* convert date to format YYYY.MMDDdd */ + gyr = (double) date->year + + (0.01 * (double) date->month) + + (0.0001 * (double) date->day) + + (0.0001 * frac) + 1.0e-9; + /* conversion factors */ + if ( date->month <= 2 ) + { + iy0 = date->year - 1L; + im0 = date->month + 12; + } + else + { + iy0 = date->year; + im0 = date->month; + } + ia = iy0 / 100L; + ib = 2L - ia + (ia >> 2); + /* calculate julian date */ + if ( date->year < 0L ) + jd = (long) ((365.25 * (double) iy0) - 0.75) + + (long) (30.6001 * (im0 + 1L) ) + + (long) date->day + 1720994L; + else + jd = (long) (365.25 * (double) iy0) + + (long) (30.6001 * (double) (im0 + 1L)) + + (long) date->day + 1720994L; + if ( gyr >= 1582.1015 ) /* on or after 15 October 1582 */ + jd += ib; + date->j_date = (double) jd + frac + 0.5; + jd = (long) (date->j_date + 0.5); + date->weekday = (jd + 1L) % 7L; + return( date->j_date ); +} /* end of double juldat( date ) */ diff --git a/libical/src/libical/ical.h b/libical/src/libical/ical.h index 69a2c3a..0ae2c15 100644 --- a/libical/src/libical/ical.h +++ b/libical/src/libical/ical.h @@ -1,2996 +1,3640 @@ +#ifdef __cplusplus +extern "C" { +#endif +/* + $Id$ +*/ +/* config.h. Generated by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the <assert.h> header file. */ +#define HAVE_ASSERT_H 1 + +/* Define to 1 if you have the `gmtime_r' function. */ +#define HAVE_GMTIME_R 1 + +/* Define to 1 if you have the <inttypes.h> header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `iswspace' function. */ +#define HAVE_ISWSPACE 1 + +/* Define to 1 if you have the <memory.h> header file. */ +#define HAVE_MEMORY_H 1 + +/* Define if we have pthread. */ +#define HAVE_PTHREAD + +/* Define to 1 if you have the <pthread.h> header file. */ +#define HAVE_PTHREAD_H 1 + +/* Define to 1 if you have the `snprintf' function. */ +#define HAVE_SNPRINTF 1 + +/* Define to 1 if you have the <stdint.h> header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the <stdlib.h> header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the <strings.h> header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the <string.h> header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the <sys/types.h> header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the <time.h> header file. */ +#define HAVE_TIME_H 1 + +/* Define to 1 if you have the <unistd.h> header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the <wctype.h> header file. */ +#define HAVE_WCTYPE_H 1 + +/* Define to make icalerror_* calls abort instead of internally signalling an + error */ +#define ICAL_ERRORS_ARE_FATAL 1 + +/* Define if we want _REENTRANT */ +/* #undef ICAL_REENTRANT */ + +/* Define to terminate lines with " +" instead of "
+" */ +#define ICAL_UNIX_NEWLINE 1 + +/* Define to 1 if you DO NOT WANT to see deprecated messages */ +#define NO_WARN_DEPRECATED 1 + +/* Define to 1 if you DO NO WANT to see the warning messages related to + ICAL_MALFORMEDDATA_ERROR and parsing .ics zoneinfo files */ +#define NO_WARN_ICAL_MALFORMEDDATA_ERROR_HACK 1 + +/* Name of package */ +#define PACKAGE "libical" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if your <sys/time.h> declares `struct tm'. */ +/* #undef TM_IN_SYS_TIME */ + +/* Version number of package */ +#define VERSION "0.24" + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#define YYTEXT_POINTER 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if <sys/types.h> does not define. */ +/* #undef mode_t */ + +/* Define to `unsigned' if <sys/types.h> does not define. */ +/* #undef size_t */ #ifndef ICAL_VERSION_H #define ICAL_VERSION_H #define ICAL_PACKAGE "libical" -#define ICAL_VERSION "0.23" +#define ICAL_VERSION "0.24" #endif /* -*- Mode: C -*- */ /*====================================================================== FILE: icaltime.h 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 ======================================================================*/ +/** @file icaltime.h + * @brief struct icaltimetype is a pseudo-object that abstracts time + * handling. + * + * It can represent either a DATE or a DATE-TIME (floating, UTC or in a + * given timezone), and it keeps track internally of its native timezone. + * + * The typical usage is to call the correct constructor specifying the + * desired timezone. If this is not known until a later time, the + * correct behavior is to specify a NULL timezone and call + * icaltime_convert_to_zone() at a later time. + * + * There are several ways to create a new icaltimetype: + * + * - icaltime_null_time() + * - icaltime_null_date() + * - icaltime_current_time_with_zone() + * - icaltime_today() + * - icaltime_from_timet_with_zone(time_t tm, int is_date, + * icaltimezone *zone) + * - icaltime_from_string_with_zone(const char* str, icaltimezone *zone) + * - icaltime_from_day_of_year(int doy, int year) + * - icaltime_from_week_number(int week_number, int year) + * + * italtimetype objects can be converted to different formats: + * + * - icaltime_as_timet(struct icaltimetype tt) + * - icaltime_as_timet_with_zone(struct icaltimetype tt, + * icaltimezone *zone) + * - icaltime_as_ical_string(struct icaltimetype tt) + * + * Accessor methods include: + * + * - icaltime_get_timezone(struct icaltimetype t) + * - icaltime_get_tzid(struct icaltimetype t) + * - icaltime_set_timezone(struct icaltimetype t, const icaltimezone *zone) + * - icaltime_day_of_year(struct icaltimetype t) + * - icaltime_day_of_week(struct icaltimetype t) + * - icaltime_start_doy_of_week(struct icaltimetype t) + * - icaltime_week_number(struct icaltimetype t) + * + * Query methods include: + * + * - icaltime_is_null_time(struct icaltimetype t) + * - icaltime_is_valid_time(struct icaltimetype t) + * - icaltime_is_date(struct icaltimetype t) + * - icaltime_is_utc(struct icaltimetype t) + * - icaltime_is_floating(struct icaltimetype t) + * + * Modify, compare and utility methods include: + * + * - icaltime_add(struct icaltimetype t, struct icaldurationtype d) + * - icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2) + * - icaltime_compare_with_zone(struct icaltimetype a,struct icaltimetype b) + * - icaltime_compare(struct icaltimetype a,struct icaltimetype b) + * - icaltime_compare_date_only(struct icaltimetype a, + * struct icaltimetype b) + * - icaltime_adjust(struct icaltimetype *tt, int days, int hours, + * int minutes, int seconds); + * - icaltime_normalize(struct icaltimetype t); + * - icaltime_convert_to_zone(const struct icaltimetype tt, + * icaltimezone *zone); + */ + #ifndef ICALTIME_H #define ICALTIME_H #include <time.h> -/* icaltime_span is returned by icalcomponent_get_span() */ +/* An opaque struct representing a timezone. We declare this here to avoid + a circular dependancy. */ +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +typedef struct _icaltimezone icaltimezone; +#endif + +/** icaltime_span is returned by icalcomponent_get_span() */ struct icaltime_span { - time_t start; /* in UTC */ - time_t end; /* in UTC */ - int is_busy; /* 1->busy time, 0-> free time */ + time_t start; /**< in UTC */ + time_t end; /**< in UTC */ + int is_busy; /**< 1->busy time, 0-> free time */ }; +typedef struct icaltime_span icaltime_span; +/* + * FIXME + * + * is_utc is redundant, and might be considered a minor optimization. + * It might be deprecated, so you should use icaltime_is_utc() instead. + */ struct icaltimetype { - int year; - int month; + int year; /**< Actual year, e.g. 2001. */ + int month; /**< 1 (Jan) to 12 (Dec). */ int day; int hour; int minute; int second; - int is_utc; /* 1-> time is in UTC timezone */ + int is_utc; /**< 1-> time is in UTC timezone */ - int is_date; /* 1 -> interpret this as date. */ + int is_date; /**< 1 -> interpret this as date. */ - const char* zone; /*Ptr to Olsen placename. Libical does not own mem*/ + int is_daylight; /**< 1 -> time is in daylight savings time. */ + + const icaltimezone *zone; /**< timezone */ }; -/* Convert seconds past UNIX epoch to a timetype*/ -struct icaltimetype icaltime_from_timet(time_t v, int is_date); +typedef struct icaltimetype icaltimetype; -/* Return the time as seconds past the UNIX epoch */ -time_t icaltime_as_timet(struct icaltimetype); +/** Return a null time, which indicates no time has been set. + This time represent the beginning of the epoch */ +struct icaltimetype icaltime_null_time(void); -/* Return a string represention of the time, in RFC2445 format. The - string is owned by libical */ -char* icaltime_as_ical_string(struct icaltimetype tt); +/** Return a null date */ +struct icaltimetype icaltime_null_date(void); -/* Like icaltime_from_timet(), except that the input may be in seconds - past the epoch in floating time. This routine is deprecated */ -struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc); +/** Returns the current time in the given timezone, as an icaltimetype. */ +struct icaltimetype icaltime_current_time_with_zone(const icaltimezone *zone); -/* Like icaltime_as_timet, but in a floating epoch. This routine is deprecated */ -int icaltime_as_int(struct icaltimetype); +/** Returns the current day as an icaltimetype, with is_date set. */ +struct icaltimetype icaltime_today(void); -/* create a time from an ISO format string */ +/** Convert seconds past UNIX epoch to a timetype*/ +struct icaltimetype icaltime_from_timet(const time_t v, const int is_date); + +/** Convert seconds past UNIX epoch to a timetype, using timezones. */ +struct icaltimetype icaltime_from_timet_with_zone(const time_t tm, + const int is_date, const icaltimezone *zone); + +/** create a time from an ISO format string */ struct icaltimetype icaltime_from_string(const char* str); -/* Routines for handling timezones */ -/* Return the offset of the named zone as seconds. tt is a time - indicating the date for which you want the offset */ -int icaltime_utc_offset(struct icaltimetype tt, const char* tzid); +/** create a time from an ISO format string */ +struct icaltimetype icaltime_from_string_with_zone(const char* str, + const icaltimezone *zone); -/* convert tt, of timezone tzid, into a utc time. Does nothing if the - time is already UTC. */ -struct icaltimetype icaltime_as_utc(struct icaltimetype tt, - const char* tzid); +/** Create a new time, given a day of year and a year. */ +struct icaltimetype icaltime_from_day_of_year(const int doy, + const int year); -/* convert tt, a time in UTC, into a time in timezone tzid */ -struct icaltimetype icaltime_as_zone(struct icaltimetype tt, - const char* tzid); +/** @brief Contructor (TODO). + * Create a new time from a weeknumber and a year. */ +struct icaltimetype icaltime_from_week_number(const int week_number, + const int year); -/* Return a null time, which indicates no time has been set. This time represent the beginning of the epoch */ -struct icaltimetype icaltime_null_time(void); +/** Return the time as seconds past the UNIX epoch */ +time_t icaltime_as_timet(const struct icaltimetype); + +/** Return the time as seconds past the UNIX epoch, using timezones. */ +time_t icaltime_as_timet_with_zone(const struct icaltimetype tt, + const icaltimezone *zone); + +/** Return a string represention of the time, in RFC2445 format. The + string is owned by libical */ +const char* icaltime_as_ical_string(const struct icaltimetype tt); + +/** @brief Return the timezone */ +const icaltimezone *icaltime_get_timezone(const struct icaltimetype t); + +/** @brief Return the tzid, or NULL for a floating time */ +char *icaltime_get_tzid(const struct icaltimetype t); + +/** @brief Set the timezone */ +struct icaltimetype icaltime_set_timezone(struct icaltimetype *t, + const icaltimezone *zone); -/* Return true of the time is null. */ -int icaltime_is_null_time(struct icaltimetype t); +/** Return the day of the year of the given time */ +int icaltime_day_of_year(const struct icaltimetype t); -/* Returns false if the time is clearly invalid, but is not null. This +/** Return the day of the week of the given time. Sunday is 1 */ +int icaltime_day_of_week(const struct icaltimetype t); + +/** Return the day of the year for the Sunday of the week that the + given time is within. */ +int icaltime_start_doy_of_week(const struct icaltimetype t); + +/** Return the week number for the week the given time is within */ +int icaltime_week_number(const struct icaltimetype t); + +/** Return true of the time is null. */ +int icaltime_is_null_time(const struct icaltimetype t); + +/** Returns false if the time is clearly invalid, but is not null. This is usually the result of creating a new time type buy not clearing it, or setting one of the flags to an illegal value. */ -int icaltime_is_valid_time(struct icaltimetype t); +int icaltime_is_valid_time(const struct icaltimetype t); -/* Reset all of the time components to be in their normal ranges. For - instance, given a time with minutes=70, the minutes will be reduces - to 10, and the hour incremented. This allows the caller to do - arithmetic on times without worrying about overflow or - underflow. */ -struct icaltimetype icaltime_normalize(struct icaltimetype t); +/** @brief Returns true if time is of DATE type, false if DATE-TIME */ +int icaltime_is_date(const struct icaltimetype t); -/* Return the day of the year of the given time */ -short icaltime_day_of_year(struct icaltimetype t); +/** @brief Returns true if time is relative to UTC zone */ +int icaltime_is_utc(const struct icaltimetype t); -/* Create a new time, given a day of year and a year. */ -struct icaltimetype icaltime_from_day_of_year(short doy, short year); +/** @brief Returns true if time is a floating time */ +int icaltime_is_floating(const struct icaltimetype t); -/* Return the day of the week of the given time. Sunday is 1 */ -short icaltime_day_of_week(struct icaltimetype t); +/** Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ +int icaltime_compare_with_zone(const struct icaltimetype a, + const struct icaltimetype b); -/* Return the day of the year for the Sunday of the week that the - given time is within. */ -short icaltime_start_doy_of_week(struct icaltimetype t); +/** Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ +int icaltime_compare(const struct icaltimetype a, + const struct icaltimetype b); -/* Return a string with the time represented in the same format as ctime(). THe string is owned by libical */ -char* icaltime_as_ctime(struct icaltimetype); +/** like icaltime_compare, but only use the date parts. */ +int icaltime_compare_date_only(const struct icaltimetype a, + const struct icaltimetype b); -/* Return the week number for the week the given time is within */ -short icaltime_week_number(struct icaltimetype t); +/** Adds or subtracts a number of days, hours, minutes and seconds. */ +void icaltime_adjust(struct icaltimetype *tt, const int days, + const int hours, const int minutes, const int seconds); -/* Create a new time from a weeknumber and a year. */ -struct icaltimetype icaltime_from_week_number(short week_number, short year); +/** Normalize the icaltime, so that all fields are within the normal range. */ +struct icaltimetype icaltime_normalize(const struct icaltimetype t); -/* Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ -int icaltime_compare(struct icaltimetype a,struct icaltimetype b); +/** convert tt, of timezone tzid, into a utc time. Does nothing if the + time is already UTC. */ +struct icaltimetype icaltime_convert_to_zone(const struct icaltimetype tt, + icaltimezone *zone); -/* like icaltime_compare, but only use the date parts. */ -int icaltime_compare_date_only(struct icaltimetype a, struct icaltimetype b); +/** Return the number of days in the given month */ +int icaltime_days_in_month(const int month, const int year); -/* Return the number of days in the given month */ -short icaltime_days_in_month(short month,short year); +/** @brief calculate an icaltimespan given a start and end time. */ +struct icaltime_span icaltime_span_new(struct icaltimetype dtstart, + struct icaltimetype dtend, + int is_busy); -#endif /* !ICALTIME_H */ +/** @brief Returns true if the two spans overlap **/ +int icaltime_span_overlaps(icaltime_span *s1, + icaltime_span *s2); +/** @brief Returns true if the span is totally within the containing + * span + */ +int icaltime_span_contains(icaltime_span *s, + icaltime_span *container); + + +#endif /* !ICALTIME_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalduration.h CREATOR: eric 26 Jan 2001 - $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 ======================================================================*/ #ifndef ICALDURATION_H #define ICALDURATION_H struct icaldurationtype { int is_neg; unsigned int days; unsigned int weeks; unsigned int hours; unsigned int minutes; unsigned int seconds; }; struct icaldurationtype icaldurationtype_from_int(int t); struct icaldurationtype icaldurationtype_from_string(const char*); int icaldurationtype_as_int(struct icaldurationtype duration); char* icaldurationtype_as_ical_string(struct icaldurationtype d); -struct icaldurationtype icaldurationtype_null_duration(); +struct icaldurationtype icaldurationtype_null_duration(void); +struct icaldurationtype icaldurationtype_bad_duration(void); int icaldurationtype_is_null_duration(struct icaldurationtype d); +int icaldurationtype_is_bad_duration(struct icaldurationtype d); struct icaltimetype icaltime_add(struct icaltimetype t, struct icaldurationtype d); struct icaldurationtype icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2); #endif /* !ICALDURATION_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalperiod.h CREATOR: eric 26 Jan 2001 - $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 ======================================================================*/ #ifndef ICALPERIOD_H #define ICALPERIOD_H struct icalperiodtype { struct icaltimetype start; struct icaltimetype end; struct icaldurationtype duration; }; struct icalperiodtype icalperiodtype_from_string (const char* str); const char* icalperiodtype_as_ical_string(struct icalperiodtype p); -struct icalperiodtype icalperiodtype_null_period(); -int icalperiodtype_is_null_period(struct icalperiodtype p); -int icalperiodtype_is_valid_period(struct icalperiodtype p); +struct icalperiodtype icalperiodtype_null_period(void); +int icalperiodtype_is_null_period(struct icalperiodtype p); +int icalperiodtype_is_valid_period(struct icalperiodtype p); #endif /* !ICALTIME_H */ /* -*- Mode: C -*-*/ /*====================================================================== FILE: icalenums.h (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 icalenums.h Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifndef ICALENUMS_H #define ICALENUMS_H /*********************************************************************** * Component enumerations **********************************************************************/ typedef enum icalcomponent_kind { ICAL_NO_COMPONENT, ICAL_ANY_COMPONENT, /* Used to select all components*/ ICAL_XROOT_COMPONENT, ICAL_XATTACH_COMPONENT, /* MIME attached data, returned by parser. */ ICAL_VEVENT_COMPONENT, ICAL_VTODO_COMPONENT, ICAL_VJOURNAL_COMPONENT, ICAL_VCALENDAR_COMPONENT, + ICAL_VAGENDA_COMPONENT, ICAL_VFREEBUSY_COMPONENT, ICAL_VALARM_COMPONENT, ICAL_XAUDIOALARM_COMPONENT, ICAL_XDISPLAYALARM_COMPONENT, ICAL_XEMAILALARM_COMPONENT, ICAL_XPROCEDUREALARM_COMPONENT, ICAL_VTIMEZONE_COMPONENT, ICAL_XSTANDARD_COMPONENT, ICAL_XDAYLIGHT_COMPONENT, ICAL_X_COMPONENT, ICAL_VSCHEDULE_COMPONENT, ICAL_VQUERY_COMPONENT, ICAL_VCAR_COMPONENT, ICAL_VCOMMAND_COMPONENT, ICAL_XLICINVALID_COMPONENT, ICAL_XLICMIMEPART_COMPONENT /* a non-stardard component that mirrors structure of MIME data */ } icalcomponent_kind; /*********************************************************************** * Request Status codes **********************************************************************/ typedef enum icalrequeststatus { ICAL_UNKNOWN_STATUS, ICAL_2_0_SUCCESS_STATUS, ICAL_2_1_FALLBACK_STATUS, ICAL_2_2_IGPROP_STATUS, ICAL_2_3_IGPARAM_STATUS, ICAL_2_4_IGXPROP_STATUS, ICAL_2_5_IGXPARAM_STATUS, ICAL_2_6_IGCOMP_STATUS, ICAL_2_7_FORWARD_STATUS, ICAL_2_8_ONEEVENT_STATUS, ICAL_2_9_TRUNC_STATUS, ICAL_2_10_ONETODO_STATUS, ICAL_2_11_TRUNCRRULE_STATUS, ICAL_3_0_INVPROPNAME_STATUS, ICAL_3_1_INVPROPVAL_STATUS, ICAL_3_2_INVPARAM_STATUS, ICAL_3_3_INVPARAMVAL_STATUS, ICAL_3_4_INVCOMP_STATUS, ICAL_3_5_INVTIME_STATUS, ICAL_3_6_INVRULE_STATUS, ICAL_3_7_INVCU_STATUS, ICAL_3_8_NOAUTH_STATUS, ICAL_3_9_BADVERSION_STATUS, ICAL_3_10_TOOBIG_STATUS, ICAL_3_11_MISSREQCOMP_STATUS, ICAL_3_12_UNKCOMP_STATUS, ICAL_3_13_BADCOMP_STATUS, ICAL_3_14_NOCAP_STATUS, + ICAL_3_15_INVCOMMAND, ICAL_4_0_BUSY_STATUS, + ICAL_4_1_STORE_ACCESS_DENIED, + ICAL_4_2_STORE_FAILED, + ICAL_4_3_STORE_NOT_FOUND, ICAL_5_0_MAYBE_STATUS, ICAL_5_1_UNAVAIL_STATUS, ICAL_5_2_NOSERVICE_STATUS, - ICAL_5_3_NOSCHED_STATUS + ICAL_5_3_NOSCHED_STATUS, + ICAL_6_1_CONTAINER_NOT_FOUND, + ICAL_9_0_UNRECOGNIZED_COMMAND } icalrequeststatus; const char* icalenum_reqstat_desc(icalrequeststatus stat); short icalenum_reqstat_major(icalrequeststatus stat); short icalenum_reqstat_minor(icalrequeststatus stat); icalrequeststatus icalenum_num_to_reqstat(short major, short minor); +char* icalenum_reqstat_code(icalrequeststatus stat); /*********************************************************************** * Conversion functions **********************************************************************/ /* Thse routines used to be in icalenums.c, but were moved into the icalproperty, icalparameter, icalvalue, or icalcomponent modules. */ /* const char* icalproperty_kind_to_string(icalproperty_kind kind);*/ #define icalenum_property_kind_to_string(x) icalproperty_kind_to_string(x) /*icalproperty_kind icalproperty_string_to_kind(const char* string)*/ #define icalenum_string_to_property_kind(x) icalproperty_string_to_kind(x) /*icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind);*/ #define icalenum_property_kind_to_value_kind(x) icalproperty_kind_to_value_kind(x) /*const char* icalenum_method_to_string(icalproperty_method);*/ #define icalenum_method_to_string(x) icalproperty_method_to_string(x) /*icalproperty_method icalenum_string_to_method(const char* string);*/ #define icalenum_string_to_method(x) icalproperty_string_to_method(x) /*const char* icalenum_status_to_string(icalproperty_status);*/ #define icalenum_status_to_string(x) icalproperty_status_to_string(x) /*icalproperty_status icalenum_string_to_status(const char* string);*/ #define icalenum_string_to_status(x) icalproperty_string_to_status(x) /*icalvalue_kind icalenum_string_to_value_kind(const char* str);*/ #define icalenum_string_to_value_kind(x) icalvalue_string_to_kind(x) /*const char* icalenum_value_kind_to_string(icalvalue_kind kind);*/ #define icalenum_value_kind_to_string(x) icalvalue_kind_to_string(x) /*const char* icalenum_component_kind_to_string(icalcomponent_kind kind);*/ #define icalenum_component_kind_to_string(x) icalcomponent_kind_to_string(x) /*icalcomponent_kind icalenum_string_to_component_kind(const char* string);*/ #define icalenum_string_to_component_kind(x) icalcomponent_string_to_kind(x) #endif /* !ICALENUMS_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icaltypes.h CREATOR: eric 20 March 1999 (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 icaltypes.h ======================================================================*/ #ifndef ICALTYPES_H #define ICALTYPES_H #include <time.h> -/* This type type should probably be an opaque type... */ -struct icalattachtype -{ - void* binary; - int owns_binary; - - char* base64; - int owns_base64; - - char* url; - - int refcount; - -}; - -/* converts base64 to binary, fetches url and stores as binary, or - just returns data */ - -struct icalattachtype* icalattachtype_new(void); -void icalattachtype_add_reference(struct icalattachtype* v); -void icalattachtype_free(struct icalattachtype* v); - -void icalattachtype_set_url(struct icalattachtype* v, char* url); -char* icalattachtype_get_url(struct icalattachtype* v); - -void icalattachtype_set_base64(struct icalattachtype* v, char* base64, - int owns); -char* icalattachtype_get_base64(struct icalattachtype* v); - -void icalattachtype_set_binary(struct icalattachtype* v, char* binary, - int owns); -void* icalattachtype_get_binary(struct icalattachtype* v); - struct icalgeotype { float lat; float lon; }; struct icaldatetimeperiodtype { struct icaltimetype time; struct icalperiodtype period; }; struct icaltriggertype { struct icaltimetype time; struct icaldurationtype duration; }; +struct icaltriggertype icaltriggertype_from_int(const int reltime); struct icaltriggertype icaltriggertype_from_string(const char* str); int icaltriggertype_is_null_trigger(struct icaltriggertype tr); +int icaltriggertype_is_bad_trigger(struct icaltriggertype tr); /* struct icalreqstattype. This struct contains two string pointers, but don't try to free either of them. The "desc" string is a pointer to a static table inside the library. Don't try to free it. The "debug" string is a pointer into the string that the called passed into to icalreqstattype_from_string. Don't try to free it either, and don't use it after the original string has been freed. BTW, you would get that original string from *icalproperty_get_requeststatus() or icalvalue_get_text(), when operating on a the value of a request_status property. */ struct icalreqstattype { icalrequeststatus code; const char* desc; const char* debug; }; struct icalreqstattype icalreqstattype_from_string(const char* str); const char* icalreqstattype_as_string(struct icalreqstattype); struct icaltimezonephase { const char* tzname; int is_stdandard; /* 1 = standard tme, 0 = daylight savings time */ struct icaltimetype dtstart; int offsetto; int tzoffsetfrom; const char* comment; struct icaldatetimeperiodtype rdate; const char* rrule; }; struct icaltimezonetype { const char* tzid; struct icaltimetype last_mod; const char* tzurl; /* Array of phases. The end of the array is a phase with tzname == 0 */ struct icaltimezonephase *phases; }; void icaltimezonetype_free(struct icaltimezonetype tzt); #endif /* !ICALTYPES_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalrecur.h CREATOR: eric 20 March 2000 (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/ +*/ + +/** +@file icalrecur.h +@brief Routines for dealing with recurring time How to use: 1) Get a rule and a start time from a component + +@code icalproperty rrule; struct icalrecurrencetype recur; struct icaltimetype dtstart; rrule = icalcomponent_get_first_property(comp,ICAL_RRULE_PROPERTY); recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); +@endcode Or, just make them up: + +@code recur = icalrecurrencetype_from_string("FREQ=YEARLY;BYDAY=SU,WE"); dtstart = icaltime_from_string("19970101T123000") +@endcode 2) Create an iterator + +@code icalrecur_iterator* ritr; ritr = icalrecur_iterator_new(recur,start); +@endcode 3) Iterator over the occurrences + +@code struct icaltimetype next; while (next = icalrecur_iterator_next(ritr) && !icaltime_is_null_time(next){ Do something with next } +@endcode Note that that the time returned by icalrecur_iterator_next is in whatever timezone that dtstart is in. -======================================================================*/ +*/ #ifndef ICALRECUR_H #define ICALRECUR_H #include <time.h> -/*********************************************************************** +/* * Recurrance enumerations -**********************************************************************/ + */ typedef enum icalrecurrencetype_frequency { /* These enums are used to index an array, so don't change the order or the integers */ ICAL_SECONDLY_RECURRENCE=0, ICAL_MINUTELY_RECURRENCE=1, ICAL_HOURLY_RECURRENCE=2, ICAL_DAILY_RECURRENCE=3, ICAL_WEEKLY_RECURRENCE=4, ICAL_MONTHLY_RECURRENCE=5, ICAL_YEARLY_RECURRENCE=6, ICAL_NO_RECURRENCE=7 } icalrecurrencetype_frequency; typedef enum icalrecurrencetype_weekday { ICAL_NO_WEEKDAY, ICAL_SUNDAY_WEEKDAY, ICAL_MONDAY_WEEKDAY, ICAL_TUESDAY_WEEKDAY, ICAL_WEDNESDAY_WEEKDAY, ICAL_THURSDAY_WEEKDAY, ICAL_FRIDAY_WEEKDAY, ICAL_SATURDAY_WEEKDAY } icalrecurrencetype_weekday; enum { ICAL_RECURRENCE_ARRAY_MAX = 0x7f7f, ICAL_RECURRENCE_ARRAY_MAX_BYTE = 0x7f }; -/********************** Recurrence type routines **************/ +/** + * Recurrence type routines + */ /* See RFC 2445 Section 4.3.10, RECUR Value, for an explaination of the values and fields in struct icalrecurrencetype */ #define ICAL_BY_SECOND_SIZE 61 #define ICAL_BY_MINUTE_SIZE 61 #define ICAL_BY_HOUR_SIZE 25 #define ICAL_BY_DAY_SIZE 364 /* 7 days * 52 weeks */ #define ICAL_BY_MONTHDAY_SIZE 32 #define ICAL_BY_YEARDAY_SIZE 367 #define ICAL_BY_WEEKNO_SIZE 54 #define ICAL_BY_MONTH_SIZE 13 #define ICAL_BY_SETPOS_SIZE 367 -/* Main struct for holding digested recurrence rules */ +/** Main struct for holding digested recurrence rules */ struct icalrecurrencetype { icalrecurrencetype_frequency freq; /* until and count are mutually exclusive. */ struct icaltimetype until; int count; short interval; icalrecurrencetype_weekday week_start; /* The BY* parameters can each take a list of values. Here I * assume that the list of values will not be larger than the * range of the value -- that is, the client will not name a * value more than once. * Each of the lists is terminated with the value * ICAL_RECURRENCE_ARRAY_MAX unless the the list is full. */ short by_second[ICAL_BY_SECOND_SIZE]; short by_minute[ICAL_BY_MINUTE_SIZE]; short by_hour[ICAL_BY_HOUR_SIZE]; short by_day[ICAL_BY_DAY_SIZE]; /* Encoded value, see below */ short by_month_day[ICAL_BY_MONTHDAY_SIZE]; short by_year_day[ ICAL_BY_YEARDAY_SIZE]; short by_week_no[ICAL_BY_WEEKNO_SIZE]; short by_month[ICAL_BY_MONTH_SIZE]; short by_set_pos[ICAL_BY_SETPOS_SIZE]; }; void icalrecurrencetype_clear(struct icalrecurrencetype *r); -/* The 'day' element of the by_day array is encoded to allow -representation of both the day of the week ( Monday, Tueday), but also -the Nth day of the week ( First tuesday of the month, last thursday of -the year) These routines decode the day values */ +/** + * Array Encoding + * + * The 'day' element of the by_day array is encoded to allow + * representation of both the day of the week ( Monday, Tueday), but also + * the Nth day of the week ( First tuesday of the month, last thursday of + * the year) These routines decode the day values + */ -/* 1 == Monday, etc. */ +/** 1 == Monday, etc. */ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day); -/* 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */ -short icalrecurrencetype_day_position(short day); +/** 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */ +int icalrecurrencetype_day_position(short day); -/*********************************************************************** - * Recurrance rule parser -**********************************************************************/ +/** Recurrance rule parser */ -/* Convert between strings ans recurrencetype structures. */ +/** Convert between strings and recurrencetype structures. */ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str); char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur); -/********** recurrence iteration routines ********************/ +/** Recurrence iteration routines */ -typedef void icalrecur_iterator; +typedef struct icalrecur_iterator_impl icalrecur_iterator; -/* Create a new recurrence rule iterator */ +/** Create a new recurrence rule iterator */ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart); -/* Get the next occurrence from an iterator */ +/** Get the next occurrence from an iterator */ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator*); -/* Free the iterator */ +void icalrecur_iterator_decrement_count(icalrecur_iterator*); + +/** Free the iterator */ void icalrecur_iterator_free(icalrecur_iterator*); -/* Fills array up with at most 'count' time_t values, each - representing an occurrence time in seconds past the POSIX epoch */ +/** + * Fills array up with at most 'count' time_t values, each + * representing an occurrence time in seconds past the POSIX epoch + */ int icalrecur_expand_recurrence(char* rule, time_t start, int count, time_t* array); #endif /* -*- Mode: C -*- */ /*====================================================================== + FILE: icalattach.h + CREATOR: acampi 28 May 02 + + + (C) COPYRIGHT 2002, Andrea Campi + + 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 icalattach.h + +======================================================================*/ + +#ifndef ICALATTACH_H +#define ICALATTACH_H + + +typedef struct icalattach_impl icalattach; + +typedef void (* icalattach_free_fn_t) (unsigned char *data, void *user_data); + +icalattach *icalattach_new_from_url (const char *url); +icalattach *icalattach_new_from_data (unsigned char *data, + icalattach_free_fn_t free_fn, void *free_fn_data); + +void icalattach_ref (icalattach *attach); +void icalattach_unref (icalattach *attach); + +int icalattach_get_is_url (icalattach *attach); +const char *icalattach_get_url (icalattach *attach); +unsigned char *icalattach_get_data (icalattach *attach); + +struct icalattachtype* icalattachtype_new(void); +void icalattachtype_add_reference(struct icalattachtype* v); +void icalattachtype_free(struct icalattachtype* v); + +void icalattachtype_set_url(struct icalattachtype* v, char* url); +char* icalattachtype_get_url(struct icalattachtype* v); + +void icalattachtype_set_base64(struct icalattachtype* v, char* base64, + int owns); +char* icalattachtype_get_base64(struct icalattachtype* v); + +void icalattachtype_set_binary(struct icalattachtype* v, char* binary, + int owns); +void* icalattachtype_get_binary(struct icalattachtype* v); + + + +#endif /* !ICALATTACH_H */ +/* -*- Mode: C -*- */ +/*====================================================================== FILE: icalvalue.h CREATOR: eric 20 March 1999 - $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 icalvalue.h ======================================================================*/ #ifndef ICALDERIVEDVALUE_H #define ICALDERIVEDVALUE_H -typedef void icalvalue; +typedef struct icalvalue_impl icalvalue; void icalvalue_set_x(icalvalue* value, const char* v); icalvalue* icalvalue_new_x(const char* v); -const char* icalvalue_get_x(icalvalue* value); - -icalvalue* icalvalue_new_attach (struct icalattachtype* v); -void icalvalue_set_attach(icalvalue* value, struct icalattachtype* v); -struct icalattachtype* icalvalue_get_attach(icalvalue* value); +const char* icalvalue_get_x(const icalvalue* value); icalvalue* icalvalue_new_recur (struct icalrecurrencetype v); void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); -struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); +struct icalrecurrencetype icalvalue_get_recur(const icalvalue* value); icalvalue* icalvalue_new_trigger (struct icaltriggertype v); void icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v); -struct icaltriggertype icalvalue_get_trigger(icalvalue* value); +struct icaltriggertype icalvalue_get_trigger(const icalvalue* value); icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); void icalvalue_set_datetimeperiod(icalvalue* value, struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(icalvalue* value); +struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(const icalvalue* value); + +icalvalue *icalvalue_new_attach (icalattach *attach); +void icalvalue_set_attach (icalvalue *value, icalattach *attach); +icalattach *icalvalue_get_attach (const icalvalue *value); void icalvalue_reset_kind(icalvalue* value); -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalvalue_kind { ICAL_ANY_VALUE=5000, ICAL_QUERY_VALUE=5001, - ICAL_TRIGGER_VALUE=5002, - ICAL_STATUS_VALUE=5003, - ICAL_TRANSP_VALUE=5004, - ICAL_CLASS_VALUE=5005, - ICAL_DATE_VALUE=5006, + ICAL_DATE_VALUE=5002, + ICAL_ATTACH_VALUE=5003, + ICAL_GEO_VALUE=5004, + ICAL_STATUS_VALUE=5005, + ICAL_TRANSP_VALUE=5006, ICAL_STRING_VALUE=5007, - ICAL_INTEGER_VALUE=5008, - ICAL_PERIOD_VALUE=5009, - ICAL_TEXT_VALUE=5010, - ICAL_DURATION_VALUE=5011, - ICAL_BOOLEAN_VALUE=5012, - ICAL_URI_VALUE=5013, - ICAL_DATETIMEPERIOD_VALUE=5014, - ICAL_GEO_VALUE=5015, - ICAL_DATETIME_VALUE=5016, - ICAL_UTCOFFSET_VALUE=5017, - ICAL_ATTACH_VALUE=5018, - ICAL_ACTION_VALUE=5019, + ICAL_TEXT_VALUE=5008, + ICAL_REQUESTSTATUS_VALUE=5009, + ICAL_BINARY_VALUE=5010, + ICAL_PERIOD_VALUE=5011, + ICAL_FLOAT_VALUE=5012, + ICAL_DATETIMEPERIOD_VALUE=5013, + ICAL_INTEGER_VALUE=5014, + ICAL_CLASS_VALUE=5015, + ICAL_URI_VALUE=5016, + ICAL_DURATION_VALUE=5017, + ICAL_BOOLEAN_VALUE=5018, + ICAL_X_VALUE=5019, ICAL_CALADDRESS_VALUE=5020, - ICAL_X_VALUE=5021, - ICAL_FLOAT_VALUE=5022, - ICAL_REQUESTSTATUS_VALUE=5023, - ICAL_METHOD_VALUE=5024, - ICAL_BINARY_VALUE=5025, - ICAL_RECUR_VALUE=5026, - ICAL_NO_VALUE=5027 + ICAL_TRIGGER_VALUE=5021, + ICAL_XLICCLASS_VALUE=5022, + ICAL_RECUR_VALUE=5023, + ICAL_ACTION_VALUE=5024, + ICAL_DATETIME_VALUE=5025, + ICAL_UTCOFFSET_VALUE=5026, + ICAL_METHOD_VALUE=5027, + ICAL_NO_VALUE=5028 } icalvalue_kind ; #define ICALPROPERTY_FIRST_ENUM 10000 typedef enum icalproperty_action { ICAL_ACTION_X = 10000, ICAL_ACTION_AUDIO = 10001, ICAL_ACTION_DISPLAY = 10002, ICAL_ACTION_EMAIL = 10003, ICAL_ACTION_PROCEDURE = 10004, ICAL_ACTION_NONE = 10005 } icalproperty_action; typedef enum icalproperty_class { ICAL_CLASS_X = 10006, ICAL_CLASS_PUBLIC = 10007, ICAL_CLASS_PRIVATE = 10008, ICAL_CLASS_CONFIDENTIAL = 10009, ICAL_CLASS_NONE = 10010 } icalproperty_class; typedef enum icalproperty_method { ICAL_METHOD_X = 10011, ICAL_METHOD_PUBLISH = 10012, ICAL_METHOD_REQUEST = 10013, ICAL_METHOD_REPLY = 10014, ICAL_METHOD_ADD = 10015, ICAL_METHOD_CANCEL = 10016, ICAL_METHOD_REFRESH = 10017, ICAL_METHOD_COUNTER = 10018, ICAL_METHOD_DECLINECOUNTER = 10019, ICAL_METHOD_CREATE = 10020, ICAL_METHOD_READ = 10021, ICAL_METHOD_RESPONSE = 10022, ICAL_METHOD_MOVE = 10023, ICAL_METHOD_MODIFY = 10024, ICAL_METHOD_GENERATEUID = 10025, ICAL_METHOD_DELETE = 10026, ICAL_METHOD_NONE = 10027 } icalproperty_method; typedef enum icalproperty_status { ICAL_STATUS_X = 10028, ICAL_STATUS_TENTATIVE = 10029, ICAL_STATUS_CONFIRMED = 10030, ICAL_STATUS_COMPLETED = 10031, ICAL_STATUS_NEEDSACTION = 10032, ICAL_STATUS_CANCELLED = 10033, ICAL_STATUS_INPROCESS = 10034, ICAL_STATUS_DRAFT = 10035, ICAL_STATUS_FINAL = 10036, ICAL_STATUS_NONE = 10037 } icalproperty_status; typedef enum icalproperty_transp { ICAL_TRANSP_X = 10038, ICAL_TRANSP_OPAQUE = 10039, - ICAL_TRANSP_TRANSPARENT = 10040, - ICAL_TRANSP_NONE = 10041 + ICAL_TRANSP_OPAQUENOCONFLICT = 10040, + ICAL_TRANSP_TRANSPARENT = 10041, + ICAL_TRANSP_TRANSPARENTNOCONFLICT = 10042, + ICAL_TRANSP_NONE = 10043 } icalproperty_transp; -#define ICALPROPERTY_LAST_ENUM 10042 +typedef enum icalproperty_xlicclass { + ICAL_XLICCLASS_X = 10044, + ICAL_XLICCLASS_PUBLISHNEW = 10045, + ICAL_XLICCLASS_PUBLISHUPDATE = 10046, + ICAL_XLICCLASS_PUBLISHFREEBUSY = 10047, + ICAL_XLICCLASS_REQUESTNEW = 10048, + ICAL_XLICCLASS_REQUESTUPDATE = 10049, + ICAL_XLICCLASS_REQUESTRESCHEDULE = 10050, + ICAL_XLICCLASS_REQUESTDELEGATE = 10051, + ICAL_XLICCLASS_REQUESTNEWORGANIZER = 10052, + ICAL_XLICCLASS_REQUESTFORWARD = 10053, + ICAL_XLICCLASS_REQUESTSTATUS = 10054, + ICAL_XLICCLASS_REQUESTFREEBUSY = 10055, + ICAL_XLICCLASS_REPLYACCEPT = 10056, + ICAL_XLICCLASS_REPLYDECLINE = 10057, + ICAL_XLICCLASS_REPLYDELEGATE = 10058, + ICAL_XLICCLASS_REPLYCRASHERACCEPT = 10059, + ICAL_XLICCLASS_REPLYCRASHERDECLINE = 10060, + ICAL_XLICCLASS_ADDINSTANCE = 10061, + ICAL_XLICCLASS_CANCELEVENT = 10062, + ICAL_XLICCLASS_CANCELINSTANCE = 10063, + ICAL_XLICCLASS_CANCELALL = 10064, + ICAL_XLICCLASS_REFRESH = 10065, + ICAL_XLICCLASS_COUNTER = 10066, + ICAL_XLICCLASS_DECLINECOUNTER = 10067, + ICAL_XLICCLASS_MALFORMED = 10068, + ICAL_XLICCLASS_OBSOLETE = 10069, + ICAL_XLICCLASS_MISSEQUENCED = 10070, + ICAL_XLICCLASS_UNKNOWN = 10071, + ICAL_XLICCLASS_NONE = 10072 +} icalproperty_xlicclass; + +#define ICALPROPERTY_LAST_ENUM 10073 /* QUERY */ icalvalue* icalvalue_new_query(const char* v); -const char* icalvalue_get_query(icalvalue* value); +const char* icalvalue_get_query(const icalvalue* value); void icalvalue_set_query(icalvalue* value, const char* v); + /* DATE */ +icalvalue* icalvalue_new_date(struct icaltimetype v); +struct icaltimetype icalvalue_get_date(const icalvalue* value); +void icalvalue_set_date(icalvalue* value, struct icaltimetype v); + + + /* GEO */ +icalvalue* icalvalue_new_geo(struct icalgeotype v); +struct icalgeotype icalvalue_get_geo(const icalvalue* value); +void icalvalue_set_geo(icalvalue* value, struct icalgeotype v); + + /* STATUS */ icalvalue* icalvalue_new_status(enum icalproperty_status v); -enum icalproperty_status icalvalue_get_status(icalvalue* value); +enum icalproperty_status icalvalue_get_status(const icalvalue* value); void icalvalue_set_status(icalvalue* value, enum icalproperty_status v); /* TRANSP */ icalvalue* icalvalue_new_transp(enum icalproperty_transp v); -enum icalproperty_transp icalvalue_get_transp(icalvalue* value); +enum icalproperty_transp icalvalue_get_transp(const icalvalue* value); void icalvalue_set_transp(icalvalue* value, enum icalproperty_transp v); - /* CLASS */ -icalvalue* icalvalue_new_class(enum icalproperty_class v); -enum icalproperty_class icalvalue_get_class(icalvalue* value); -void icalvalue_set_class(icalvalue* value, enum icalproperty_class v); + /* STRING */ +icalvalue* icalvalue_new_string(const char* v); +const char* icalvalue_get_string(const icalvalue* value); +void icalvalue_set_string(icalvalue* value, const char* v); - /* DATE */ -icalvalue* icalvalue_new_date(struct icaltimetype v); -struct icaltimetype icalvalue_get_date(icalvalue* value); -void icalvalue_set_date(icalvalue* value, struct icaltimetype v); + /* TEXT */ +icalvalue* icalvalue_new_text(const char* v); +const char* icalvalue_get_text(const icalvalue* value); +void icalvalue_set_text(icalvalue* value, const char* v); - /* STRING */ -icalvalue* icalvalue_new_string(const char* v); -const char* icalvalue_get_string(icalvalue* value); -void icalvalue_set_string(icalvalue* value, const char* v); + /* REQUEST-STATUS */ +icalvalue* icalvalue_new_requeststatus(struct icalreqstattype v); +struct icalreqstattype icalvalue_get_requeststatus(const icalvalue* value); +void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v); - /* INTEGER */ -icalvalue* icalvalue_new_integer(int v); -int icalvalue_get_integer(icalvalue* value); -void icalvalue_set_integer(icalvalue* value, int v); + /* BINARY */ +icalvalue* icalvalue_new_binary(const char* v); +const char* icalvalue_get_binary(const icalvalue* value); +void icalvalue_set_binary(icalvalue* value, const char* v); /* PERIOD */ icalvalue* icalvalue_new_period(struct icalperiodtype v); -struct icalperiodtype icalvalue_get_period(icalvalue* value); +struct icalperiodtype icalvalue_get_period(const icalvalue* value); void icalvalue_set_period(icalvalue* value, struct icalperiodtype v); - /* TEXT */ -icalvalue* icalvalue_new_text(const char* v); -const char* icalvalue_get_text(icalvalue* value); -void icalvalue_set_text(icalvalue* value, const char* v); + /* FLOAT */ +icalvalue* icalvalue_new_float(float v); +float icalvalue_get_float(const icalvalue* value); +void icalvalue_set_float(icalvalue* value, float v); - /* DURATION */ -icalvalue* icalvalue_new_duration(struct icaldurationtype v); -struct icaldurationtype icalvalue_get_duration(icalvalue* value); -void icalvalue_set_duration(icalvalue* value, struct icaldurationtype v); + /* INTEGER */ +icalvalue* icalvalue_new_integer(int v); +int icalvalue_get_integer(const icalvalue* value); +void icalvalue_set_integer(icalvalue* value, int v); - /* BOOLEAN */ -icalvalue* icalvalue_new_boolean(int v); -int icalvalue_get_boolean(icalvalue* value); -void icalvalue_set_boolean(icalvalue* value, int v); + /* CLASS */ +icalvalue* icalvalue_new_class(enum icalproperty_class v); +enum icalproperty_class icalvalue_get_class(const icalvalue* value); +void icalvalue_set_class(icalvalue* value, enum icalproperty_class v); /* URI */ icalvalue* icalvalue_new_uri(const char* v); -const char* icalvalue_get_uri(icalvalue* value); +const char* icalvalue_get_uri(const icalvalue* value); void icalvalue_set_uri(icalvalue* value, const char* v); - /* GEO */ -icalvalue* icalvalue_new_geo(struct icalgeotype v); -struct icalgeotype icalvalue_get_geo(icalvalue* value); -void icalvalue_set_geo(icalvalue* value, struct icalgeotype v); + /* DURATION */ +icalvalue* icalvalue_new_duration(struct icaldurationtype v); +struct icaldurationtype icalvalue_get_duration(const icalvalue* value); +void icalvalue_set_duration(icalvalue* value, struct icaldurationtype v); - /* DATE-TIME */ -icalvalue* icalvalue_new_datetime(struct icaltimetype v); -struct icaltimetype icalvalue_get_datetime(icalvalue* value); -void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); + /* BOOLEAN */ +icalvalue* icalvalue_new_boolean(int v); +int icalvalue_get_boolean(const icalvalue* value); +void icalvalue_set_boolean(icalvalue* value, int v); - /* UTC-OFFSET */ -icalvalue* icalvalue_new_utcoffset(int v); -int icalvalue_get_utcoffset(icalvalue* value); -void icalvalue_set_utcoffset(icalvalue* value, int v); + /* CAL-ADDRESS */ +icalvalue* icalvalue_new_caladdress(const char* v); +const char* icalvalue_get_caladdress(const icalvalue* value); +void icalvalue_set_caladdress(icalvalue* value, const char* v); + + + /* X-LIC-CLASS */ +icalvalue* icalvalue_new_xlicclass(enum icalproperty_xlicclass v); +enum icalproperty_xlicclass icalvalue_get_xlicclass(const icalvalue* value); +void icalvalue_set_xlicclass(icalvalue* value, enum icalproperty_xlicclass v); /* ACTION */ icalvalue* icalvalue_new_action(enum icalproperty_action v); -enum icalproperty_action icalvalue_get_action(icalvalue* value); +enum icalproperty_action icalvalue_get_action(const icalvalue* value); void icalvalue_set_action(icalvalue* value, enum icalproperty_action v); - /* CAL-ADDRESS */ -icalvalue* icalvalue_new_caladdress(const char* v); -const char* icalvalue_get_caladdress(icalvalue* value); -void icalvalue_set_caladdress(icalvalue* value, const char* v); - - - /* FLOAT */ -icalvalue* icalvalue_new_float(float v); -float icalvalue_get_float(icalvalue* value); -void icalvalue_set_float(icalvalue* value, float v); + /* DATE-TIME */ +icalvalue* icalvalue_new_datetime(struct icaltimetype v); +struct icaltimetype icalvalue_get_datetime(const icalvalue* value); +void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); - /* REQUEST-STATUS */ -icalvalue* icalvalue_new_requeststatus(struct icalreqstattype v); -struct icalreqstattype icalvalue_get_requeststatus(icalvalue* value); -void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v); + /* UTC-OFFSET */ +icalvalue* icalvalue_new_utcoffset(int v); +int icalvalue_get_utcoffset(const icalvalue* value); +void icalvalue_set_utcoffset(icalvalue* value, int v); /* METHOD */ icalvalue* icalvalue_new_method(enum icalproperty_method v); -enum icalproperty_method icalvalue_get_method(icalvalue* value); +enum icalproperty_method icalvalue_get_method(const icalvalue* value); void icalvalue_set_method(icalvalue* value, enum icalproperty_method v); - - /* BINARY */ -icalvalue* icalvalue_new_binary(const char* v); -const char* icalvalue_get_binary(icalvalue* value); -void icalvalue_set_binary(icalvalue* value, const char* v); - #endif /*ICALVALUE_H*/ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalparam.h CREATOR: eric 20 March 1999 - $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 icalparam.h ======================================================================*/ #ifndef ICALDERIVEDPARAMETER_H #define ICALDERIVEDPARAMETER_H -typedef void icalparameter; +typedef struct icalparameter_impl icalparameter; const char* icalparameter_enum_to_string(int e); int icalparameter_string_to_enum(const char* str); -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalparameter_kind { ICAL_ANY_PARAMETER = 0, ICAL_ALTREP_PARAMETER, ICAL_CN_PARAMETER, ICAL_CUTYPE_PARAMETER, ICAL_DELEGATEDFROM_PARAMETER, ICAL_DELEGATEDTO_PARAMETER, ICAL_DIR_PARAMETER, ICAL_ENCODING_PARAMETER, ICAL_FBTYPE_PARAMETER, ICAL_FMTTYPE_PARAMETER, ICAL_LANGUAGE_PARAMETER, ICAL_MEMBER_PARAMETER, ICAL_PARTSTAT_PARAMETER, ICAL_RANGE_PARAMETER, ICAL_RELATED_PARAMETER, ICAL_RELTYPE_PARAMETER, ICAL_ROLE_PARAMETER, ICAL_RSVP_PARAMETER, ICAL_SENTBY_PARAMETER, ICAL_TZID_PARAMETER, ICAL_VALUE_PARAMETER, ICAL_X_PARAMETER, ICAL_XLICCOMPARETYPE_PARAMETER, ICAL_XLICERRORTYPE_PARAMETER, ICAL_NO_PARAMETER } icalparameter_kind; #define ICALPARAMETER_FIRST_ENUM 20000 typedef enum icalparameter_cutype { ICAL_CUTYPE_X = 20000, ICAL_CUTYPE_INDIVIDUAL = 20001, ICAL_CUTYPE_GROUP = 20002, ICAL_CUTYPE_RESOURCE = 20003, ICAL_CUTYPE_ROOM = 20004, ICAL_CUTYPE_UNKNOWN = 20005, ICAL_CUTYPE_NONE = 20006 } icalparameter_cutype; typedef enum icalparameter_encoding { ICAL_ENCODING_X = 20007, ICAL_ENCODING_8BIT = 20008, ICAL_ENCODING_BASE64 = 20009, ICAL_ENCODING_NONE = 20010 } icalparameter_encoding; typedef enum icalparameter_fbtype { ICAL_FBTYPE_X = 20011, ICAL_FBTYPE_FREE = 20012, ICAL_FBTYPE_BUSY = 20013, ICAL_FBTYPE_BUSYUNAVAILABLE = 20014, ICAL_FBTYPE_BUSYTENTATIVE = 20015, ICAL_FBTYPE_NONE = 20016 } icalparameter_fbtype; typedef enum icalparameter_partstat { ICAL_PARTSTAT_X = 20017, ICAL_PARTSTAT_NEEDSACTION = 20018, ICAL_PARTSTAT_ACCEPTED = 20019, ICAL_PARTSTAT_DECLINED = 20020, ICAL_PARTSTAT_TENTATIVE = 20021, ICAL_PARTSTAT_DELEGATED = 20022, ICAL_PARTSTAT_COMPLETED = 20023, ICAL_PARTSTAT_INPROCESS = 20024, ICAL_PARTSTAT_NONE = 20025 } icalparameter_partstat; typedef enum icalparameter_range { ICAL_RANGE_X = 20026, ICAL_RANGE_THISANDPRIOR = 20027, ICAL_RANGE_THISANDFUTURE = 20028, ICAL_RANGE_NONE = 20029 } icalparameter_range; typedef enum icalparameter_related { ICAL_RELATED_X = 20030, ICAL_RELATED_START = 20031, - ICAL_RELATED_END = 20032, + ICAL_RELATED_END = 20032, ICAL_RELATED_NONE = 20033 } icalparameter_related; typedef enum icalparameter_reltype { ICAL_RELTYPE_X = 20034, ICAL_RELTYPE_PARENT = 20035, ICAL_RELTYPE_CHILD = 20036, ICAL_RELTYPE_SIBLING = 20037, ICAL_RELTYPE_NONE = 20038 } icalparameter_reltype; typedef enum icalparameter_role { ICAL_ROLE_X = 20039, ICAL_ROLE_CHAIR = 20040, ICAL_ROLE_REQPARTICIPANT = 20041, ICAL_ROLE_OPTPARTICIPANT = 20042, ICAL_ROLE_NONPARTICIPANT = 20043, ICAL_ROLE_NONE = 20044 } icalparameter_role; typedef enum icalparameter_rsvp { ICAL_RSVP_X = 20045, ICAL_RSVP_TRUE = 20046, ICAL_RSVP_FALSE = 20047, ICAL_RSVP_NONE = 20048 } icalparameter_rsvp; typedef enum icalparameter_value { ICAL_VALUE_X = 20049, ICAL_VALUE_BINARY = 20050, ICAL_VALUE_BOOLEAN = 20051, ICAL_VALUE_DATE = 20052, ICAL_VALUE_DURATION = 20053, ICAL_VALUE_FLOAT = 20054, ICAL_VALUE_INTEGER = 20055, ICAL_VALUE_PERIOD = 20056, ICAL_VALUE_RECUR = 20057, ICAL_VALUE_TEXT = 20058, ICAL_VALUE_URI = 20059, ICAL_VALUE_ERROR = 20060, ICAL_VALUE_DATETIME = 20061, ICAL_VALUE_UTCOFFSET = 20062, ICAL_VALUE_CALADDRESS = 20063, ICAL_VALUE_NONE = 20064 } icalparameter_value; typedef enum icalparameter_xliccomparetype { ICAL_XLICCOMPARETYPE_X = 20065, ICAL_XLICCOMPARETYPE_EQUAL = 20066, ICAL_XLICCOMPARETYPE_NOTEQUAL = 20067, ICAL_XLICCOMPARETYPE_LESS = 20068, ICAL_XLICCOMPARETYPE_GREATER = 20069, ICAL_XLICCOMPARETYPE_LESSEQUAL = 20070, ICAL_XLICCOMPARETYPE_GREATEREQUAL = 20071, ICAL_XLICCOMPARETYPE_REGEX = 20072, - ICAL_XLICCOMPARETYPE_NONE = 20073 + ICAL_XLICCOMPARETYPE_ISNULL = 20073, + ICAL_XLICCOMPARETYPE_ISNOTNULL = 20074, + ICAL_XLICCOMPARETYPE_NONE = 20075 } icalparameter_xliccomparetype; typedef enum icalparameter_xlicerrortype { - ICAL_XLICERRORTYPE_X = 20074, - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR = 20075, - ICAL_XLICERRORTYPE_PROPERTYPARSEERROR = 20076, - ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR = 20077, - ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR = 20078, - ICAL_XLICERRORTYPE_VALUEPARSEERROR = 20079, - ICAL_XLICERRORTYPE_INVALIDITIP = 20080, - ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR = 20081, - ICAL_XLICERRORTYPE_MIMEPARSEERROR = 20082, - ICAL_XLICERRORTYPE_NONE = 20083 + ICAL_XLICERRORTYPE_X = 20076, + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR = 20077, + ICAL_XLICERRORTYPE_PROPERTYPARSEERROR = 20078, + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR = 20079, + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR = 20080, + ICAL_XLICERRORTYPE_VALUEPARSEERROR = 20081, + ICAL_XLICERRORTYPE_INVALIDITIP = 20082, + ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR = 20083, + ICAL_XLICERRORTYPE_MIMEPARSEERROR = 20084, + ICAL_XLICERRORTYPE_VCALPROPPARSEERROR = 20085, + ICAL_XLICERRORTYPE_NONE = 20086 } icalparameter_xlicerrortype; -#define ICALPARAMETER_LAST_ENUM 20084 +#define ICALPARAMETER_LAST_ENUM 20087 -/* DELEGATED-FROM */ -icalparameter* icalparameter_new_delegatedfrom(const char* v); -const char* icalparameter_get_delegatedfrom(icalparameter* value); -void icalparameter_set_delegatedfrom(icalparameter* value, const char* v); - -/* DELEGATED-TO */ -icalparameter* icalparameter_new_delegatedto(const char* v); -const char* icalparameter_get_delegatedto(icalparameter* value); -void icalparameter_set_delegatedto(icalparameter* value, const char* v); - -/* RANGE */ -icalparameter* icalparameter_new_range(icalparameter_range v); -icalparameter_range icalparameter_get_range(icalparameter* value); -void icalparameter_set_range(icalparameter* value, icalparameter_range v); - -/* ENCODING */ -icalparameter* icalparameter_new_encoding(icalparameter_encoding v); -icalparameter_encoding icalparameter_get_encoding(icalparameter* value); -void icalparameter_set_encoding(icalparameter* value, icalparameter_encoding v); - -/* RSVP */ -icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v); -icalparameter_rsvp icalparameter_get_rsvp(icalparameter* value); -void icalparameter_set_rsvp(icalparameter* value, icalparameter_rsvp v); +/* LANGUAGE */ +icalparameter* icalparameter_new_language(const char* v); +const char* icalparameter_get_language(const icalparameter* value); +void icalparameter_set_language(icalparameter* value, const char* v); -/* PARTSTAT */ -icalparameter* icalparameter_new_partstat(icalparameter_partstat v); -icalparameter_partstat icalparameter_get_partstat(icalparameter* value); -void icalparameter_set_partstat(icalparameter* value, icalparameter_partstat v); +/* DIR */ +icalparameter* icalparameter_new_dir(const char* v); +const char* icalparameter_get_dir(const icalparameter* value); +void icalparameter_set_dir(icalparameter* value, const char* v); /* RELTYPE */ icalparameter* icalparameter_new_reltype(icalparameter_reltype v); -icalparameter_reltype icalparameter_get_reltype(icalparameter* value); +icalparameter_reltype icalparameter_get_reltype(const icalparameter* value); void icalparameter_set_reltype(icalparameter* value, icalparameter_reltype v); -/* CUTYPE */ -icalparameter* icalparameter_new_cutype(icalparameter_cutype v); -icalparameter_cutype icalparameter_get_cutype(icalparameter* value); -void icalparameter_set_cutype(icalparameter* value, icalparameter_cutype v); - -/* MEMBER */ -icalparameter* icalparameter_new_member(const char* v); -const char* icalparameter_get_member(icalparameter* value); -void icalparameter_set_member(icalparameter* value, const char* v); - /* FMTTYPE */ icalparameter* icalparameter_new_fmttype(const char* v); -const char* icalparameter_get_fmttype(icalparameter* value); +const char* icalparameter_get_fmttype(const icalparameter* value); void icalparameter_set_fmttype(icalparameter* value, const char* v); -/* SENT-BY */ -icalparameter* icalparameter_new_sentby(const char* v); -const char* icalparameter_get_sentby(icalparameter* value); -void icalparameter_set_sentby(icalparameter* value, const char* v); +/* TZID */ +icalparameter* icalparameter_new_tzid(const char* v); +const char* icalparameter_get_tzid(const icalparameter* value); +void icalparameter_set_tzid(icalparameter* value, const char* v); + +/* RANGE */ +icalparameter* icalparameter_new_range(icalparameter_range v); +icalparameter_range icalparameter_get_range(const icalparameter* value); +void icalparameter_set_range(icalparameter* value, icalparameter_range v); + +/* DELEGATED-TO */ +icalparameter* icalparameter_new_delegatedto(const char* v); +const char* icalparameter_get_delegatedto(const icalparameter* value); +void icalparameter_set_delegatedto(icalparameter* value, const char* v); + +/* CN */ +icalparameter* icalparameter_new_cn(const char* v); +const char* icalparameter_get_cn(const icalparameter* value); +void icalparameter_set_cn(icalparameter* value, const char* v); /* VALUE */ icalparameter* icalparameter_new_value(icalparameter_value v); -icalparameter_value icalparameter_get_value(icalparameter* value); +icalparameter_value icalparameter_get_value(const icalparameter* value); void icalparameter_set_value(icalparameter* value, icalparameter_value v); -/* ALTREP */ -icalparameter* icalparameter_new_altrep(const char* v); -const char* icalparameter_get_altrep(icalparameter* value); -void icalparameter_set_altrep(icalparameter* value, const char* v); +/* X-LIC-COMPARETYPE */ +icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v); +icalparameter_xliccomparetype icalparameter_get_xliccomparetype(const icalparameter* value); +void icalparameter_set_xliccomparetype(icalparameter* value, icalparameter_xliccomparetype v); -/* DIR */ -icalparameter* icalparameter_new_dir(const char* v); -const char* icalparameter_get_dir(icalparameter* value); -void icalparameter_set_dir(icalparameter* value, const char* v); +/* X */ +icalparameter* icalparameter_new_x(const char* v); +const char* icalparameter_get_x(const icalparameter* value); +void icalparameter_set_x(icalparameter* value, const char* v); -/* RELATED */ -icalparameter* icalparameter_new_related(icalparameter_related v); -icalparameter_related icalparameter_get_related(icalparameter* value); -void icalparameter_set_related(icalparameter* value, icalparameter_related v); +/* SENT-BY */ +icalparameter* icalparameter_new_sentby(const char* v); +const char* icalparameter_get_sentby(const icalparameter* value); +void icalparameter_set_sentby(icalparameter* value, const char* v); -/* CN */ -icalparameter* icalparameter_new_cn(const char* v); -const char* icalparameter_get_cn(icalparameter* value); -void icalparameter_set_cn(icalparameter* value, const char* v); +/* MEMBER */ +icalparameter* icalparameter_new_member(const char* v); +const char* icalparameter_get_member(const icalparameter* value); +void icalparameter_set_member(icalparameter* value, const char* v); + +/* RSVP */ +icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v); +icalparameter_rsvp icalparameter_get_rsvp(const icalparameter* value); +void icalparameter_set_rsvp(icalparameter* value, icalparameter_rsvp v); + +/* CUTYPE */ +icalparameter* icalparameter_new_cutype(icalparameter_cutype v); +icalparameter_cutype icalparameter_get_cutype(const icalparameter* value); +void icalparameter_set_cutype(icalparameter* value, icalparameter_cutype v); /* X-LIC-ERRORTYPE */ icalparameter* icalparameter_new_xlicerrortype(icalparameter_xlicerrortype v); -icalparameter_xlicerrortype icalparameter_get_xlicerrortype(icalparameter* value); +icalparameter_xlicerrortype icalparameter_get_xlicerrortype(const icalparameter* value); void icalparameter_set_xlicerrortype(icalparameter* value, icalparameter_xlicerrortype v); -/* X */ -icalparameter* icalparameter_new_x(const char* v); -const char* icalparameter_get_x(icalparameter* value); -void icalparameter_set_x(icalparameter* value, const char* v); +/* RELATED */ +icalparameter* icalparameter_new_related(icalparameter_related v); +icalparameter_related icalparameter_get_related(const icalparameter* value); +void icalparameter_set_related(icalparameter* value, icalparameter_related v); -/* LANGUAGE */ -icalparameter* icalparameter_new_language(const char* v); -const char* icalparameter_get_language(icalparameter* value); -void icalparameter_set_language(icalparameter* value, const char* v); +/* ENCODING */ +icalparameter* icalparameter_new_encoding(icalparameter_encoding v); +icalparameter_encoding icalparameter_get_encoding(const icalparameter* value); +void icalparameter_set_encoding(icalparameter* value, icalparameter_encoding v); -/* ROLE */ -icalparameter* icalparameter_new_role(icalparameter_role v); -icalparameter_role icalparameter_get_role(icalparameter* value); -void icalparameter_set_role(icalparameter* value, icalparameter_role v); +/* ALTREP */ +icalparameter* icalparameter_new_altrep(const char* v); +const char* icalparameter_get_altrep(const icalparameter* value); +void icalparameter_set_altrep(icalparameter* value, const char* v); -/* X-LIC-COMPARETYPE */ -icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v); -icalparameter_xliccomparetype icalparameter_get_xliccomparetype(icalparameter* value); -void icalparameter_set_xliccomparetype(icalparameter* value, icalparameter_xliccomparetype v); +/* DELEGATED-FROM */ +icalparameter* icalparameter_new_delegatedfrom(const char* v); +const char* icalparameter_get_delegatedfrom(const icalparameter* value); +void icalparameter_set_delegatedfrom(icalparameter* value, const char* v); /* FBTYPE */ icalparameter* icalparameter_new_fbtype(icalparameter_fbtype v); -icalparameter_fbtype icalparameter_get_fbtype(icalparameter* value); +icalparameter_fbtype icalparameter_get_fbtype(const icalparameter* value); void icalparameter_set_fbtype(icalparameter* value, icalparameter_fbtype v); -/* TZID */ -icalparameter* icalparameter_new_tzid(const char* v); -const char* icalparameter_get_tzid(icalparameter* value); -void icalparameter_set_tzid(icalparameter* value, const char* v); +/* ROLE */ +icalparameter* icalparameter_new_role(icalparameter_role v); +icalparameter_role icalparameter_get_role(const icalparameter* value); +void icalparameter_set_role(icalparameter* value, icalparameter_role v); + +/* PARTSTAT */ +icalparameter* icalparameter_new_partstat(icalparameter_partstat v); +icalparameter_partstat icalparameter_get_partstat(const icalparameter* value); +void icalparameter_set_partstat(icalparameter* value, icalparameter_partstat v); #endif /*ICALPARAMETER_H*/ +/* Everything below this line is machine generated. Do not edit. */ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalvalue.h + CREATOR: eric 20 March 1999 + + + + (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 icalvalue.h + + ======================================================================*/ + +#ifndef ICALVALUE_H +#define ICALVALUE_H + +#include <time.h> + +/* Defined in icalderivedvalue.h */ +/*typedef struct icalvalue_impl icalvalue;*/ + +icalvalue* icalvalue_new(icalvalue_kind kind); + +icalvalue* icalvalue_new_clone(const icalvalue* value); + +icalvalue* icalvalue_new_from_string(icalvalue_kind kind, const char* str); + +void icalvalue_free(icalvalue* value); + +int icalvalue_is_valid(const icalvalue* value); + +const char* icalvalue_as_ical_string(const icalvalue* value); + +icalvalue_kind icalvalue_isa(const icalvalue* value); + +int icalvalue_isa_value(void*); + +icalparameter_xliccomparetype icalvalue_compare(const icalvalue* a, const icalvalue *b); + + +/* Special, non autogenerated value accessors */ + +icalvalue* icalvalue_new_recur (struct icalrecurrencetype v); +void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); +struct icalrecurrencetype icalvalue_get_recur(const icalvalue* value); + +icalvalue* icalvalue_new_trigger (struct icaltriggertype v); +void icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v); +struct icaltriggertype icalvalue_get_trigger(const icalvalue* value); + +icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); +void icalvalue_set_datetimeperiod(icalvalue* value, + struct icaldatetimeperiodtype v); +struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(const icalvalue* value); + +/* Convert enumerations */ + +icalvalue_kind icalvalue_string_to_kind(const char* str); +const char* icalvalue_kind_to_string(const icalvalue_kind kind); + +/** Check validity of a specific icalvalue_kind **/ +int icalvalue_kind_is_valid(const icalvalue_kind kind); + +/** Encode a character string in ical format, esacpe certain characters, etc. */ +int icalvalue_encode_ical_string(const char *szText, char *szEncText, int MaxBufferLen); + +#endif /*ICALVALUE_H*/ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalparam.h + CREATOR: eric 20 March 1999 + + + + + + (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 icalparam.h + + ======================================================================*/ + +#ifndef ICALPARAM_H +#define ICALPARAM_H + + +/* Declared in icalderivedparameter.h */ +/*typedef struct icalparameter_impl icalparameter;*/ + +icalparameter* icalparameter_new(icalparameter_kind kind); +icalparameter* icalparameter_new_clone(icalparameter* p); + +/* Create from string of form "PARAMNAME=VALUE" */ +icalparameter* icalparameter_new_from_string(const char* value); + +/* Create from just the value, the part after the "=" */ +icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind, const char* value); + +void icalparameter_free(icalparameter* parameter); + +char* icalparameter_as_ical_string(icalparameter* parameter); + +int icalparameter_is_valid(icalparameter* parameter); + +icalparameter_kind icalparameter_isa(icalparameter* parameter); + +int icalparameter_isa_parameter(void* param); + +/* Acess the name of an X parameer */ +void icalparameter_set_xname (icalparameter* param, const char* v); +const char* icalparameter_get_xname(icalparameter* param); +void icalparameter_set_xvalue (icalparameter* param, const char* v); +const char* icalparameter_get_xvalue(icalparameter* param); + +/* Convert enumerations */ + +const char* icalparameter_kind_to_string(icalparameter_kind kind); +icalparameter_kind icalparameter_string_to_kind(const char* string); + + + +#endif /* -*- Mode: C -*- ====================================================================== FILE: icalderivedproperties.{c,h} CREATOR: eric 09 May 1999 - $Id$ (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef ICALDERIVEDPROPERTY_H #define ICALDERIVEDPROPERTY_H #include <time.h> -typedef void icalproperty; +typedef struct icalproperty_impl icalproperty; - -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalproperty_kind { ICAL_ANY_PROPERTY = 0, ICAL_ACTION_PROPERTY, + ICAL_ALLOWCONFLICT_PROPERTY, ICAL_ATTACH_PROPERTY, ICAL_ATTENDEE_PROPERTY, + ICAL_CALID_PROPERTY, + ICAL_CALMASTER_PROPERTY, ICAL_CALSCALE_PROPERTY, + ICAL_CARID_PROPERTY, ICAL_CATEGORIES_PROPERTY, ICAL_CLASS_PROPERTY, ICAL_COMMENT_PROPERTY, ICAL_COMPLETED_PROPERTY, ICAL_CONTACT_PROPERTY, ICAL_CREATED_PROPERTY, + ICAL_DECREED_PROPERTY, + ICAL_DEFAULTCHARSET_PROPERTY, + ICAL_DEFAULTLOCALE_PROPERTY, + ICAL_DEFAULTTZID_PROPERTY, ICAL_DESCRIPTION_PROPERTY, ICAL_DTEND_PROPERTY, ICAL_DTSTAMP_PROPERTY, ICAL_DTSTART_PROPERTY, ICAL_DUE_PROPERTY, ICAL_DURATION_PROPERTY, ICAL_EXDATE_PROPERTY, + ICAL_EXPAND_PROPERTY, ICAL_EXRULE_PROPERTY, ICAL_FREEBUSY_PROPERTY, ICAL_GEO_PROPERTY, ICAL_LASTMODIFIED_PROPERTY, ICAL_LOCATION_PROPERTY, ICAL_MAXRESULTS_PROPERTY, ICAL_MAXRESULTSSIZE_PROPERTY, ICAL_METHOD_PROPERTY, ICAL_ORGANIZER_PROPERTY, + ICAL_OWNER_PROPERTY, ICAL_PERCENTCOMPLETE_PROPERTY, ICAL_PRIORITY_PROPERTY, ICAL_PRODID_PROPERTY, ICAL_QUERY_PROPERTY, ICAL_QUERYNAME_PROPERTY, ICAL_RDATE_PROPERTY, ICAL_RECURRENCEID_PROPERTY, ICAL_RELATEDTO_PROPERTY, + ICAL_RELCALID_PROPERTY, ICAL_REPEAT_PROPERTY, ICAL_REQUESTSTATUS_PROPERTY, ICAL_RESOURCES_PROPERTY, ICAL_RRULE_PROPERTY, ICAL_SCOPE_PROPERTY, ICAL_SEQUENCE_PROPERTY, ICAL_STATUS_PROPERTY, ICAL_SUMMARY_PROPERTY, ICAL_TARGET_PROPERTY, ICAL_TRANSP_PROPERTY, ICAL_TRIGGER_PROPERTY, ICAL_TZID_PROPERTY, ICAL_TZNAME_PROPERTY, ICAL_TZOFFSETFROM_PROPERTY, ICAL_TZOFFSETTO_PROPERTY, ICAL_TZURL_PROPERTY, ICAL_UID_PROPERTY, ICAL_URL_PROPERTY, ICAL_VERSION_PROPERTY, ICAL_X_PROPERTY, + ICAL_XLICCLASS_PROPERTY, ICAL_XLICCLUSTERCOUNT_PROPERTY, ICAL_XLICERROR_PROPERTY, ICAL_XLICMIMECHARSET_PROPERTY, ICAL_XLICMIMECID_PROPERTY, ICAL_XLICMIMECONTENTTYPE_PROPERTY, ICAL_XLICMIMEENCODING_PROPERTY, ICAL_XLICMIMEFILENAME_PROPERTY, ICAL_XLICMIMEOPTINFO_PROPERTY, ICAL_NO_PROPERTY } icalproperty_kind; -icalproperty* icalproperty_vanew_action(enum icalproperty_action v, ...); /* ACTION */ icalproperty* icalproperty_new_action(enum icalproperty_action v); void icalproperty_set_action(icalproperty* prop, enum icalproperty_action v); -enum icalproperty_action icalproperty_get_action(icalproperty* prop);icalproperty* icalproperty_vanew_attach(struct icalattachtype* v, ...); +enum icalproperty_action icalproperty_get_action(const icalproperty* prop);icalproperty* icalproperty_vanew_action(enum icalproperty_action v, ...); + +/* ALLOW-CONFLICT */ +icalproperty* icalproperty_new_allowconflict(const char* v); +void icalproperty_set_allowconflict(icalproperty* prop, const char* v); +const char* icalproperty_get_allowconflict(const icalproperty* prop);icalproperty* icalproperty_vanew_allowconflict(const char* v, ...); /* ATTACH */ -icalproperty* icalproperty_new_attach(struct icalattachtype* v); -void icalproperty_set_attach(icalproperty* prop, struct icalattachtype* v); -struct icalattachtype* icalproperty_get_attach(icalproperty* prop);icalproperty* icalproperty_vanew_attendee(const char* v, ...); +icalproperty* icalproperty_new_attach(icalattach * v); +void icalproperty_set_attach(icalproperty* prop, icalattach * v); +icalattach * icalproperty_get_attach(const icalproperty* prop);icalproperty* icalproperty_vanew_attach(icalattach * v, ...); /* ATTENDEE */ icalproperty* icalproperty_new_attendee(const char* v); void icalproperty_set_attendee(icalproperty* prop, const char* v); -const char* icalproperty_get_attendee(icalproperty* prop);icalproperty* icalproperty_vanew_calscale(const char* v, ...); +const char* icalproperty_get_attendee(const icalproperty* prop);icalproperty* icalproperty_vanew_attendee(const char* v, ...); + +/* CALID */ +icalproperty* icalproperty_new_calid(const char* v); +void icalproperty_set_calid(icalproperty* prop, const char* v); +const char* icalproperty_get_calid(const icalproperty* prop);icalproperty* icalproperty_vanew_calid(const char* v, ...); + +/* CALMASTER */ +icalproperty* icalproperty_new_calmaster(const char* v); +void icalproperty_set_calmaster(icalproperty* prop, const char* v); +const char* icalproperty_get_calmaster(const icalproperty* prop);icalproperty* icalproperty_vanew_calmaster(const char* v, ...); /* CALSCALE */ icalproperty* icalproperty_new_calscale(const char* v); void icalproperty_set_calscale(icalproperty* prop, const char* v); -const char* icalproperty_get_calscale(icalproperty* prop);icalproperty* icalproperty_vanew_categories(const char* v, ...); +const char* icalproperty_get_calscale(const icalproperty* prop);icalproperty* icalproperty_vanew_calscale(const char* v, ...); + +/* CARID */ +icalproperty* icalproperty_new_carid(const char* v); +void icalproperty_set_carid(icalproperty* prop, const char* v); +const char* icalproperty_get_carid(const icalproperty* prop);icalproperty* icalproperty_vanew_carid(const char* v, ...); /* CATEGORIES */ icalproperty* icalproperty_new_categories(const char* v); void icalproperty_set_categories(icalproperty* prop, const char* v); -const char* icalproperty_get_categories(icalproperty* prop);icalproperty* icalproperty_vanew_class(const char* v, ...); +const char* icalproperty_get_categories(const icalproperty* prop);icalproperty* icalproperty_vanew_categories(const char* v, ...); /* CLASS */ -icalproperty* icalproperty_new_class(const char* v); -void icalproperty_set_class(icalproperty* prop, const char* v); -const char* icalproperty_get_class(icalproperty* prop);icalproperty* icalproperty_vanew_comment(const char* v, ...); +icalproperty* icalproperty_new_class(enum icalproperty_class v); +void icalproperty_set_class(icalproperty* prop, enum icalproperty_class v); +enum icalproperty_class icalproperty_get_class(const icalproperty* prop);icalproperty* icalproperty_vanew_class(enum icalproperty_class v, ...); /* COMMENT */ icalproperty* icalproperty_new_comment(const char* v); void icalproperty_set_comment(icalproperty* prop, const char* v); -const char* icalproperty_get_comment(icalproperty* prop);icalproperty* icalproperty_vanew_completed(struct icaltimetype v, ...); +const char* icalproperty_get_comment(const icalproperty* prop);icalproperty* icalproperty_vanew_comment(const char* v, ...); /* COMPLETED */ icalproperty* icalproperty_new_completed(struct icaltimetype v); void icalproperty_set_completed(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_completed(icalproperty* prop);icalproperty* icalproperty_vanew_contact(const char* v, ...); +struct icaltimetype icalproperty_get_completed(const icalproperty* prop);icalproperty* icalproperty_vanew_completed(struct icaltimetype v, ...); /* CONTACT */ icalproperty* icalproperty_new_contact(const char* v); void icalproperty_set_contact(icalproperty* prop, const char* v); -const char* icalproperty_get_contact(icalproperty* prop);icalproperty* icalproperty_vanew_created(struct icaltimetype v, ...); +const char* icalproperty_get_contact(const icalproperty* prop);icalproperty* icalproperty_vanew_contact(const char* v, ...); /* CREATED */ icalproperty* icalproperty_new_created(struct icaltimetype v); void icalproperty_set_created(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_created(icalproperty* prop);icalproperty* icalproperty_vanew_description(const char* v, ...); +struct icaltimetype icalproperty_get_created(const icalproperty* prop);icalproperty* icalproperty_vanew_created(struct icaltimetype v, ...); + +/* DECREED */ +icalproperty* icalproperty_new_decreed(const char* v); +void icalproperty_set_decreed(icalproperty* prop, const char* v); +const char* icalproperty_get_decreed(const icalproperty* prop);icalproperty* icalproperty_vanew_decreed(const char* v, ...); + +/* DEFAULT-CHARSET */ +icalproperty* icalproperty_new_defaultcharset(const char* v); +void icalproperty_set_defaultcharset(icalproperty* prop, const char* v); +const char* icalproperty_get_defaultcharset(const icalproperty* prop);icalproperty* icalproperty_vanew_defaultcharset(const char* v, ...); + +/* DEFAULT-LOCALE */ +icalproperty* icalproperty_new_defaultlocale(const char* v); +void icalproperty_set_defaultlocale(icalproperty* prop, const char* v); +const char* icalproperty_get_defaultlocale(const icalproperty* prop);icalproperty* icalproperty_vanew_defaultlocale(const char* v, ...); + +/* DEFAULT-TZID */ +icalproperty* icalproperty_new_defaulttzid(const char* v); +void icalproperty_set_defaulttzid(icalproperty* prop, const char* v); +const char* icalproperty_get_defaulttzid(const icalproperty* prop);icalproperty* icalproperty_vanew_defaulttzid(const char* v, ...); /* DESCRIPTION */ icalproperty* icalproperty_new_description(const char* v); void icalproperty_set_description(icalproperty* prop, const char* v); -const char* icalproperty_get_description(icalproperty* prop);icalproperty* icalproperty_vanew_dtend(struct icaltimetype v, ...); +const char* icalproperty_get_description(const icalproperty* prop);icalproperty* icalproperty_vanew_description(const char* v, ...); /* DTEND */ icalproperty* icalproperty_new_dtend(struct icaltimetype v); void icalproperty_set_dtend(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtend(icalproperty* prop);icalproperty* icalproperty_vanew_dtstamp(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtend(const icalproperty* prop);icalproperty* icalproperty_vanew_dtend(struct icaltimetype v, ...); /* DTSTAMP */ icalproperty* icalproperty_new_dtstamp(struct icaltimetype v); void icalproperty_set_dtstamp(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtstamp(icalproperty* prop);icalproperty* icalproperty_vanew_dtstart(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtstamp(const icalproperty* prop);icalproperty* icalproperty_vanew_dtstamp(struct icaltimetype v, ...); /* DTSTART */ icalproperty* icalproperty_new_dtstart(struct icaltimetype v); void icalproperty_set_dtstart(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtstart(icalproperty* prop);icalproperty* icalproperty_vanew_due(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtstart(const icalproperty* prop);icalproperty* icalproperty_vanew_dtstart(struct icaltimetype v, ...); /* DUE */ icalproperty* icalproperty_new_due(struct icaltimetype v); void icalproperty_set_due(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_due(icalproperty* prop);icalproperty* icalproperty_vanew_duration(struct icaldurationtype v, ...); +struct icaltimetype icalproperty_get_due(const icalproperty* prop);icalproperty* icalproperty_vanew_due(struct icaltimetype v, ...); /* DURATION */ icalproperty* icalproperty_new_duration(struct icaldurationtype v); void icalproperty_set_duration(icalproperty* prop, struct icaldurationtype v); -struct icaldurationtype icalproperty_get_duration(icalproperty* prop);icalproperty* icalproperty_vanew_exdate(struct icaltimetype v, ...); +struct icaldurationtype icalproperty_get_duration(const icalproperty* prop);icalproperty* icalproperty_vanew_duration(struct icaldurationtype v, ...); /* EXDATE */ icalproperty* icalproperty_new_exdate(struct icaltimetype v); void icalproperty_set_exdate(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_exdate(icalproperty* prop);icalproperty* icalproperty_vanew_exrule(struct icalrecurrencetype v, ...); +struct icaltimetype icalproperty_get_exdate(const icalproperty* prop);icalproperty* icalproperty_vanew_exdate(struct icaltimetype v, ...); + +/* EXPAND */ +icalproperty* icalproperty_new_expand(int v); +void icalproperty_set_expand(icalproperty* prop, int v); +int icalproperty_get_expand(const icalproperty* prop);icalproperty* icalproperty_vanew_expand(int v, ...); /* EXRULE */ icalproperty* icalproperty_new_exrule(struct icalrecurrencetype v); void icalproperty_set_exrule(icalproperty* prop, struct icalrecurrencetype v); -struct icalrecurrencetype icalproperty_get_exrule(icalproperty* prop);icalproperty* icalproperty_vanew_freebusy(struct icalperiodtype v, ...); +struct icalrecurrencetype icalproperty_get_exrule(const icalproperty* prop);icalproperty* icalproperty_vanew_exrule(struct icalrecurrencetype v, ...); /* FREEBUSY */ icalproperty* icalproperty_new_freebusy(struct icalperiodtype v); void icalproperty_set_freebusy(icalproperty* prop, struct icalperiodtype v); -struct icalperiodtype icalproperty_get_freebusy(icalproperty* prop);icalproperty* icalproperty_vanew_geo(struct icalgeotype v, ...); +struct icalperiodtype icalproperty_get_freebusy(const icalproperty* prop);icalproperty* icalproperty_vanew_freebusy(struct icalperiodtype v, ...); /* GEO */ icalproperty* icalproperty_new_geo(struct icalgeotype v); void icalproperty_set_geo(icalproperty* prop, struct icalgeotype v); -struct icalgeotype icalproperty_get_geo(icalproperty* prop);icalproperty* icalproperty_vanew_lastmodified(struct icaltimetype v, ...); +struct icalgeotype icalproperty_get_geo(const icalproperty* prop);icalproperty* icalproperty_vanew_geo(struct icalgeotype v, ...); /* LAST-MODIFIED */ icalproperty* icalproperty_new_lastmodified(struct icaltimetype v); void icalproperty_set_lastmodified(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_lastmodified(icalproperty* prop);icalproperty* icalproperty_vanew_location(const char* v, ...); +struct icaltimetype icalproperty_get_lastmodified(const icalproperty* prop);icalproperty* icalproperty_vanew_lastmodified(struct icaltimetype v, ...); /* LOCATION */ icalproperty* icalproperty_new_location(const char* v); void icalproperty_set_location(icalproperty* prop, const char* v); -const char* icalproperty_get_location(icalproperty* prop);icalproperty* icalproperty_vanew_maxresults(int v, ...); +const char* icalproperty_get_location(const icalproperty* prop);icalproperty* icalproperty_vanew_location(const char* v, ...); /* MAXRESULTS */ icalproperty* icalproperty_new_maxresults(int v); void icalproperty_set_maxresults(icalproperty* prop, int v); -int icalproperty_get_maxresults(icalproperty* prop);icalproperty* icalproperty_vanew_maxresultssize(int v, ...); +int icalproperty_get_maxresults(const icalproperty* prop);icalproperty* icalproperty_vanew_maxresults(int v, ...); /* MAXRESULTSSIZE */ icalproperty* icalproperty_new_maxresultssize(int v); void icalproperty_set_maxresultssize(icalproperty* prop, int v); -int icalproperty_get_maxresultssize(icalproperty* prop);icalproperty* icalproperty_vanew_method(enum icalproperty_method v, ...); +int icalproperty_get_maxresultssize(const icalproperty* prop);icalproperty* icalproperty_vanew_maxresultssize(int v, ...); /* METHOD */ icalproperty* icalproperty_new_method(enum icalproperty_method v); void icalproperty_set_method(icalproperty* prop, enum icalproperty_method v); -enum icalproperty_method icalproperty_get_method(icalproperty* prop);icalproperty* icalproperty_vanew_organizer(const char* v, ...); +enum icalproperty_method icalproperty_get_method(const icalproperty* prop);icalproperty* icalproperty_vanew_method(enum icalproperty_method v, ...); /* ORGANIZER */ icalproperty* icalproperty_new_organizer(const char* v); void icalproperty_set_organizer(icalproperty* prop, const char* v); -const char* icalproperty_get_organizer(icalproperty* prop);icalproperty* icalproperty_vanew_percentcomplete(int v, ...); +const char* icalproperty_get_organizer(const icalproperty* prop);icalproperty* icalproperty_vanew_organizer(const char* v, ...); + +/* OWNER */ +icalproperty* icalproperty_new_owner(const char* v); +void icalproperty_set_owner(icalproperty* prop, const char* v); +const char* icalproperty_get_owner(const icalproperty* prop);icalproperty* icalproperty_vanew_owner(const char* v, ...); /* PERCENT-COMPLETE */ icalproperty* icalproperty_new_percentcomplete(int v); void icalproperty_set_percentcomplete(icalproperty* prop, int v); -int icalproperty_get_percentcomplete(icalproperty* prop);icalproperty* icalproperty_vanew_priority(int v, ...); +int icalproperty_get_percentcomplete(const icalproperty* prop);icalproperty* icalproperty_vanew_percentcomplete(int v, ...); /* PRIORITY */ icalproperty* icalproperty_new_priority(int v); void icalproperty_set_priority(icalproperty* prop, int v); -int icalproperty_get_priority(icalproperty* prop);icalproperty* icalproperty_vanew_prodid(const char* v, ...); +int icalproperty_get_priority(const icalproperty* prop);icalproperty* icalproperty_vanew_priority(int v, ...); /* PRODID */ icalproperty* icalproperty_new_prodid(const char* v); void icalproperty_set_prodid(icalproperty* prop, const char* v); -const char* icalproperty_get_prodid(icalproperty* prop);icalproperty* icalproperty_vanew_query(const char* v, ...); +const char* icalproperty_get_prodid(const icalproperty* prop);icalproperty* icalproperty_vanew_prodid(const char* v, ...); /* QUERY */ icalproperty* icalproperty_new_query(const char* v); void icalproperty_set_query(icalproperty* prop, const char* v); -const char* icalproperty_get_query(icalproperty* prop);icalproperty* icalproperty_vanew_queryname(const char* v, ...); +const char* icalproperty_get_query(const icalproperty* prop);icalproperty* icalproperty_vanew_query(const char* v, ...); /* QUERYNAME */ icalproperty* icalproperty_new_queryname(const char* v); void icalproperty_set_queryname(icalproperty* prop, const char* v); -const char* icalproperty_get_queryname(icalproperty* prop);icalproperty* icalproperty_vanew_rdate(struct icaldatetimeperiodtype v, ...); +const char* icalproperty_get_queryname(const icalproperty* prop);icalproperty* icalproperty_vanew_queryname(const char* v, ...); /* RDATE */ icalproperty* icalproperty_new_rdate(struct icaldatetimeperiodtype v); void icalproperty_set_rdate(icalproperty* prop, struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalproperty_get_rdate(icalproperty* prop);icalproperty* icalproperty_vanew_recurrenceid(struct icaltimetype v, ...); +struct icaldatetimeperiodtype icalproperty_get_rdate(const icalproperty* prop);icalproperty* icalproperty_vanew_rdate(struct icaldatetimeperiodtype v, ...); /* RECURRENCE-ID */ icalproperty* icalproperty_new_recurrenceid(struct icaltimetype v); void icalproperty_set_recurrenceid(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_recurrenceid(icalproperty* prop);icalproperty* icalproperty_vanew_relatedto(const char* v, ...); +struct icaltimetype icalproperty_get_recurrenceid(const icalproperty* prop);icalproperty* icalproperty_vanew_recurrenceid(struct icaltimetype v, ...); /* RELATED-TO */ icalproperty* icalproperty_new_relatedto(const char* v); void icalproperty_set_relatedto(icalproperty* prop, const char* v); -const char* icalproperty_get_relatedto(icalproperty* prop);icalproperty* icalproperty_vanew_repeat(int v, ...); +const char* icalproperty_get_relatedto(const icalproperty* prop);icalproperty* icalproperty_vanew_relatedto(const char* v, ...); + +/* RELCALID */ +icalproperty* icalproperty_new_relcalid(const char* v); +void icalproperty_set_relcalid(icalproperty* prop, const char* v); +const char* icalproperty_get_relcalid(const icalproperty* prop);icalproperty* icalproperty_vanew_relcalid(const char* v, ...); /* REPEAT */ icalproperty* icalproperty_new_repeat(int v); void icalproperty_set_repeat(icalproperty* prop, int v); -int icalproperty_get_repeat(icalproperty* prop);icalproperty* icalproperty_vanew_requeststatus(struct icalreqstattype v, ...); +int icalproperty_get_repeat(const icalproperty* prop);icalproperty* icalproperty_vanew_repeat(int v, ...); /* REQUEST-STATUS */ icalproperty* icalproperty_new_requeststatus(struct icalreqstattype v); void icalproperty_set_requeststatus(icalproperty* prop, struct icalreqstattype v); -struct icalreqstattype icalproperty_get_requeststatus(icalproperty* prop);icalproperty* icalproperty_vanew_resources(const char* v, ...); +struct icalreqstattype icalproperty_get_requeststatus(const icalproperty* prop);icalproperty* icalproperty_vanew_requeststatus(struct icalreqstattype v, ...); /* RESOURCES */ icalproperty* icalproperty_new_resources(const char* v); void icalproperty_set_resources(icalproperty* prop, const char* v); -const char* icalproperty_get_resources(icalproperty* prop);icalproperty* icalproperty_vanew_rrule(struct icalrecurrencetype v, ...); +const char* icalproperty_get_resources(const icalproperty* prop);icalproperty* icalproperty_vanew_resources(const char* v, ...); /* RRULE */ icalproperty* icalproperty_new_rrule(struct icalrecurrencetype v); void icalproperty_set_rrule(icalproperty* prop, struct icalrecurrencetype v); -struct icalrecurrencetype icalproperty_get_rrule(icalproperty* prop);icalproperty* icalproperty_vanew_scope(const char* v, ...); +struct icalrecurrencetype icalproperty_get_rrule(const icalproperty* prop);icalproperty* icalproperty_vanew_rrule(struct icalrecurrencetype v, ...); /* SCOPE */ icalproperty* icalproperty_new_scope(const char* v); void icalproperty_set_scope(icalproperty* prop, const char* v); -const char* icalproperty_get_scope(icalproperty* prop);icalproperty* icalproperty_vanew_sequence(int v, ...); +const char* icalproperty_get_scope(const icalproperty* prop);icalproperty* icalproperty_vanew_scope(const char* v, ...); /* SEQUENCE */ icalproperty* icalproperty_new_sequence(int v); void icalproperty_set_sequence(icalproperty* prop, int v); -int icalproperty_get_sequence(icalproperty* prop);icalproperty* icalproperty_vanew_status(enum icalproperty_status v, ...); +int icalproperty_get_sequence(const icalproperty* prop);icalproperty* icalproperty_vanew_sequence(int v, ...); /* STATUS */ icalproperty* icalproperty_new_status(enum icalproperty_status v); void icalproperty_set_status(icalproperty* prop, enum icalproperty_status v); -enum icalproperty_status icalproperty_get_status(icalproperty* prop);icalproperty* icalproperty_vanew_summary(const char* v, ...); +enum icalproperty_status icalproperty_get_status(const icalproperty* prop);icalproperty* icalproperty_vanew_status(enum icalproperty_status v, ...); /* SUMMARY */ icalproperty* icalproperty_new_summary(const char* v); void icalproperty_set_summary(icalproperty* prop, const char* v); -const char* icalproperty_get_summary(icalproperty* prop);icalproperty* icalproperty_vanew_target(const char* v, ...); +const char* icalproperty_get_summary(const icalproperty* prop);icalproperty* icalproperty_vanew_summary(const char* v, ...); /* TARGET */ icalproperty* icalproperty_new_target(const char* v); void icalproperty_set_target(icalproperty* prop, const char* v); -const char* icalproperty_get_target(icalproperty* prop);icalproperty* icalproperty_vanew_transp(const char* v, ...); +const char* icalproperty_get_target(const icalproperty* prop);icalproperty* icalproperty_vanew_target(const char* v, ...); /* TRANSP */ -icalproperty* icalproperty_new_transp(const char* v); -void icalproperty_set_transp(icalproperty* prop, const char* v); -const char* icalproperty_get_transp(icalproperty* prop);icalproperty* icalproperty_vanew_trigger(struct icaltriggertype v, ...); +icalproperty* icalproperty_new_transp(enum icalproperty_transp v); +void icalproperty_set_transp(icalproperty* prop, enum icalproperty_transp v); +enum icalproperty_transp icalproperty_get_transp(const icalproperty* prop);icalproperty* icalproperty_vanew_transp(enum icalproperty_transp v, ...); /* TRIGGER */ icalproperty* icalproperty_new_trigger(struct icaltriggertype v); void icalproperty_set_trigger(icalproperty* prop, struct icaltriggertype v); -struct icaltriggertype icalproperty_get_trigger(icalproperty* prop);icalproperty* icalproperty_vanew_tzid(const char* v, ...); +struct icaltriggertype icalproperty_get_trigger(const icalproperty* prop);icalproperty* icalproperty_vanew_trigger(struct icaltriggertype v, ...); /* TZID */ icalproperty* icalproperty_new_tzid(const char* v); void icalproperty_set_tzid(icalproperty* prop, const char* v); -const char* icalproperty_get_tzid(icalproperty* prop);icalproperty* icalproperty_vanew_tzname(const char* v, ...); +const char* icalproperty_get_tzid(const icalproperty* prop);icalproperty* icalproperty_vanew_tzid(const char* v, ...); /* TZNAME */ icalproperty* icalproperty_new_tzname(const char* v); void icalproperty_set_tzname(icalproperty* prop, const char* v); -const char* icalproperty_get_tzname(icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetfrom(int v, ...); +const char* icalproperty_get_tzname(const icalproperty* prop);icalproperty* icalproperty_vanew_tzname(const char* v, ...); /* TZOFFSETFROM */ icalproperty* icalproperty_new_tzoffsetfrom(int v); void icalproperty_set_tzoffsetfrom(icalproperty* prop, int v); -int icalproperty_get_tzoffsetfrom(icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetto(int v, ...); +int icalproperty_get_tzoffsetfrom(const icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetfrom(int v, ...); /* TZOFFSETTO */ icalproperty* icalproperty_new_tzoffsetto(int v); void icalproperty_set_tzoffsetto(icalproperty* prop, int v); -int icalproperty_get_tzoffsetto(icalproperty* prop);icalproperty* icalproperty_vanew_tzurl(const char* v, ...); +int icalproperty_get_tzoffsetto(const icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetto(int v, ...); /* TZURL */ icalproperty* icalproperty_new_tzurl(const char* v); void icalproperty_set_tzurl(icalproperty* prop, const char* v); -const char* icalproperty_get_tzurl(icalproperty* prop);icalproperty* icalproperty_vanew_uid(const char* v, ...); +const char* icalproperty_get_tzurl(const icalproperty* prop);icalproperty* icalproperty_vanew_tzurl(const char* v, ...); /* UID */ icalproperty* icalproperty_new_uid(const char* v); void icalproperty_set_uid(icalproperty* prop, const char* v); -const char* icalproperty_get_uid(icalproperty* prop);icalproperty* icalproperty_vanew_url(const char* v, ...); +const char* icalproperty_get_uid(const icalproperty* prop);icalproperty* icalproperty_vanew_uid(const char* v, ...); /* URL */ icalproperty* icalproperty_new_url(const char* v); void icalproperty_set_url(icalproperty* prop, const char* v); -const char* icalproperty_get_url(icalproperty* prop);icalproperty* icalproperty_vanew_version(const char* v, ...); +const char* icalproperty_get_url(const icalproperty* prop);icalproperty* icalproperty_vanew_url(const char* v, ...); /* VERSION */ icalproperty* icalproperty_new_version(const char* v); void icalproperty_set_version(icalproperty* prop, const char* v); -const char* icalproperty_get_version(icalproperty* prop);icalproperty* icalproperty_vanew_x(const char* v, ...); +const char* icalproperty_get_version(const icalproperty* prop);icalproperty* icalproperty_vanew_version(const char* v, ...); /* X */ icalproperty* icalproperty_new_x(const char* v); void icalproperty_set_x(icalproperty* prop, const char* v); -const char* icalproperty_get_x(icalproperty* prop);icalproperty* icalproperty_vanew_xlicclustercount(const char* v, ...); +const char* icalproperty_get_x(const icalproperty* prop);icalproperty* icalproperty_vanew_x(const char* v, ...); + +/* X-LIC-CLASS */ +icalproperty* icalproperty_new_xlicclass(enum icalproperty_xlicclass v); +void icalproperty_set_xlicclass(icalproperty* prop, enum icalproperty_xlicclass v); +enum icalproperty_xlicclass icalproperty_get_xlicclass(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicclass(enum icalproperty_xlicclass v, ...); /* X-LIC-CLUSTERCOUNT */ icalproperty* icalproperty_new_xlicclustercount(const char* v); void icalproperty_set_xlicclustercount(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicclustercount(icalproperty* prop);icalproperty* icalproperty_vanew_xlicerror(const char* v, ...); +const char* icalproperty_get_xlicclustercount(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicclustercount(const char* v, ...); /* X-LIC-ERROR */ icalproperty* icalproperty_new_xlicerror(const char* v); void icalproperty_set_xlicerror(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicerror(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecharset(const char* v, ...); +const char* icalproperty_get_xlicerror(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicerror(const char* v, ...); /* X-LIC-MIMECHARSET */ icalproperty* icalproperty_new_xlicmimecharset(const char* v); void icalproperty_set_xlicmimecharset(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecharset(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecid(const char* v, ...); +const char* icalproperty_get_xlicmimecharset(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecharset(const char* v, ...); /* X-LIC-MIMECID */ icalproperty* icalproperty_new_xlicmimecid(const char* v); void icalproperty_set_xlicmimecid(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecid(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecontenttype(const char* v, ...); +const char* icalproperty_get_xlicmimecid(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecid(const char* v, ...); /* X-LIC-MIMECONTENTTYPE */ icalproperty* icalproperty_new_xlicmimecontenttype(const char* v); void icalproperty_set_xlicmimecontenttype(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecontenttype(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeencoding(const char* v, ...); +const char* icalproperty_get_xlicmimecontenttype(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecontenttype(const char* v, ...); /* X-LIC-MIMEENCODING */ icalproperty* icalproperty_new_xlicmimeencoding(const char* v); void icalproperty_set_xlicmimeencoding(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimeencoding(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimefilename(const char* v, ...); +const char* icalproperty_get_xlicmimeencoding(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeencoding(const char* v, ...); /* X-LIC-MIMEFILENAME */ icalproperty* icalproperty_new_xlicmimefilename(const char* v); void icalproperty_set_xlicmimefilename(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimefilename(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeoptinfo(const char* v, ...); +const char* icalproperty_get_xlicmimefilename(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimefilename(const char* v, ...); /* X-LIC-MIMEOPTINFO */ icalproperty* icalproperty_new_xlicmimeoptinfo(const char* v); void icalproperty_set_xlicmimeoptinfo(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimeoptinfo(icalproperty* prop); - -#endif /*ICALPROPERTY_H*/ -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalvalue.h - CREATOR: eric 20 March 1999 - - - $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 icalvalue.h - - ======================================================================*/ - -#ifndef ICALVALUE_H -#define ICALVALUE_H - -#include <time.h> - -/* Defined in icalderivedvalue.h */ -/*typedef void icalvalue;*/ - -icalvalue* icalvalue_new(icalvalue_kind kind); - -icalvalue* icalvalue_new_clone(icalvalue* value); - -icalvalue* icalvalue_new_from_string(icalvalue_kind kind, const char* str); - -void icalvalue_free(icalvalue* value); - -int icalvalue_is_valid(icalvalue* value); - -const char* icalvalue_as_ical_string(icalvalue* value); - -icalvalue_kind icalvalue_isa(icalvalue* value); - -int icalvalue_isa_value(void*); - -icalparameter_xliccomparetype icalvalue_compare(icalvalue* a, icalvalue *b); - - -/* Special, non autogenerated value accessors */ - -icalvalue* icalvalue_new_recur (struct icalrecurrencetype v); -void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); -struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); - -icalvalue* icalvalue_new_trigger (struct icaltriggertype v); -void icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v); -struct icaltriggertype icalvalue_get_trigger(icalvalue* value); - -icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); -void icalvalue_set_datetimeperiod(icalvalue* value, - struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(icalvalue* value); - -/* Convert enumerations */ - -icalvalue_kind icalvalue_string_to_kind(const char* str); -const char* icalvalue_kind_to_string(icalvalue_kind kind); - - -#endif /*ICALVALUE_H*/ -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalparam.h - CREATOR: eric 20 March 1999 - - - $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 icalparam.h - - ======================================================================*/ - -#ifndef ICALPARAM_H -#define ICALPARAM_H - - -/* Declared in icalderivedparameter.h */ -/*typedef void icalparameter;*/ +const char* icalproperty_get_xlicmimeoptinfo(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeoptinfo(const char* v, ...); -icalparameter* icalparameter_new(icalparameter_kind kind); -icalparameter* icalparameter_new_clone(icalparameter* p); - -/* Create from string of form "PARAMNAME=VALUE" */ -icalparameter* icalparameter_new_from_string(const char* value); - -/* Create from just the value, the part after the "=" */ -icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind, const char* value); - -void icalparameter_free(icalparameter* parameter); - -char* icalparameter_as_ical_string(icalparameter* parameter); - -int icalparameter_is_valid(icalparameter* parameter); - -icalparameter_kind icalparameter_isa(icalparameter* parameter); - -int icalparameter_isa_parameter(void* param); - -/* Acess the name of an X parameer */ -void icalparameter_set_xname (icalparameter* param, const char* v); -const char* icalparameter_get_xname(icalparameter* param); -void icalparameter_set_xvalue (icalparameter* param, const char* v); -const char* icalparameter_get_xvalue(icalparameter* param); - -/* Convert enumerations */ -const char* icalparameter_kind_to_string(icalparameter_kind kind); -icalparameter_kind icalparameter_string_to_kind(const char* string); - - - -#endif +#endif /*ICALPROPERTY_H*/ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalproperty.h CREATOR: eric 20 March 1999 - $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 icalparam.h ======================================================================*/ #ifndef ICALPROPERTY_H #define ICALPROPERTY_H #include <time.h> - +#include <stdarg.h> /* for va_... */ /* Actually in icalderivedproperty.h: - typedef void icalproperty; */ + typedef struct icalproperty_impl icalproperty; */ icalproperty* icalproperty_new(icalproperty_kind kind); icalproperty* icalproperty_new_clone(icalproperty * prop); icalproperty* icalproperty_new_from_string(const char* str); const char* icalproperty_as_ical_string(icalproperty* prop); void icalproperty_free(icalproperty* prop); icalproperty_kind icalproperty_isa(icalproperty* property); int icalproperty_isa_property(void* property); +void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args); void icalproperty_add_parameter(icalproperty* prop,icalparameter* parameter); void icalproperty_set_parameter(icalproperty* prop,icalparameter* parameter); void icalproperty_set_parameter_from_string(icalproperty* prop, const char* name, const char* value); const char* icalproperty_get_parameter_as_string(icalproperty* prop, const char* name); void icalproperty_remove_parameter(icalproperty* prop, icalparameter_kind kind); -int icalproperty_count_parameters(icalproperty* prop); +void icalproperty_remove_parameter_by_kind(icalproperty* prop, + icalparameter_kind kind); + +void icalproperty_remove_parameter_by_name(icalproperty* prop, + const char *name); + +void icalproperty_remove_parameter_by_ref(icalproperty* prop, + icalparameter *param); + + + +int icalproperty_count_parameters(const icalproperty* prop); /* Iterate through the parameters */ icalparameter* icalproperty_get_first_parameter(icalproperty* prop, icalparameter_kind kind); icalparameter* icalproperty_get_next_parameter(icalproperty* prop, icalparameter_kind kind); /* Access the value of the property */ void icalproperty_set_value(icalproperty* prop, icalvalue* value); void icalproperty_set_value_from_string(icalproperty* prop,const char* value, const char* kind); -icalvalue* icalproperty_get_value(icalproperty* prop); -const char* icalproperty_get_value_as_string(icalproperty* prop); +icalvalue* icalproperty_get_value(const icalproperty* prop); +const char* icalproperty_get_value_as_string(const icalproperty* prop); /* Deal with X properties */ void icalproperty_set_x_name(icalproperty* prop, const char* name); const char* icalproperty_get_x_name(icalproperty* prop); -/* Return the name of the property -- the type name converted to a - string, or the value of _get_x_name if the type is and X property */ -const char* icalproperty_get_name (icalproperty* prop); +/** Return the name of the property -- the type name converted to a + * string, or the value of _get_x_name if the type is and X + * property + */ +const char* icalproperty_get_property_name (const icalproperty* prop); icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value); /* Convert kinds to string and get default value type */ icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind); -icalvalue_kind icalproperty_value_kind_to_kind(icalvalue_kind kind); +icalproperty_kind icalproperty_value_kind_to_kind(icalvalue_kind kind); const char* icalproperty_kind_to_string(icalproperty_kind kind); icalproperty_kind icalproperty_string_to_kind(const char* string); +/** Check validity of a specific icalproperty_kind **/ +int icalproperty_kind_is_valid(const icalproperty_kind kind); + icalproperty_method icalproperty_string_to_method(const char* str); const char* icalproperty_method_to_string(icalproperty_method method); const char* icalproperty_enum_to_string(int e); int icalproperty_string_to_enum(const char* str); +int icalproperty_kind_and_string_to_enum(const int kind, const char* str); const char* icalproperty_status_to_string(icalproperty_status); icalproperty_status icalproperty_string_to_status(const char* string); int icalproperty_enum_belongs_to_property(icalproperty_kind kind, int e); #endif /*ICALPROPERTY_H*/ -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalattendee.h - CREATOR: eric 8 Mar 01 - - - (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 icaltypes.h - -======================================================================*/ - -#ifndef ICALATTENDEE_H -#define ICALATTENDEE_H - -#include <time.h> - -struct icalorganizertype { - const char* value; - const char* common_name; - const char* dir; - const char* sentby; - const char* language; - -}; - -/* Create a copy of the given organizer. Libical will not own the - memory for the strings in the copy; the call must free them */ -struct icalorganizertype icalorganizertype_new_clone(struct icalorganizertype a); - - -struct icalattendeetype { - const char* cuid; /* Cal user id, contents of the property value */ - /*icalparameter_cutype cutype;*/ - const char* member; - /*icalparameter_role role;*/ - int rsvp; - const char* delto; - const char* delfrom; - const char* sentby; - const char* cn; - const char* dir; - const char* language; -}; - -/* Create a copy of the given attendee. Libical will not own the - memory for the strings in the copy; the call must free them */ -struct icalattendeetype icalattendeetype_new_clone(struct icalattendeetype a); - - -#endif /* !ICALATTENDEE_H */ /*====================================================================== FILE: pvl.h CREATOR: eric November, 1995 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef __PVL_H__ #define __PVL_H__ -typedef void* pvl_list; -typedef void* pvl_elem; +typedef struct pvl_list_t* pvl_list; +typedef struct pvl_elem_t* pvl_elem; -/* - struct pvl_elem_t - - This type is private. Always use pvl_elem instead. The struct would - not even appear in this header except to make code in the USE_MACROS - blocks work +/** + * This type is private. Always use pvl_elem instead. The struct would + * not even appear in this header except to make code in the USE_MACROS + * blocks work + */ - */ typedef struct pvl_elem_t { - int MAGIC; /* Magic Identifier */ - void *d; /* Pointer to data user is storing */ - struct pvl_elem_t *next; /* Next element */ - struct pvl_elem_t *prior; /* prior element */ + int MAGIC; /**< Magic Identifier */ + void *d; /**< Pointer to data user is storing */ + struct pvl_elem_t *next; /**< Next element */ + struct pvl_elem_t *prior; /**< Prior element */ } pvl_elem_t; -/* This global is incremented for each call to pvl_new_element(); it gives each - * list a unique identifer */ +/** + * This global is incremented for each call to pvl_new_element(); it gives each + * list a unique identifer + */ extern int pvl_elem_count; extern int pvl_list_count; /* Create new lists or elements */ pvl_elem pvl_new_element(void* d, pvl_elem next,pvl_elem prior); pvl_list pvl_newlist(void); void pvl_free(pvl_list); /* Add, remove, or get the head of the list */ void pvl_unshift(pvl_list l,void *d); void* pvl_shift(pvl_list l); pvl_elem pvl_head(pvl_list); /* Add, remove or get the tail of the list */ void pvl_push(pvl_list l,void *d); void* pvl_pop(pvl_list l); pvl_elem pvl_tail(pvl_list); /* Insert elements in random places */ typedef int (*pvl_comparef)(void* a, void* b); /* a, b are of the data type*/ void pvl_insert_ordered(pvl_list l,pvl_comparef f,void *d); void pvl_insert_after(pvl_list l,pvl_elem e,void *d); void pvl_insert_before(pvl_list l,pvl_elem e,void *d); /* Remove an element, or clear the entire list */ void* pvl_remove(pvl_list,pvl_elem); /* Remove element, return data */ void pvl_clear(pvl_list); /* Remove all elements, de-allocate all data */ int pvl_count(pvl_list); /* Navagate the list */ pvl_elem pvl_next(pvl_elem e); pvl_elem pvl_prior(pvl_elem e); /* get the data in the list */ #ifndef PVL_USE_MACROS void* pvl_data(pvl_elem); #else #define pvl_data(x) x==0 ? 0 : ((struct pvl_elem_t *)x)->d; #endif /* Find an element for which a function returns true */ typedef int (*pvl_findf)(void* a, void* b); /*a is list elem, b is other data*/ pvl_elem pvl_find(pvl_list l,pvl_findf f,void* v); pvl_elem pvl_find_next(pvl_list l,pvl_findf f,void* v); -/* Pass each element in the list to a function */ -typedef void (*pvl_applyf)(void* a, void* b); /*a is list elem, b is other data*/ +/** + * Pass each element in the list to a function + * a is list elem, b is other data + */ +typedef void (*pvl_applyf)(void* a, void* b); void pvl_apply(pvl_list l,pvl_applyf f, void *v); #endif /* __PVL_H__ */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*====================================================================== + FILE: icalarray.h + CREATOR: Damon Chaplin 07 March 2001 + + + + (C) COPYRIGHT 2001, Ximian, Inc. + + 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/ + + +======================================================================*/ + + +#ifndef ICALARRAY_H +#define ICALARRAY_H + +/** @file icalarray.h + * + * @brief An array of arbitrarily-sized elements which grows + * dynamically as elements are added. + */ + +typedef struct _icalarray icalarray; +struct _icalarray { + unsigned int element_size; + unsigned int increment_size; + unsigned int num_elements; + unsigned int space_allocated; + void *data; +}; + + + +icalarray *icalarray_new (int element_size, + int increment_size); +void icalarray_free (icalarray *array); + +void icalarray_append (icalarray *array, + void *element); +void icalarray_remove_element_at (icalarray *array, + int position); + +void *icalarray_element_at (icalarray *array, + int position); + +void icalarray_sort (icalarray *array, + int (*compare) (const void *, const void *)); + + +#endif /* ICALARRAY_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalcomponent.h CREATOR: eric 20 March 1999 (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 icalcomponent.h ======================================================================*/ #ifndef ICALCOMPONENT_H #define ICALCOMPONENT_H -typedef void icalcomponent; +typedef struct icalcomponent_impl icalcomponent; + +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +/** @brief An opaque struct representing a timezone. + * We declare this here to avoid a circular dependancy. + */ +typedef struct _icaltimezone icaltimezone; +#endif + /* This is exposed so that callers will not have to allocate and deallocate iterators. Pretend that you can't see it. */ typedef struct icalcompiter { icalcomponent_kind kind; pvl_elem iter; } icalcompiter; icalcomponent* icalcomponent_new(icalcomponent_kind kind); icalcomponent* icalcomponent_new_clone(icalcomponent* component); icalcomponent* icalcomponent_new_from_string(char* str); icalcomponent* icalcomponent_vanew(icalcomponent_kind kind, ...); void icalcomponent_free(icalcomponent* component); char* icalcomponent_as_ical_string(icalcomponent* component); int icalcomponent_is_valid(icalcomponent* component); -icalcomponent_kind icalcomponent_isa(icalcomponent* component); +icalcomponent_kind icalcomponent_isa(const icalcomponent* component); int icalcomponent_isa_component (void* component); /* * Working with properties */ void icalcomponent_add_property(icalcomponent* component, icalproperty* property); void icalcomponent_remove_property(icalcomponent* component, icalproperty* property); int icalcomponent_count_properties(icalcomponent* component, icalproperty_kind kind); /* Iterate through the properties */ icalproperty* icalcomponent_get_current_property(icalcomponent* component); icalproperty* icalcomponent_get_first_property(icalcomponent* component, icalproperty_kind kind); icalproperty* icalcomponent_get_next_property(icalcomponent* component, icalproperty_kind kind); /* * Working with components */ /* Return the first VEVENT, VTODO or VJOURNAL sub-component of cop, or comp if it is one of those types */ icalcomponent* icalcomponent_get_inner(icalcomponent* comp); void icalcomponent_add_component(icalcomponent* parent, icalcomponent* child); void icalcomponent_remove_component(icalcomponent* parent, icalcomponent* child); int icalcomponent_count_components(icalcomponent* component, icalcomponent_kind kind); +/** + This takes 2 VCALENDAR components and merges the second one into the first, + resolving any problems with conflicting TZIDs. comp_to_merge will no + longer exist after calling this function. */ +void icalcomponent_merge_component(icalcomponent* comp, + icalcomponent* comp_to_merge); + + /* Iteration Routines. There are two forms of iterators, internal and external. The internal ones came first, and are almost completely sufficient, but they fail badly when you want to construct a loop that removes components from the container.*/ /* Iterate through components */ icalcomponent* icalcomponent_get_current_component (icalcomponent* component); icalcomponent* icalcomponent_get_first_component(icalcomponent* component, icalcomponent_kind kind); icalcomponent* icalcomponent_get_next_component(icalcomponent* component, icalcomponent_kind kind); /* Using external iterators */ icalcompiter icalcomponent_begin_component(icalcomponent* component, icalcomponent_kind kind); icalcompiter icalcomponent_end_component(icalcomponent* component, icalcomponent_kind kind); icalcomponent* icalcompiter_next(icalcompiter* i); icalcomponent* icalcompiter_prior(icalcompiter* i); icalcomponent* icalcompiter_deref(icalcompiter* i); +/* Working with embedded error properties */ +/* Check the component against itip rules and insert error properties*/ /* Working with embedded error properties */ +int icalcomponent_check_restrictions(icalcomponent* comp); +/** Count embedded errors. */ int icalcomponent_count_errors(icalcomponent* component); -/* Remove all X-LIC-ERROR properties*/ +/** Remove all X-LIC-ERROR properties*/ void icalcomponent_strip_errors(icalcomponent* component); -/* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ +/** Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ void icalcomponent_convert_errors(icalcomponent* component); /* Internal operations. They are private, and you should not be using them. */ icalcomponent* icalcomponent_get_parent(icalcomponent* component); void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent); -/* Kind conversion routiens */ +/* Kind conversion routines */ + +int icalcomponent_kind_is_valid(const icalcomponent_kind kind); icalcomponent_kind icalcomponent_string_to_kind(const char* string); const char* icalcomponent_kind_to_string(icalcomponent_kind kind); /************* Derived class methods. **************************** If the code was in an OO language, the remaining routines would be members of classes derived from icalcomponent. Don't call them on the wrong component subtypes. */ -/* For VCOMPONENT: Return a reference to the first VEVENT, VTODO or +/** For VCOMPONENT: Return a reference to the first VEVENT, VTODO or VJOURNAL */ icalcomponent* icalcomponent_get_first_real_component(icalcomponent *c); -/* For VEVENT, VTODO, VJOURNAL and VTIMEZONE: report the start and end +/** For VEVENT, VTODO, VJOURNAL and VTIMEZONE: report the start and end times of an event in UTC */ struct icaltime_span icalcomponent_get_span(icalcomponent* comp); /******************** Convienience routines **********************/ void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v); struct icaltimetype icalcomponent_get_dtstart(icalcomponent* comp); /* For the icalcomponent routines only, dtend and duration are tied together. If you call the set routine for one and the other exists, the routine will calculate the change to the other. That is, if there is a DTEND and you call set_duration, the routine will modify DTEND to be the sum of DTSTART and the duration. If you call a get routine for one and the other exists, the routine will calculate the return value. If you call a set routine and neither exists, the routine will create the apcompriate comperty */ struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp); void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v); +struct icaltimetype icalcomponent_get_due(icalcomponent* comp); +void icalcomponent_set_due(icalcomponent* comp, struct icaltimetype v); + void icalcomponent_set_duration(icalcomponent* comp, struct icaldurationtype v); struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp); void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method); icalproperty_method icalcomponent_get_method(icalcomponent* comp); struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp); void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v); - void icalcomponent_set_summary(icalcomponent* comp, const char* v); const char* icalcomponent_get_summary(icalcomponent* comp); void icalcomponent_set_comment(icalcomponent* comp, const char* v); const char* icalcomponent_get_comment(icalcomponent* comp); void icalcomponent_set_uid(icalcomponent* comp, const char* v); const char* icalcomponent_get_uid(icalcomponent* comp); +void icalcomponent_set_relcalid(icalcomponent* comp, const char* v); +const char* icalcomponent_get_relcalid(icalcomponent* comp); + void icalcomponent_set_recurrenceid(icalcomponent* comp, struct icaltimetype v); struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp); +void icalcomponent_set_description(icalcomponent* comp, const char* v); +const char* icalcomponent_get_description(icalcomponent* comp); -void icalcomponent_set_organizer(icalcomponent* comp, - struct icalorganizertype org); - struct icalorganizertype icalcomponent_get_organizer(icalcomponent* comp); +void icalcomponent_set_location(icalcomponent* comp, const char* v); +const char* icalcomponent_get_location(icalcomponent* comp); +void icalcomponent_set_sequence(icalcomponent* comp, int v); +int icalcomponent_get_sequence(icalcomponent* comp); -void icalcomponent_add_attendee(icalcomponent *comp, - struct icalattendeetype attendee); +void icalcomponent_set_status(icalcomponent* comp, enum icalproperty_status v); +enum icalproperty_status icalcomponent_get_status(icalcomponent* comp); -int icalcomponent_remove_attendee(icalcomponent *comp, char* cuid); -/* Get the Nth attendee. Out of range indices return an attendee - with cuid == 0 */ -struct icalattendeetype icalcomponent_get_attendee(icalcomponent *comp, - int index); +/** Calls the given function for each TZID parameter found in the + component, and any subcomponents. */ +void icalcomponent_foreach_tzid(icalcomponent* comp, + void (*callback)(icalparameter *param, void *data), + void *callback_data); +/** Returns the icaltimezone in the component corresponding to the + TZID, or NULL if it can't be found. */ +icaltimezone* icalcomponent_get_timezone(icalcomponent* comp, + const char *tzid); +int icalproperty_recurrence_is_excluded(icalcomponent *comp, + struct icaltimetype *dtstart, + struct icaltimetype *recurtime); + +void icalcomponent_foreach_recurrence(icalcomponent* comp, + struct icaltimetype start, + struct icaltimetype end, + void (*callback)(icalcomponent *comp, + struct icaltime_span *span, + void *data), + void *callback_data); /*************** Type Specific routines ***************/ icalcomponent* icalcomponent_new_vcalendar(); icalcomponent* icalcomponent_new_vevent(); icalcomponent* icalcomponent_new_vtodo(); icalcomponent* icalcomponent_new_vjournal(); icalcomponent* icalcomponent_new_valarm(); icalcomponent* icalcomponent_new_vfreebusy(); icalcomponent* icalcomponent_new_vtimezone(); icalcomponent* icalcomponent_new_xstandard(); icalcomponent* icalcomponent_new_xdaylight(); +icalcomponent* icalcomponent_new_vagenda(); +icalcomponent* icalcomponent_new_vquery(); +#endif /* !ICALCOMPONENT_H */ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*====================================================================== + FILE: icaltimezone.h + CREATOR: Damon Chaplin 15 March 2001 -#endif /* !ICALCOMPONENT_H */ + (C) COPYRIGHT 2001, Damon Chaplin + + 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/ + + +======================================================================*/ +/** + * @file icaltimezone.h + * @brief timezone handling routines + */ + +#ifndef ICALTIMEZONE_H +#define ICALTIMEZONE_H + +#include <stdio.h> /* For FILE* */ + + +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +/** @brief An opaque struct representing a timezone. + * We declare this here to avoid a circular dependancy. + */ +typedef struct _icaltimezone icaltimezone; +#endif + +/** + * @par Creating/Destroying individual icaltimezones. + */ + +/** Creates a new icaltimezone. */ +icaltimezone *icaltimezone_new (void); + +/** Frees all memory used for the icaltimezone. Set free_struct to free the + icaltimezone struct as well. */ +void icaltimezone_free (icaltimezone *zone, + int free_struct); + + +/** + * @par Accessing timezones. + */ + +/** Free any builtin timezone information **/ +void icaltimezone_free_builtin_timezones(void); + +/** Returns the array of builtin icaltimezones. */ +icalarray* icaltimezone_get_builtin_timezones (void); +/** Returns a single builtin timezone, given its Olson city name. */ +icaltimezone* icaltimezone_get_builtin_timezone (const char *location); +/** Returns a single builtin timezone, given its TZID. */ +icaltimezone* icaltimezone_get_builtin_timezone_from_tzid (const char *tzid); + +/** Returns the UTC timezone. */ +icaltimezone* icaltimezone_get_utc_timezone (void); + +/** Returns the TZID of a timezone. */ +char* icaltimezone_get_tzid (icaltimezone *zone); + +/** Returns the city name of a timezone. */ +char* icaltimezone_get_location (icaltimezone *zone); + +/** Returns the TZNAME properties used in the latest STANDARD and DAYLIGHT + components. If they are the same it will return just one, e.g. "LMT". + If they are different it will format them like "EST/EDT". Note that this + may also return NULL. */ +char* icaltimezone_get_tznames (icaltimezone *zone); + +/** Returns the latitude of a builtin timezone. */ +double icaltimezone_get_latitude (icaltimezone *zone); + +/** Returns the longitude of a builtin timezone. */ +double icaltimezone_get_longitude (icaltimezone *zone); + +/** Returns the VTIMEZONE component of a timezone. */ +icalcomponent* icaltimezone_get_component (icaltimezone *zone); + +/** Sets the VTIMEZONE component of an icaltimezone, initializing the tzid, + location & tzname fields. It returns 1 on success or 0 on failure, i.e. + no TZID was found. */ +int icaltimezone_set_component (icaltimezone *zone, + icalcomponent *comp); + +/** + * @par Converting times between timezones. + */ + +void icaltimezone_convert_time (struct icaltimetype *tt, + icaltimezone *from_zone, + icaltimezone *to_zone); + + +/** + * @par Getting offsets from UTC. + */ + +/** Calculates the UTC offset of a given local time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int icaltimezone_get_utc_offset (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight); + +/** Calculates the UTC offset of a given UTC time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int icaltimezone_get_utc_offset_of_utc_time (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight); + + + +/* + * Handling arrays of timezones. Mainly for internal use. + */ +icalarray* icaltimezone_array_new (void); + +void icaltimezone_array_append_from_vtimezone (icalarray *timezones, + icalcomponent *child); +void icaltimezone_array_free (icalarray *timezones); + + +/* + * @par Handling the default location the timezone files + */ + +/** Set the directory to look for the zonefiles */ +void set_zone_directory(char *path); + +/** Free memory dedicated to the zonefile directory */ +void free_zone_directory(void); + +/* + * @par Debugging Output. + */ + +/** Dumps information about changes in the timezone up to and including + max_year. */ +int icaltimezone_dump_changes (icaltimezone *zone, + int max_year, + FILE *fp); + +#endif /* ICALTIMEZONE_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalparser.h CREATOR: eric 20 April 1999 - $Id$ (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 icalparser.h ======================================================================*/ #ifndef ICALPARSER_H #define ICALPARSER_H #include <stdio.h> /* For FILE* */ -typedef void* icalparser; +typedef struct icalparser_impl icalparser; -/*********************************************************************** - * Line-oriented parsing. +/** + * @file icalparser.h + * @brief Line-oriented parsing. * - * Create a new parser via icalparse_new_parser, then add ines one at + * Create a new parser via icalparse_new_parser, then add lines one at * a time with icalparse_add_line(). icalparser_add_line() will return * non-zero when it has finished with a component. - ***********************************************************************/ + */ typedef enum icalparser_state { ICALPARSER_ERROR, ICALPARSER_SUCCESS, ICALPARSER_BEGIN_COMP, ICALPARSER_END_COMP, ICALPARSER_IN_PROGRESS } icalparser_state; icalparser* icalparser_new(void); icalcomponent* icalparser_add_line(icalparser* parser, char* str ); icalcomponent* icalparser_clean(icalparser* parser); icalparser_state icalparser_get_state(icalparser* parser); void icalparser_free(icalparser* parser); -/*********************************************************************** +/** * Message oriented parsing. icalparser_parse takes a string that * holds the text ( in RFC 2445 format ) and returns a pointer to an * icalcomponent. The caller owns the memory. line_gen_func is a * pointer to a function that returns one content line per invocation - **********************************************************************/ + */ icalcomponent* icalparser_parse(icalparser *parser, - char* (*line_gen_func)(char *s, size_t size, void *d)); + char* (*line_gen_func)(char *s, size_t size, void *d)); -/* Set the data that icalparser_parse will give to the line_gen_func - as the parameter 'd'*/ +/** + Set the data that icalparser_parse will give to the line_gen_func + as the parameter 'd' + */ void icalparser_set_gen_data(icalparser* parser, void* data); icalcomponent* icalparser_parse_string(const char* str); /*********************************************************************** * Parser support functions ***********************************************************************/ -/* Use the flex/bison parser to turn a string into a value type */ +/** Use the flex/bison parser to turn a string into a value type */ icalvalue* icalparser_parse_value(icalvalue_kind kind, const char* str, icalcomponent** errors); -/* Given a line generator function, return a single iCal content line.*/ +/** Given a line generator function, return a single iCal content line.*/ char* icalparser_get_line(icalparser* parser, char* (*line_gen_func)(char *s, size_t size, void *d)); -char* string_line_generator(char *out, size_t buf_size, void *d); +char* icalparser_string_line_generator(char *out, size_t buf_size, void *d); #endif /* !ICALPARSE_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalmemory.h CREATOR: eric 30 June 1999 - $Id$ - $Locker$ 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 Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef ICALMEMORY_H #define ICALMEMORY_H +#ifndef WIN32 #include <sys/types.h> /* for size_t */ - +#else +#include <stddef.h> +#endif /* Tmp buffers are managed by ical. References can be returned to the caller, although the caller will not own the memory. */ void* icalmemory_tmp_buffer(size_t size); char* icalmemory_tmp_copy(const char* str); -/* Add an externally allocated buffer to the ring. */ +/** Add an externally allocated buffer to the ring. */ void icalmemory_add_tmp_buffer(void*); -/* Free all memory used in the ring */ +/** Free all memory used in the ring */ void icalmemory_free_ring(void); /* Non-tmp buffers must be freed. These are mostly wrappers around * malloc, etc, but are used so the caller can change the memory * allocators in a future version of the library */ void* icalmemory_new_buffer(size_t size); void* icalmemory_resize_buffer(void* buf, size_t size); void icalmemory_free_buffer(void* buf); -/* icalmemory_append_string will copy the string 'string' to the +/** + icalmemory_append_string will copy the string 'string' to the buffer 'buf' starting at position 'pos', reallocing 'buf' if it is too small. 'buf_size' is the size of 'buf' and will be changed if 'buf' is reallocated. 'pos' will point to the last byte of the new string in 'buf', usually a '\0' */ /* THESE ROUTINES CAN NOT BE USED ON TMP BUFFERS. Only use them on normally allocated memory, or on buffers created from icalmemory_new_buffer, never with buffers created by icalmemory_tmp_buffer. If icalmemory_append_string has to resize a buffer on the ring, the ring will loose track of it an you will have memory problems. */ void icalmemory_append_string(char** buf, char** pos, size_t* buf_size, const char* string); -/* icalmemory_append_char is similar, but is appends a character instead of a string */ +/** icalmemory_append_char is similar, but is appends a character instead of a string */ void icalmemory_append_char(char** buf, char** pos, size_t* buf_size, char ch); -/* A wrapper around strdup. Partly to trap calls to strdup, partly - because in -ansi, gcc on Red Hat claims that strudup is undeclared */ +/** A wrapper around strdup. Partly to trap calls to strdup, partly + because in -ansi, gcc on Red Hat claims that strdup is undeclared */ char* icalmemory_strdup(const char *s); #endif /* !ICALMEMORY_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalerror.h CREATOR: eric 09 May 1999 - $Id$ (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 icalerror.h ======================================================================*/ #ifndef ICALERROR_H #define ICALERROR_H #include <assert.h> #include <stdio.h> /* For icalerror_warn() */ #ifdef HAVE_CONFIG_H -#include "config.h" #endif #define ICAL_SETERROR_ISFUNC -/* This routine is called before any error is triggered. It is called +/** This routine is called before any error is triggered. It is called by icalerror_set_errno, so it does not appear in all of the macros below */ void icalerror_stop_here(void); void icalerror_crash_here(void); typedef enum icalerrorenum { - + ICAL_NO_ERROR, /* icalerrno may not be initialized - put it first so and pray that the compiler initialize things to zero */ ICAL_BADARG_ERROR, ICAL_NEWFAILED_ERROR, ICAL_ALLOCATION_ERROR, ICAL_MALFORMEDDATA_ERROR, ICAL_PARSE_ERROR, ICAL_INTERNAL_ERROR, /* Like assert --internal consist. prob */ ICAL_FILE_ERROR, ICAL_USAGE_ERROR, ICAL_UNIMPLEMENTED_ERROR, - ICAL_UNKNOWN_ERROR, /* Used for problems in input to icalerror_strerror()*/ - ICAL_NO_ERROR + ICAL_UNKNOWN_ERROR /* Used for problems in input to icalerror_strerror()*/ } icalerrorenum; -/* The libical error enumeration, like errno*/ -extern icalerrorenum icalerrno; +icalerrorenum * icalerrno_return(void); +#define icalerrno (*(icalerrno_return())) -/* If true, libicl aborts after a call to icalerror_set_error*/ +/** If true, libicl aborts after a call to icalerror_set_error + * + * @warning NOT THREAD SAFE -- recommended that you do not change + * this in a multithreaded program. + */ extern int icalerror_errors_are_fatal; /* Warning messages */ #ifdef __GNUC__ca #define icalerror_warn(message) {fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);} #else /* __GNU_C__ */ #define icalerror_warn(message) {fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);} #endif /* __GNU_C__ */ void icalerror_clear_errno(void); +void _icalerror_set_errno(icalerrorenum); /* Make an individual error fatal or non-fatal. */ typedef enum icalerrorstate { ICAL_ERROR_FATAL, /* Not fata */ ICAL_ERROR_NONFATAL, /* Fatal */ ICAL_ERROR_DEFAULT, /* Use the value of icalerror_errors_are_fatal*/ ICAL_ERROR_UNKNOWN /* Asked state for an unknown error type */ } icalerrorstate ; char* icalerror_strerror(icalerrorenum e); char* icalerror_perror(); void icalerror_set_error_state( icalerrorenum error, icalerrorstate); icalerrorstate icalerror_get_error_state( icalerrorenum error); #ifndef ICAL_SETERROR_ISFUNC #define icalerror_set_errno(x) \ icalerrno = x; \ if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL || \ (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT && \ icalerror_errors_are_fatal == 1 )){ \ icalerror_warn(icalerror_strerror(x)); \ assert(0); \ } #else -void icalerror_set_errno(icalerrorenum); +void icalerror_set_errno(icalerrorenum x); #endif #ifdef ICAL_ERRORS_ARE_FATAL #undef NDEBUG #endif #define icalerror_check_value_type(value,type); #define icalerror_check_property_type(value,type); #define icalerror_check_parameter_type(value,type); #define icalerror_check_component_type(value,type); /* Assert with a message */ #ifdef ICAL_ERRORS_ARE_FATAL #ifdef __GNUC__ #define icalerror_assert(test,message) if(!(test)){fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);icalerror_stop_here(); abort();} #else /*__GNUC__*/ #define icalerror_assert(test,message) if(!(test)){fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);icalerror_stop_here(); abort();} #endif /*__GNUC__*/ #else /* ICAL_ERRORS_ARE_FATAL */ #define icalerror_assert(test,message) #endif /* ICAL_ERRORS_ARE_FATAL */ /* Check & abort if check fails */ #define icalerror_check_arg(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); } /* Check & return void if check fails*/ #define icalerror_check_arg_rv(test,arg) if(!(test)) {icalerror_set_errno(ICAL_BADARG_ERROR); return; } /* Check & return 0 if check fails*/ #define icalerror_check_arg_rz(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0;} /* Check & return an error if check fails*/ #define icalerror_check_arg_re(test,arg,error) if(!(test)) { icalerror_stop_here(); assert(0); return error;} /* Check & return something*/ #define icalerror_check_arg_rx(test,arg,x) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return x;} /* String interfaces to set an error to NONFATAL and restore it to its original value */ icalerrorstate icalerror_supress(const char* error); void icalerror_restore(const char* error, icalerrorstate es); #endif /* !ICALERROR_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalrestriction.h CREATOR: eric 24 April 1999 - $Id$ (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 icalrestriction.h Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifndef ICALRESTRICTION_H #define ICALRESTRICTION_H /* These must stay in this order for icalrestriction_compare to work */ typedef enum icalrestriction_kind { ICAL_RESTRICTION_NONE=0, /* 0 */ ICAL_RESTRICTION_ZERO, /* 1 */ ICAL_RESTRICTION_ONE, /* 2 */ ICAL_RESTRICTION_ZEROPLUS, /* 3 */ ICAL_RESTRICTION_ONEPLUS, /* 4 */ ICAL_RESTRICTION_ZEROORONE, /* 5 */ ICAL_RESTRICTION_ONEEXCLUSIVE, /* 6 */ ICAL_RESTRICTION_ONEMUTUAL, /* 7 */ ICAL_RESTRICTION_UNKNOWN /* 8 */ } icalrestriction_kind; int icalrestriction_compare(icalrestriction_kind restr, int count); int icalrestriction_is_parameter_allowed(icalproperty_kind property, icalparameter_kind parameter); int icalrestriction_check(icalcomponent* comp); #endif /* !ICALRESTRICTION_H */ /* -*- Mode: C -*- ====================================================================== FILE: sspm.h Mime Parser CREATOR: eric 25 June 2000 - $Id$ - $Locker$ The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. 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 Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef SSPM_H #define SSPM_H enum sspm_major_type { SSPM_NO_MAJOR_TYPE, SSPM_TEXT_MAJOR_TYPE, SSPM_IMAGE_MAJOR_TYPE, SSPM_AUDIO_MAJOR_TYPE, SSPM_VIDEO_MAJOR_TYPE, SSPM_APPLICATION_MAJOR_TYPE, SSPM_MULTIPART_MAJOR_TYPE, SSPM_MESSAGE_MAJOR_TYPE, SSPM_UNKNOWN_MAJOR_TYPE }; enum sspm_minor_type { SSPM_NO_MINOR_TYPE, SSPM_ANY_MINOR_TYPE, SSPM_PLAIN_MINOR_TYPE, SSPM_RFC822_MINOR_TYPE, SSPM_DIGEST_MINOR_TYPE, SSPM_CALENDAR_MINOR_TYPE, SSPM_MIXED_MINOR_TYPE, SSPM_RELATED_MINOR_TYPE, SSPM_ALTERNATIVE_MINOR_TYPE, SSPM_PARALLEL_MINOR_TYPE, SSPM_UNKNOWN_MINOR_TYPE }; enum sspm_encoding { SSPM_NO_ENCODING, SSPM_QUOTED_PRINTABLE_ENCODING, SSPM_8BIT_ENCODING, SSPM_7BIT_ENCODING, SSPM_BINARY_ENCODING, SSPM_BASE64_ENCODING, SSPM_UNKNOWN_ENCODING }; enum sspm_error{ SSPM_NO_ERROR, SSPM_UNEXPECTED_BOUNDARY_ERROR, SSPM_WRONG_BOUNDARY_ERROR, SSPM_NO_BOUNDARY_ERROR, SSPM_NO_HEADER_ERROR, SSPM_MALFORMED_HEADER_ERROR }; struct sspm_header { int def; char* boundary; enum sspm_major_type major; enum sspm_minor_type minor; char *minor_text; char ** content_type_params; char* charset; enum sspm_encoding encoding; char* filename; char* content_id; enum sspm_error error; char* error_text; }; struct sspm_part { struct sspm_header header; int level; size_t data_size; void *data; }; struct sspm_action_map { enum sspm_major_type major; enum sspm_minor_type minor; void* (*new_part)(); void (*add_line)(void *part, struct sspm_header *header, char* line, size_t size); void* (*end_part)(void* part); void (*free_part)(void *part); }; char* sspm_major_type_string(enum sspm_major_type type); char* sspm_minor_type_string(enum sspm_minor_type type); char* sspm_encoding_string(enum sspm_encoding type); int sspm_parse_mime(struct sspm_part *parts, size_t max_parts, struct sspm_action_map *actions, char* (*get_string)(char *s, size_t size, void* data), void *get_string_data, struct sspm_header *first_header ); void sspm_free_parts(struct sspm_part *parts, size_t max_parts); char *decode_quoted_printable(char *dest, char *src, size_t *size); char *decode_base64(char *dest, char *src, size_t *size); int sspm_write_mime(struct sspm_part *parts,size_t num_parts, char **output_string, char* header); #endif /*SSPM_H*/ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalmime.h CREATOR: eric 26 July 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/ ======================================================================*/ #ifndef ICALMIME_H #define ICALMIME_H icalcomponent* icalmime_parse( char* (*line_gen_func)(char *s, size_t size, void *d), void *data); /* The inverse of icalmime_parse, not implemented yet. Use sspm.h directly. */ char* icalmime_as_mime_string(char* component); #endif /* !ICALMIME_H */ /* -*- Mode: C -*- ====================================================================== FILE: icallangbind.h CREATOR: eric 25 jan 2001 DESCRIPTION: - $Id$ - $Locker$ (C) COPYRIGHT 1999 Eric Busboom http://www.softwarestudio.org This package is free software and is provided "as is" without express or implied warranty. It may be used, redistributed and/or modified under the same terms as perl itself. ( Either the Artistic License or the GPL. ) ======================================================================*/ #ifndef __ICALLANGBIND_H__ #define __ICALLANGBIND_H__ int* icallangbind_new_array(int size); void icallangbind_free_array(int* array); int icallangbind_access_array(int* array, int index); icalproperty* icallangbind_get_property(icalcomponent *c, int n, const char* prop); const char* icallangbind_get_property_val(icalproperty* p); const char* icallangbind_get_parameter(icalproperty *p, const char* parameter); icalcomponent* icallangbind_get_component(icalcomponent *c, const char* comp); icalproperty* icallangbind_get_first_property(icalcomponent *c, const char* prop); icalproperty* icallangbind_get_next_property(icalcomponent *c, const char* prop); icalcomponent* icallangbind_get_first_component(icalcomponent *c, const char* comp); icalcomponent* icallangbind_get_next_component(icalcomponent *c, const char* comp); +icalparameter* icallangbind_get_first_parameter(icalproperty *prop); + +icalparameter* icallangbind_get_next_parameter(icalproperty *prop); const char* icallangbind_property_eval_string(icalproperty* prop, char* sep); int icallangbind_string_to_open_flag(const char* str); + +const char* icallangbind_quote_as_ical(const char* str); #endif /*__ICALLANGBIND_H__*/ +#ifdef __cplusplus +}; +#endif diff --git a/libical/src/libical/icalarray.c b/libical/src/libical/icalarray.c new file mode 100644 index 0000000..78e1ada --- a/dev/null +++ b/libical/src/libical/icalarray.c @@ -0,0 +1,163 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- + ====================================================================== + FILE: icalarray.c + CREATOR: Damon Chaplin 07 March 2001 + + $Id$ + $Locker$ + + (C) COPYRIGHT 2001, Ximian, Inc. + + 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/ + + + ======================================================================*/ + +/** @file icalarray.c + * + * @brief An array of arbitrarily-sized elements which grows + * dynamically as elements are added. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#include "icalarray.h" +#include "icalerror.h" + + +static void icalarray_expand (icalarray *array, + int space_needed); + +/** @brief Constructor + */ + +icalarray* +icalarray_new (int element_size, + int increment_size) +{ + icalarray *array; + + array = (icalarray*) malloc (sizeof (icalarray)); + if (!array) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return NULL; + } + + array->element_size = element_size; + array->increment_size = increment_size; + array->num_elements = 0; + array->space_allocated = 0; + array->data = NULL; + + return array; +} + +/** @brief Destructor + */ + +void +icalarray_free (icalarray *array) +{ + if (array->data) + free (array->data); + free (array); +} + + +void +icalarray_append (icalarray *array, + void *element) +{ + if (array->num_elements >= array->space_allocated) + icalarray_expand (array, 1); + + memcpy ((char *)(array->data) + ( array->num_elements * array->element_size ), element, + array->element_size); + array->num_elements++; +} + + +void* +icalarray_element_at (icalarray *array, + int position) +{ + assert (position >= 0); + assert (position < array->num_elements); + + return (char *)(array->data) + (position * array->element_size); +} + + +void +icalarray_remove_element_at (icalarray *array, + int position) +{ + void *dest; + int elements_to_move; + + assert (position >= 0); + assert (position < array->num_elements); + + dest = (char *)array->data + (position * array->element_size); + elements_to_move = array->num_elements - position - 1; + + if (elements_to_move > 0) + memmove (dest, (char *)dest + array->element_size, + elements_to_move * array->element_size); + + array->num_elements--; +} + + +void +icalarray_sort (icalarray *array, + int (*compare) (const void *, + const void *)) +{ + qsort (array->data, array->num_elements, array->element_size, compare); +} + + +static void +icalarray_expand (icalarray *array, + int space_needed) +{ + int new_space_allocated; + void *new_data; + + new_space_allocated = array->space_allocated + array->increment_size; + + if (space_needed > array->increment_size) + new_space_allocated += space_needed; + + /* + new_data = realloc (array->data, + new_space_allocated * array->element_size); + */ + new_data = malloc(new_space_allocated * array->element_size); + memcpy(new_data,array->data,array->element_size*array->space_allocated); + free(array->data); + + if (new_data) { + array->data = new_data; + array->space_allocated = new_space_allocated; + } else { + icalerror_set_errno(ICAL_ALLOCATION_ERROR); + } +} + + diff --git a/libical/src/libical/icalarray.h b/libical/src/libical/icalarray.h new file mode 100644 index 0000000..e265167 --- a/dev/null +++ b/libical/src/libical/icalarray.h @@ -0,0 +1,63 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*====================================================================== + FILE: icalarray.h + CREATOR: Damon Chaplin 07 March 2001 + + + $Id$ + $Locker$ + + (C) COPYRIGHT 2001, Ximian, Inc. + + 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/ + + +======================================================================*/ + + +#ifndef ICALARRAY_H +#define ICALARRAY_H + +/** @file icalarray.h + * + * @brief An array of arbitrarily-sized elements which grows + * dynamically as elements are added. + */ + +typedef struct _icalarray icalarray; +struct _icalarray { + unsigned int element_size; + unsigned int increment_size; + unsigned int num_elements; + unsigned int space_allocated; + void *data; +}; + + + +icalarray *icalarray_new (int element_size, + int increment_size); +void icalarray_free (icalarray *array); + +void icalarray_append (icalarray *array, + void *element); +void icalarray_remove_element_at (icalarray *array, + int position); + +void *icalarray_element_at (icalarray *array, + int position); + +void icalarray_sort (icalarray *array, + int (*compare) (const void *, const void *)); + + +#endif /* ICALARRAY_H */ diff --git a/libical/src/libical/icalattach.c b/libical/src/libical/icalattach.c new file mode 100644 index 0000000..8da9d43 --- a/dev/null +++ b/libical/src/libical/icalattach.c @@ -0,0 +1,139 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalattach.c + CREATOR: acampi 28 May 02 + + $Id$ + $Locker$ + + + (C) COPYRIGHT 2000, Andrea Campi + + 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 icaltypes.c + + ======================================================================*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "icaltypes.h" +#include "icalerror.h" +#include "icalmemory.h" +#include "icalattachimpl.h" +#include <stdlib.h> /* for malloc and abs() */ +#include <errno.h> /* for errno */ +#include <string.h> /* for icalmemory_strdup */ +#include <assert.h> + +icalattach * +icalattach_new_from_url (const char *url) +{ + icalattach *attach; + char *url_copy; + + icalerror_check_arg_rz ((url != NULL), "url"); + + if ((attach = malloc (sizeof (icalattach))) == NULL) { + errno = ENOMEM; + return NULL; + } + + if ((url_copy = strdup (url)) == NULL) { + free (attach); + errno = ENOMEM; + return NULL; + } + + attach->refcount = 1; + attach->is_url = 1; + attach->u.url.url = url_copy; + + return attach; +} + +icalattach * +icalattach_new_from_data (unsigned char *data, icalattach_free_fn_t free_fn, + void *free_fn_data) +{ + icalattach *attach; + + icalerror_check_arg_rz ((data != NULL), "data"); + + if ((attach = malloc (sizeof (icalattach))) == NULL) { + errno = ENOMEM; + return NULL; + } + + attach->refcount = 1; + attach->is_url = 0; + attach->u.data.data = data; + attach->u.data.free_fn = free_fn; + attach->u.data.free_fn_data = free_fn_data; + + return attach; +} + +void +icalattach_ref (icalattach *attach) +{ + icalerror_check_arg_rv ((attach != NULL), "attach"); + icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 0"); + + attach->refcount++; +} + +void +icalattach_unref (icalattach *attach) +{ + icalerror_check_arg_rv ((attach != NULL), "attach"); + icalerror_check_arg_rv ((attach->refcount > 0), "attach->refcount > 0"); + + attach->refcount--; + + if (attach->refcount != 0) + return; + + if (attach->is_url) + free (attach->u.url.url); + else if (attach->u.data.free_fn) + (* attach->u.data.free_fn) (attach->u.data.data, attach->u.data.free_fn_data); + + free (attach); +} + +int +icalattach_get_is_url (icalattach *attach) +{ + icalerror_check_arg_rz ((attach != NULL), "attach"); + + return attach->is_url ? 1 : 0; +} + +const char * +icalattach_get_url (icalattach *attach) +{ + icalerror_check_arg_rz ((attach != NULL), "attach"); + icalerror_check_arg_rz ((attach->is_url), "attach->is_url"); + + return attach->u.url.url; +} + +unsigned char * +icalattach_get_data (icalattach *attach) +{ + icalerror_check_arg_rz ((attach != NULL), "attach"); + icalerror_check_arg_rz ((!attach->is_url), "!attach->is_url"); + + return attach->u.data.data; +} diff --git a/libical/src/libical/icalattach.h b/libical/src/libical/icalattach.h new file mode 100644 index 0000000..ba4488d --- a/dev/null +++ b/libical/src/libical/icalattach.h @@ -0,0 +1,60 @@ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalattach.h + CREATOR: acampi 28 May 02 + + + (C) COPYRIGHT 2002, Andrea Campi + + 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 icalattach.h + +======================================================================*/ + +#ifndef ICALATTACH_H +#define ICALATTACH_H + + +typedef struct icalattach_impl icalattach; + +typedef void (* icalattach_free_fn_t) (unsigned char *data, void *user_data); + +icalattach *icalattach_new_from_url (const char *url); +icalattach *icalattach_new_from_data (unsigned char *data, + icalattach_free_fn_t free_fn, void *free_fn_data); + +void icalattach_ref (icalattach *attach); +void icalattach_unref (icalattach *attach); + +int icalattach_get_is_url (icalattach *attach); +const char *icalattach_get_url (icalattach *attach); +unsigned char *icalattach_get_data (icalattach *attach); + +struct icalattachtype* icalattachtype_new(void); +void icalattachtype_add_reference(struct icalattachtype* v); +void icalattachtype_free(struct icalattachtype* v); + +void icalattachtype_set_url(struct icalattachtype* v, char* url); +char* icalattachtype_get_url(struct icalattachtype* v); + +void icalattachtype_set_base64(struct icalattachtype* v, char* base64, + int owns); +char* icalattachtype_get_base64(struct icalattachtype* v); + +void icalattachtype_set_binary(struct icalattachtype* v, char* binary, + int owns); +void* icalattachtype_get_binary(struct icalattachtype* v); + + + +#endif /* !ICALATTACH_H */ diff --git a/libical/src/libical/icalattachimpl.h b/libical/src/libical/icalattachimpl.h new file mode 100644 index 0000000..b8abe63 --- a/dev/null +++ b/libical/src/libical/icalattachimpl.h @@ -0,0 +1,59 @@ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalattachimpl.h + CREATOR: acampi 28 May 02 + + $Id$ + + + (C) COPYRIGHT 2000, Andrea Campi + + 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 icalattachimpl.h + + +======================================================================*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#ifndef ICALATTACHIMPL_H +#define ICALATTACHIMPL_H + +#include "icalattach.h" + +/* Private structure for ATTACH values */ +struct icalattach_impl { + /* Reference count */ + int refcount; + + union { + /* URL attachment data */ + struct { + char *url; + } url; + + /* Inline data */ + struct { + unsigned char *data; + icalattach_free_fn_t free_fn; + void *free_fn_data; + } data; + } u; + + /* TRUE if URL, FALSE if inline data */ + unsigned int is_url : 1; +}; + +#endif diff --git a/libical/src/libical/icalcomponent.c b/libical/src/libical/icalcomponent.c index af0d3ec..fbd0492 100644 --- a/libical/src/libical/icalcomponent.c +++ b/libical/src/libical/icalcomponent.c @@ -1,1488 +1,2595 @@ /*====================================================================== FILE: icalcomponent.c CREATOR: eric 28 April 1999 $Id$ - (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 icalcomponent.c ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "icalcomponent.h" #include "pvl.h" /* "Pointer-to-void list" */ #include "icalerror.h" #include "icalmemory.h" #include "icalenums.h" #include "icaltime.h" +#include "icalarray.h" +#include "icaltimezone.h" #include "icalduration.h" #include "icalperiod.h" #include "icalparser.h" +#include "icalrestriction.h" #include <stdlib.h> /* for malloc */ #include <stdarg.h> /* for va_list, etc */ #include <errno.h> #include <assert.h> #include <stdio.h> /* for fprintf */ -#include <string.h> - -#define MAX_TMP 1024 +#include <string.h> /* for strdup */ +#include <limits.h> /* for INT_MAX */ struct icalcomponent_impl { char id[5]; icalcomponent_kind kind; char* x_name; pvl_list properties; pvl_elem property_iterator; pvl_list components; pvl_elem component_iterator; icalcomponent* parent; + + /** An array of icaltimezone structs. We use this so we can do fast + lookup of timezones using binary searches. timezones_sorted is + set to 0 whenever we add a timezone, so we remember to sort the + array before doing a binary search. */ + icalarray* timezones; + int timezones_sorted; }; /* icalproperty functions that only components get to use */ void icalproperty_set_parent(icalproperty* property, icalcomponent* component); icalcomponent* icalproperty_get_parent(icalproperty* property); -void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args); -icalcomponent* icalcomponent_new_impl (icalcomponent_kind kind); -int icalcomponent_property_sorter(void *a, void *b); - - -void icalcomponent_add_children(struct icalcomponent_impl *impl,va_list args) +void icalcomponent_add_children(icalcomponent *impl,va_list args); +static icalcomponent* icalcomponent_new_impl (icalcomponent_kind kind); + +static void icalcomponent_merge_vtimezone (icalcomponent *comp, + icalcomponent *vtimezone, + icalarray *tzids_to_rename); +static void icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, + icalcomponent *vtimezone, + icalproperty *tzid_prop, + const char *tzid, + icalarray *tzids_to_rename); +static unsigned int icalcomponent_get_tzid_prefix_len (const char *tzid); +static void icalcomponent_rename_tzids(icalcomponent* comp, + icalarray* rename_table); +static void icalcomponent_rename_tzids_callback(icalparameter *param, + void *data); +static int icalcomponent_compare_vtimezones (icalcomponent *vtimezone1, + icalcomponent *vtimezone2); +static int icalcomponent_compare_timezone_fn (const void *elem1, + const void *elem2); + + +void icalcomponent_add_children(icalcomponent *impl, va_list args) { void* vp; while((vp = va_arg(args, void*)) != 0) { assert (icalcomponent_isa_component(vp) != 0 || icalproperty_isa_property(vp) != 0 ) ; if (icalcomponent_isa_component(vp) != 0 ){ - - icalcomponent_add_component((icalcomponent*)impl, - (icalcomponent*)vp); + icalcomponent_add_component(impl, (icalcomponent*)vp); } else if (icalproperty_isa_property(vp) != 0 ){ - - icalcomponent_add_property((icalcomponent*)impl, - (icalproperty*)vp); + icalcomponent_add_property(impl, (icalproperty*)vp); } } } -icalcomponent* +static icalcomponent* icalcomponent_new_impl (icalcomponent_kind kind) { - struct icalcomponent_impl* comp; + icalcomponent* comp; - if ( ( comp = (struct icalcomponent_impl*) - malloc(sizeof(struct icalcomponent_impl))) == 0) { + if (!icalcomponent_kind_is_valid(kind)) + return NULL; + + if ( ( comp = (icalcomponent*) malloc(sizeof(icalcomponent))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } strcpy(comp->id,"comp"); comp->kind = kind; comp->properties = pvl_newlist(); comp->property_iterator = 0; comp->components = pvl_newlist(); comp->component_iterator = 0; comp->x_name = 0; comp->parent = 0; + comp->timezones = NULL; + comp->timezones_sorted = 1; return comp; } +/** @brief Constructor + */ icalcomponent* icalcomponent_new (icalcomponent_kind kind) { - return (icalcomponent*)icalcomponent_new_impl(kind); + return icalcomponent_new_impl(kind); } +/** @brief Constructor + */ icalcomponent* icalcomponent_vanew (icalcomponent_kind kind, ...) { va_list args; - struct icalcomponent_impl *impl = icalcomponent_new_impl(kind); + icalcomponent *impl = icalcomponent_new_impl(kind); if (impl == 0){ return 0; } va_start(args,kind); icalcomponent_add_children(impl, args); va_end(args); - return (icalcomponent*) impl; + return impl; } +/** @brief Constructor + */ icalcomponent* icalcomponent_new_from_string(char* str) { return icalparser_parse_string(str); } -icalcomponent* icalcomponent_new_clone(icalcomponent* component) +/** @brief Constructor + */ +icalcomponent* icalcomponent_new_clone(icalcomponent* old) { - struct icalcomponent_impl *old = (struct icalcomponent_impl*)component; - struct icalcomponent_impl *new; + icalcomponent *new; icalproperty *p; icalcomponent *c; pvl_elem itr; - icalerror_check_arg_rz( (component!=0), "component"); + icalerror_check_arg_rz( (old!=0), "component"); new = icalcomponent_new_impl(old->kind); if (new == 0){ return 0; } for( itr = pvl_head(old->properties); itr != 0; itr = pvl_next(itr)) { p = (icalproperty*)pvl_data(itr); icalcomponent_add_property(new,icalproperty_new_clone(p)); } for( itr = pvl_head(old->components); itr != 0; itr = pvl_next(itr)) { c = (icalcomponent*)pvl_data(itr); icalcomponent_add_component(new,icalcomponent_new_clone(c)); } return new; } - +/*** @brief Destructor + */ void -icalcomponent_free (icalcomponent* component) +icalcomponent_free (icalcomponent* c) { icalproperty* prop; icalcomponent* comp; - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - icalerror_check_arg_rv( (component!=0), "component"); + icalerror_check_arg_rv( (c!=0), "component"); #ifdef ICAL_FREE_ON_LIST_IS_ERROR icalerror_assert( (c->parent ==0),"Tried to free a component that is still attached to a parent component"); #else if(c->parent != 0){ return; } #endif - if(component != 0 ){ + if(c != 0 ){ - while( (prop=pvl_pop(c->properties)) != 0){ - assert(prop != 0); - icalproperty_set_parent(prop,0); - icalproperty_free(prop); - } - - pvl_free(c->properties); + if ( c->properties != 0 ) + { + while( (prop=pvl_pop(c->properties)) != 0){ + assert(prop != 0); + icalproperty_set_parent(prop,0); + icalproperty_free(prop); + } + pvl_free(c->properties); + } + while( (comp=pvl_data(pvl_head(c->components))) != 0){ assert(comp!=0); - icalcomponent_remove_component(component,comp); + icalcomponent_remove_component(c,comp); icalcomponent_free(comp); } pvl_free(c->components); if (c->x_name != 0) { free(c->x_name); } + if (c->timezones) + icaltimezone_array_free (c->timezones); + c->kind = ICAL_NO_COMPONENT; c->properties = 0; c->property_iterator = 0; c->components = 0; c->component_iterator = 0; c->x_name = 0; c->id[0] = 'X'; + c->timezones = NULL; free(c); } } char* -icalcomponent_as_ical_string (icalcomponent* component) +icalcomponent_as_ical_string (icalcomponent* impl) { char* buf, *out_buf; const char* tmp_buf; size_t buf_size = 1024; char* buf_ptr = 0; pvl_elem itr; - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; +/* WIN32 automatically adds the \r, Anybody else need it? #ifdef ICAL_UNIX_NEWLINE +*/ char newline[] = "\n"; +/* #else - char newline[] = "\n"; + char newline[] = "\r\n"; #endif +*/ + icalcomponent *c; icalproperty *p; - icalcomponent_kind kind = icalcomponent_isa(component); + icalcomponent_kind kind = icalcomponent_isa(impl); const char* kind_string; buf = icalmemory_new_buffer(buf_size); buf_ptr = buf; - icalerror_check_arg_rz( (component!=0), "component"); + icalerror_check_arg_rz( (impl!=0), "component"); icalerror_check_arg_rz( (kind!=ICAL_NO_COMPONENT), "component kind is ICAL_NO_COMPONENT"); kind_string = icalcomponent_kind_to_string(kind); icalerror_check_arg_rz( (kind_string!=0),"Unknown kind of component"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); - + + for( itr = pvl_head(impl->properties); itr != 0; itr = pvl_next(itr)) - { - // printf("3333calcomponent_as_ical_string System Timezone2: %s %s \n", *tzname, getenv("TZ") ); - + { p = (icalproperty*)pvl_data(itr); icalerror_assert((p!=0),"Got a null property"); tmp_buf = icalproperty_as_ical_string(p); icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf); } for( itr = pvl_head(impl->components); itr != 0; itr = pvl_next(itr)) - { - + { c = (icalcomponent*)pvl_data(itr); tmp_buf = icalcomponent_as_ical_string(c); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, tmp_buf); } - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:"); //tzset(); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, icalcomponent_kind_to_string(kind)); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); //tzset(); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); out_buf = icalmemory_tmp_copy(buf); free(buf); return out_buf; } int icalcomponent_is_valid (icalcomponent* component) { - struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; - - - if ( (strcmp(impl->id,"comp") == 0) && - impl->kind != ICAL_NO_COMPONENT){ + if ( (strcmp(component->id,"comp") == 0) && + component->kind != ICAL_NO_COMPONENT){ return 1; } else { return 0; } } icalcomponent_kind -icalcomponent_isa (icalcomponent* component) +icalcomponent_isa (const icalcomponent* component) { - struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; - icalerror_check_arg_rz( (component!=0), "component"); + icalerror_check_arg_rx( (component!=0), "component", ICAL_NO_COMPONENT); if(component != 0) { - return impl->kind; + return component->kind; } return ICAL_NO_COMPONENT; } int icalcomponent_isa_component (void* component) { - struct icalcomponent_impl *impl = (struct icalcomponent_impl *)component; + icalcomponent *impl = component; icalerror_check_arg_rz( (component!=0), "component"); if (strcmp(impl->id,"comp") == 0) { return 1; } else { return 0; } } -int icalcomponent_property_sorter(void *a, void *b) -{ - icalproperty_kind kinda, kindb; - const char *ksa, *ksb; - - kinda = icalproperty_isa((icalproperty*)a); - kindb = icalproperty_isa((icalproperty*)b); - - ksa = icalproperty_kind_to_string(kinda); - ksb = icalproperty_kind_to_string(kindb); - - return strcmp(ksa,ksb); -} - - void icalcomponent_add_property (icalcomponent* component, icalproperty* property) { - struct icalcomponent_impl *impl; - icalerror_check_arg_rv( (component!=0), "component"); icalerror_check_arg_rv( (property!=0), "property"); - impl = (struct icalcomponent_impl*)component; - icalerror_assert( (!icalproperty_get_parent(property)),"The property has already been added to a component. Remove the property with icalcomponent_remove_property before calling icalcomponent_add_property"); icalproperty_set_parent(property,component); -#ifdef ICAL_INSERT_ORDERED - pvl_insert_ordered(impl->properties, - icalcomponent_property_sorter,property); -#else - pvl_push(impl->properties,property); -#endif - + pvl_push(component->properties,property); } void icalcomponent_remove_property (icalcomponent* component, icalproperty* property) { - struct icalcomponent_impl *impl; pvl_elem itr, next_itr; - struct icalproperty_impl *pimpl; icalerror_check_arg_rv( (component!=0), "component"); icalerror_check_arg_rv( (property!=0), "property"); - impl = (struct icalcomponent_impl*)component; - - pimpl = (struct icalproperty_impl*)property; - icalerror_assert( (icalproperty_get_parent(property)),"The property is not a member of a component"); - for( itr = pvl_head(impl->properties); + for( itr = pvl_head(component->properties); itr != 0; itr = next_itr) { next_itr = pvl_next(itr); if( pvl_data(itr) == (void*)property ){ - if (impl->property_iterator == itr){ - impl->property_iterator = pvl_next(itr); + if (component->property_iterator == itr){ + component->property_iterator = pvl_next(itr); } - pvl_remove( impl->properties, itr); + pvl_remove( component->properties, itr); icalproperty_set_parent(property,0); } } } int icalcomponent_count_properties (icalcomponent* component, icalproperty_kind kind) { int count=0; pvl_elem itr; - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; icalerror_check_arg_rz( (component!=0), "component"); - for( itr = pvl_head(impl->properties); + for( itr = pvl_head(component->properties); itr != 0; itr = pvl_next(itr)) { if(kind == icalproperty_isa((icalproperty*)pvl_data(itr)) || kind == ICAL_ANY_PROPERTY){ count++; } } return count; } icalproperty* icalcomponent_get_current_property (icalcomponent* component) { - - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; icalerror_check_arg_rz( (component!=0),"component"); - if ((c->property_iterator==0)){ + if ((component->property_iterator==0)){ return 0; } - return (icalproperty*) pvl_data(c->property_iterator); - + return (icalproperty*) pvl_data(component->property_iterator); } icalproperty* -icalcomponent_get_first_property (icalcomponent* component, icalproperty_kind kind) +icalcomponent_get_first_property (icalcomponent* c, icalproperty_kind kind) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - icalerror_check_arg_rz( (component!=0),"component"); + icalerror_check_arg_rz( (c!=0),"component"); for( c->property_iterator = pvl_head(c->properties); c->property_iterator != 0; c->property_iterator = pvl_next(c->property_iterator)) { icalproperty *p = (icalproperty*) pvl_data(c->property_iterator); if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) { return p; } } return 0; } icalproperty* -icalcomponent_get_next_property (icalcomponent* component, icalproperty_kind kind) +icalcomponent_get_next_property (icalcomponent* c, icalproperty_kind kind) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - icalerror_check_arg_rz( (component!=0),"component"); + icalerror_check_arg_rz( (c!=0),"component"); if (c->property_iterator == 0){ return 0; } for( c->property_iterator = pvl_next(c->property_iterator); c->property_iterator != 0; c->property_iterator = pvl_next(c->property_iterator)) { icalproperty *p = (icalproperty*) pvl_data(c->property_iterator); if (icalproperty_isa(p) == kind || kind == ICAL_ANY_PROPERTY) { return p; } } return 0; } icalproperty** icalcomponent_get_properties (icalcomponent* component, icalproperty_kind kind); void icalcomponent_add_component (icalcomponent* parent, icalcomponent* child) { - struct icalcomponent_impl *impl, *cimpl; - icalerror_check_arg_rv( (parent!=0), "parent"); icalerror_check_arg_rv( (child!=0), "child"); - impl = (struct icalcomponent_impl*)parent; - cimpl = (struct icalcomponent_impl*)child; - - if (cimpl->parent !=0) { + if (child->parent !=0) { icalerror_set_errno(ICAL_USAGE_ERROR); } - cimpl->parent = parent; + child->parent = parent; + + pvl_push(parent->components,child); - pvl_push(impl->components,child); + /* If the new component is a VTIMEZONE, add it to our array. */ + if (child->kind == ICAL_VTIMEZONE_COMPONENT) { + /* FIXME: Currently we are also creating this array when loading in + a builtin VTIMEZONE, when we don't need it. */ + if (!parent->timezones) + parent->timezones = icaltimezone_array_new (); + + icaltimezone_array_append_from_vtimezone (parent->timezones, child); + + /* Flag that we need to sort it before doing any binary searches. */ + parent->timezones_sorted = 0; + } } void icalcomponent_remove_component (icalcomponent* parent, icalcomponent* child) { - struct icalcomponent_impl *impl,*cimpl; pvl_elem itr, next_itr; icalerror_check_arg_rv( (parent!=0), "parent"); icalerror_check_arg_rv( (child!=0), "child"); - impl = (struct icalcomponent_impl*)parent; - cimpl = (struct icalcomponent_impl*)child; - - for( itr = pvl_head(impl->components); + /* If the component is a VTIMEZONE, remove it from our array as well. */ + if (child->kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + int i, num_elements; + + num_elements = parent->timezones ? parent->timezones->num_elements : 0; + for (i = 0; i < num_elements; i++) { + zone = icalarray_element_at (parent->timezones, i); + if (icaltimezone_get_component (zone) == child) { + icaltimezone_free (zone, 0); + icalarray_remove_element_at (parent->timezones, i); + break; + } + } + } + + for( itr = pvl_head(parent->components); itr != 0; itr = next_itr) { next_itr = pvl_next(itr); if( pvl_data(itr) == (void*)child ){ - if (impl->component_iterator == itr){ + if (parent->component_iterator == itr){ /* Don't let the current iterator become invalid */ /* HACK. The semantics for this are troubling. */ - impl->component_iterator = - pvl_next(impl->component_iterator); + parent->component_iterator = + pvl_next(parent->component_iterator); } - pvl_remove( impl->components, itr); - cimpl->parent = 0; + pvl_remove( parent->components, itr); + child->parent = 0; break; } } } int icalcomponent_count_components (icalcomponent* component, icalcomponent_kind kind) { int count=0; pvl_elem itr; - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; icalerror_check_arg_rz( (component!=0), "component"); - for( itr = pvl_head(impl->components); + for( itr = pvl_head(component->components); itr != 0; itr = pvl_next(itr)) { if(kind == icalcomponent_isa((icalcomponent*)pvl_data(itr)) || kind == ICAL_ANY_COMPONENT){ count++; } } return count; } icalcomponent* icalcomponent_get_current_component(icalcomponent* component) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - icalerror_check_arg_rz( (component!=0),"component"); - if (c->component_iterator == 0){ + if (component->component_iterator == 0){ return 0; } - return (icalcomponent*) pvl_data(c->component_iterator); + return (icalcomponent*) pvl_data(component->component_iterator); } icalcomponent* -icalcomponent_get_first_component (icalcomponent* component, +icalcomponent_get_first_component (icalcomponent* c, icalcomponent_kind kind) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - - icalerror_check_arg_rz( (component!=0),"component"); + icalerror_check_arg_rz( (c!=0),"component"); for( c->component_iterator = pvl_head(c->components); c->component_iterator != 0; c->component_iterator = pvl_next(c->component_iterator)) { icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator); if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) { return p; } } return 0; } icalcomponent* -icalcomponent_get_next_component (icalcomponent* component, icalcomponent_kind kind) +icalcomponent_get_next_component (icalcomponent* c, icalcomponent_kind kind) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - - icalerror_check_arg_rz( (component!=0),"component"); + icalerror_check_arg_rz( (c!=0),"component"); if (c->component_iterator == 0){ return 0; } for( c->component_iterator = pvl_next(c->component_iterator); c->component_iterator != 0; c->component_iterator = pvl_next(c->component_iterator)) { icalcomponent *p = (icalcomponent*) pvl_data(c->component_iterator); if (icalcomponent_isa(p) == kind || kind == ICAL_ANY_COMPONENT) { return p; } } return 0; } icalcomponent* icalcomponent_get_first_real_component(icalcomponent *c) { icalcomponent *comp; for(comp = icalcomponent_get_first_component(c,ICAL_ANY_COMPONENT); comp != 0; comp = icalcomponent_get_next_component(c,ICAL_ANY_COMPONENT)){ icalcomponent_kind kind = icalcomponent_isa(comp); if(kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT || kind == ICAL_VJOURNAL_COMPONENT || - kind == ICAL_VFREEBUSY_COMPONENT ){ + kind == ICAL_VFREEBUSY_COMPONENT || + kind == ICAL_VQUERY_COMPONENT || + kind == ICAL_VAGENDA_COMPONENT){ return comp; } } return 0; } -time_t icalcomponent_convert_time(icalproperty *p) -{ - struct icaltimetype sict; - time_t convt; - icalproperty *tzp; - - - /* Though it says _dtstart, it will work for dtend too */ - sict = icalproperty_get_dtstart(p); - - tzp = icalproperty_get_first_parameter(p,ICAL_TZID_PARAMETER); - - if (sict.is_utc == 1 && tzp != 0){ - icalerror_warn("icalcomponent_get_span: component has a UTC DTSTART with a timezone specified "); - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return 0; - } - if(sict.is_utc == 1){ - /* _as_timet will use gmtime() to do the conversion */ - convt = icaltime_as_timet(sict); - -#ifdef TEST_CONVERT_TIME - printf("convert time: use as_timet:\n %s\n %s", - icalproperty_as_ical_string(p), ctime(&convt)); -#endif - - } else if (sict.is_utc == 0 && tzp == 0 ) { - time_t offset; - - /* _as_timet will use localtime() to do the conversion */ - convt = icaltime_as_timet(sict); - offset = icaltime_utc_offset(sict,0); - convt += offset; - -#ifdef TEST_CONVERT_TIME - printf("convert time: use as_timet and adjust:\n %s\n %s", - icalproperty_as_ical_string(p), ctime(&convt)); -#endif - } else { - /* Convert the time to UTC for the named timezone*/ - const char* timezone = icalparameter_get_tzid(tzp); - convt = icaltime_as_timet(icaltime_as_utc(sict,timezone)); - -#ifdef TEST_CONVERT_TIME - printf("convert time: use _as_utc:\n %s\n %s", - icalproperty_as_ical_string(p), ctime(&convt)); -#endif - } - - return convt; -} -struct icaltime_span icalcomponent_get_span(icalcomponent* comp) +/** @brief Get the timespan covered by this component, in UTC + * (deprecated) + * + * see icalcomponent_foreach_recurrence() for a better way to + * extract spans from an component. + * + * This method can be called on either a VCALENDAR or any real + * component. If the VCALENDAR contains no real component, but + * contains a VTIMEZONE, we return that span instead. + * This might not be a desirable behavior; we keep it for now + * for backward compatibility, but it might be deprecated at a + * future time. + * + * FIXME this API needs to be clarified. DTEND is defined as the + * first available time after the end of this event, so the span + * should actually end 1 second before DTEND. + */ + +icaltime_span icalcomponent_get_span(icalcomponent* comp) { icalcomponent *inner; - icalproperty *p, *duration; icalcomponent_kind kind; - struct icaltime_span span; - struct icaltimetype start; + icaltime_span span; + struct icaltimetype start, end; span.start = 0; span.end = 0; span.is_busy= 1; /* initial Error checking */ + if (comp == NULL) { + return span; + } -/* icalerror_check_arg_rz( (comp!=0),"comp");*/ - + /* FIXME this might go away */ kind = icalcomponent_isa(comp); - if(kind == ICAL_VCALENDAR_COMPONENT){ inner = icalcomponent_get_first_real_component(comp); /* Maybe there is a VTIMEZONE in there */ if (inner == 0){ inner = icalcomponent_get_first_component(comp, ICAL_VTIMEZONE_COMPONENT); } } else { inner = comp; } if (inner == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/ return span; } kind = icalcomponent_isa(inner); if( !( kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VJOURNAL_COMPONENT || kind == ICAL_VTODO_COMPONENT || kind == ICAL_VFREEBUSY_COMPONENT )) { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); /*icalerror_warn("icalcomponent_get_span: no component specified, or empty VCALENDAR component");*/ return span; } + /* Get to work. starting with DTSTART */ + start = icalcomponent_get_dtstart(comp); + if (icaltime_is_null_time(start)) { + return span; + } + span.start = icaltime_as_timet_with_zone(start, + icaltimezone_get_utc_timezone()); + /* The end time could be specified as either a DTEND or a DURATION */ + /* icalcomponent_get_dtend takes care of these cases. */ + end = icalcomponent_get_dtend(comp); + if (icaltime_is_null_time(end)) { + if (!icaltime_is_date(start)) { + /* If dtstart is a DATE-TIME and there is no DTEND nor DURATION + it takes no time */ + span.start = 0; + return span; + } else { + end = start; + } + } - /* Get to work. starting with DTSTART */ + span.end = icaltime_as_timet_with_zone(end, + icaltimezone_get_utc_timezone()); + if (icaltime_is_date(start)) { + /* Until the end of the day*/ + span.end += 60*60*24 - 1; + } - p = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY); + return span; - if (p ==0 ) { - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - /*icalerror_warn("icalcomponent_get_span: component has no DTSTART time");*/ - return span; +} + +/** + * Decide if this recurrance is acceptable + * + * @param comp A valid icalcomponent. + * @param dtstart The base dtstart value for this component. + * @param recurtime The time to test against. + * + * @return true if the recurrence value is excluded, false otherwise. + * + * This function decides if a specific recurrence value is + * excluded by EXRULE or EXDATE properties. + * + * It's not the most efficient code. You might get better performance + * if you assume that recurtime is always increasing for each + * call. Then you could: + * + * - sort the EXDATE values + * - save the state of each EXRULE iterator for the next call. + * + * In this case though you don't need to worry how you call this + * function. It will always return the correct result. + */ + +int icalproperty_recurrence_is_excluded(icalcomponent *comp, + struct icaltimetype *dtstart, + struct icaltimetype *recurtime) { + icalproperty *exdate, *exrule; + + if (comp == NULL || + dtstart == NULL || + recurtime == NULL || + icaltime_is_null_time(*recurtime)) + /* BAD DATA */ + return 1; + + /** first test against the exdate values **/ + for (exdate = icalcomponent_get_first_property(comp,ICAL_EXDATE_PROPERTY); + exdate != NULL; + exdate = icalcomponent_get_next_property(comp,ICAL_EXDATE_PROPERTY)) { + + struct icaltimetype exdatetime = icalproperty_get_exdate(exdate); + + if (icaltime_compare(*recurtime, exdatetime) == 0) { + /** MATCHED **/ + return 1; + } + } + + /** Now test against the EXRULEs **/ + for (exrule = icalcomponent_get_first_property(comp,ICAL_EXRULE_PROPERTY); + exdate != NULL; + exdate = icalcomponent_get_next_property(comp,ICAL_EXRULE_PROPERTY)) { + + struct icalrecurrencetype recur = icalproperty_get_exrule(exrule); + icalrecur_iterator *exrule_itr = icalrecur_iterator_new(recur, *dtstart); + struct icaltimetype exrule_time; + + while (1) { + int result; + exrule_time = icalrecur_iterator_next(exrule_itr); + + if (icaltime_is_null_time(exrule_time)) + break; + + result = icaltime_compare(*recurtime, exrule_time); + if (result == 0) { + icalrecur_iterator_free(exrule_itr); + return 1; /** MATCH **/ + } + if (result == 1) + break; /** exrule_time > recurtime **/ } + icalrecur_iterator_free(exrule_itr); + } - start = icalproperty_get_dtstart(p); + return 0; /** no matches **/ +} - icalerror_clear_errno(); +/** + * @brief Return the busy status based on the TRANSP property. + * + * @param comp A valid icalcomponent. + * + * @return 1 if the event is a busy item, 0 if it is not. + */ - span.start = icalcomponent_convert_time(p); +static int icalcomponent_is_busy(icalcomponent *comp) { + icalproperty *transp; + enum icalproperty_status status; + int ret = 1; -#ifdef TEST_CONVERT_TIME - printf("convert time:\n %s %s", - icalproperty_as_ical_string(p), ctime(&span.start)); -#endif + /** @todo check access control here, converting busy->free if the + permissions do not allow access... */ - if(icalerrno != ICAL_NO_ERROR){ - span.start = 0; - return span; + /* Is this a busy time? Check the TRANSP property */ + transp = icalcomponent_get_first_property(comp, ICAL_TRANSP_PROPERTY); + + if (transp) { + icalvalue *transp_val = icalproperty_get_value(transp); + + switch (icalvalue_get_transp(transp_val)) { + case ICAL_TRANSP_OPAQUE: + case ICAL_TRANSP_OPAQUENOCONFLICT: + case ICAL_TRANSP_NONE: + ret = 1; + break; + case ICAL_TRANSP_TRANSPARENT: + case ICAL_TRANSP_TRANSPARENTNOCONFLICT: + ret = 0; + break; + default: + ret = 0; + break; } + } + status = icalcomponent_get_status(comp); + if (ret && status) { + switch (status) { + case ICAL_STATUS_CANCELLED: + case ICAL_STATUS_TENTATIVE: + ret = 0; + break; + default: + break; + } + } + return(ret); +} - /* The end time could be specified as either a DTEND or a DURATION */ - p = icalcomponent_get_first_property(inner, ICAL_DTEND_PROPERTY); - duration = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); - if (p==0 && duration == 0 && start.is_date != 1) { - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - /*icalerror_warn("icalcomponent_get_span: component has neither DTEND nor DURATION time");*/ - span.start = 0; - return span; - } - if (p!=0){ - span.end = icalcomponent_convert_time(p); - } else if (start.is_date == 1) { - /* Duration is all day */ - span.end = span.start + 60*60*24; - } else { - /* Use the duration */ - struct icaldurationtype dur; - time_t durt; - - - dur = icalproperty_get_duration(duration); - durt = icaldurationtype_as_int(dur); - span.end = span.start+durt; +/** + * @brief cycle through all recurrances of an event + * + * @param comp A valid VEVENT component + * @param start Ignore timespans before this + * @param end Ignore timespans after this + * @param callback Function called for each timespan within the range + * @param callback_data Pointer passed back to the callback function + * + * This function will call the specified callback function for once + * for the base value of DTSTART, and foreach recurring date/time + * value. + * + * It will filter out events that are specified as an EXDATE or an EXRULE. + * + * @todo We do not filter out duplicate RRULES/RDATES + * @todo We do not handle RDATEs with explicit periods + */ + +void icalcomponent_foreach_recurrence(icalcomponent* comp, + struct icaltimetype start, + struct icaltimetype end, + void (*callback)(icalcomponent *comp, + struct icaltime_span *span, + void *data), + void *callback_data) +{ + struct icaltimetype dtstart, dtend; + icaltime_span recurspan, basespan, limit_span; + time_t limit_start, limit_end; + int dtduration; + icalproperty *rrule, *rdate; + struct icaldurationtype dur; + pvl_elem property_iterator; /* for saving the iterator */ + + if (comp == NULL || callback == NULL) + return; + + dtstart = icalcomponent_get_dtstart(comp); + + if (icaltime_is_null_time(dtstart)) + return; + + + /* The end time could be specified as either a DTEND or a DURATION */ + /* icalcomponent_get_dtend takes care of these cases. */ + dtend = icalcomponent_get_dtend(comp); + + /* Now set up the base span for this item, corresponding to the + base DTSTART and DTEND */ + basespan = icaltime_span_new(dtstart, dtend, 1); + + basespan.is_busy = icalcomponent_is_busy(comp); + + + /** Calculate the ceiling and floor values.. **/ + limit_start = icaltime_as_timet_with_zone(start, icaltimezone_get_utc_timezone()); + if (!icaltime_is_null_time(end)) + limit_end = icaltime_as_timet_with_zone(end, icaltimezone_get_utc_timezone()); + else + limit_end = INT_MAX; /* max 32 bit time_t */ + + limit_span.start = limit_start; + limit_span.end = limit_end; + + + /* Do the callback for the initial DTSTART entry */ + + if (!icalproperty_recurrence_is_excluded(comp, &dtstart, &dtstart)) { + /** call callback action **/ + if (icaltime_span_overlaps(&basespan, &limit_span)) + (*callback) (comp, &basespan, callback_data); + } + + recurspan = basespan; + dtduration = basespan.end - basespan.start; + + /* Now cycle through the rrule entries */ + for (rrule = icalcomponent_get_first_property(comp,ICAL_RRULE_PROPERTY); + rrule != NULL; + rrule = icalcomponent_get_next_property(comp,ICAL_RRULE_PROPERTY)) { + + struct icalrecurrencetype recur = icalproperty_get_rrule(rrule); + icalrecur_iterator *rrule_itr = icalrecur_iterator_new(recur, dtstart); + struct icaltimetype rrule_time = icalrecur_iterator_next(rrule_itr); + /** note that icalrecur_iterator_next always returns dtstart + the first time.. **/ + + while (1) { + rrule_time = icalrecur_iterator_next(rrule_itr); + + if (icaltime_is_null_time(rrule_time)) + break; + + dur = icaltime_subtract(rrule_time, dtstart); + + recurspan.start = basespan.start + icaldurationtype_as_int(dur); + recurspan.end = recurspan.start + dtduration; + + /** save the iterator ICK! **/ + property_iterator = comp->property_iterator; + + if (!icalproperty_recurrence_is_excluded(comp, &dtstart, &rrule_time)) { + /** call callback action **/ + if (icaltime_span_overlaps(&recurspan, &limit_span)) + (*callback) (comp, &recurspan, callback_data); + } + comp->property_iterator = property_iterator; + } /* end of iteration over a specific RRULE */ + + icalrecur_iterator_free(rrule_itr); + } /* end of RRULE loop */ + + + /** Now process RDATE entries **/ + for (rdate = icalcomponent_get_first_property(comp,ICAL_RDATE_PROPERTY); + rdate != NULL; + rdate = icalcomponent_get_next_property(comp,ICAL_RDATE_PROPERTY)) { + + struct icaldatetimeperiodtype rdate_period = icalproperty_get_rdate(rdate); + + /** RDATES can specify raw datetimes, periods, or dates. + we only support raw datetimes for now.. + + @todo Add support for other types **/ + + if (icaltime_is_null_time(rdate_period.time)) + continue; + + dur = icaltime_subtract(rdate_period.time, dtstart); + + recurspan.start = basespan.start + icaldurationtype_as_int(dur); + recurspan.end = recurspan.start + dtduration; + + /** save the iterator ICK! **/ + property_iterator = comp->property_iterator; + + if (!icalproperty_recurrence_is_excluded(comp, &dtstart, &rdate_period.time)) { + /** call callback action **/ + (*callback) (comp, &recurspan, callback_data); } + comp->property_iterator = property_iterator; + } +} + - return span; +int icalcomponent_check_restrictions(icalcomponent* comp){ + icalerror_check_arg_rz(comp!=0,"comp"); + return icalrestriction_check(comp); } +/** @brief returns the number of errors encountered parsing the data + * + * This function counts the number times the X-LIC-ERROR occurs + * in the data structure. + */ int icalcomponent_count_errors(icalcomponent* component) { int errors = 0; icalproperty *p; icalcomponent *c; pvl_elem itr; - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; - for( itr = pvl_head(impl->properties); + for( itr = pvl_head(component->properties); itr != 0; itr = pvl_next(itr)) { p = (icalproperty*)pvl_data(itr); if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) { errors++; } } - for( itr = pvl_head(impl->components); + for( itr = pvl_head(component->components); itr != 0; itr = pvl_next(itr)) { c = (icalcomponent*)pvl_data(itr); errors += icalcomponent_count_errors(c); } return errors; } void icalcomponent_strip_errors(icalcomponent* component) { icalproperty *p; icalcomponent *c; pvl_elem itr, next_itr; - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; - for( itr = pvl_head(impl->properties); + for( itr = pvl_head(component->properties); itr != 0; itr = next_itr) { p = (icalproperty*)pvl_data(itr); next_itr = pvl_next(itr); if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) { icalcomponent_remove_property(component,p); } } - for( itr = pvl_head(impl->components); + for( itr = pvl_head(component->components); itr != 0; itr = pvl_next(itr)) { c = (icalcomponent*)pvl_data(itr); icalcomponent_strip_errors(c); } } /* Hack. This will change the state of the iterators */ void icalcomponent_convert_errors(icalcomponent* component) { icalproperty *p, *next_p; icalcomponent *c; for(p = icalcomponent_get_first_property(component,ICAL_ANY_PROPERTY); p != 0; p = next_p){ next_p = icalcomponent_get_next_property(component,ICAL_ANY_PROPERTY); if(icalproperty_isa(p) == ICAL_XLICERROR_PROPERTY) { struct icalreqstattype rst; icalparameter *param = icalproperty_get_first_parameter (p,ICAL_XLICERRORTYPE_PARAMETER); rst.code = ICAL_UNKNOWN_STATUS; rst.desc = 0; switch(icalparameter_get_xlicerrortype(param)){ case ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR: { rst.code = ICAL_3_2_INVPARAM_STATUS; break; } case ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR: { rst.code = ICAL_3_3_INVPARAMVAL_STATUS; break; } case ICAL_XLICERRORTYPE_PROPERTYPARSEERROR: { rst.code = ICAL_3_0_INVPROPNAME_STATUS; break; } case ICAL_XLICERRORTYPE_VALUEPARSEERROR: { rst.code = ICAL_3_1_INVPROPVAL_STATUS; break; } case ICAL_XLICERRORTYPE_COMPONENTPARSEERROR: { rst.code = ICAL_3_4_INVCOMP_STATUS; break; } default: { + break; } } if (rst.code != ICAL_UNKNOWN_STATUS){ rst.debug = icalproperty_get_xlicerror(p); icalcomponent_add_property(component, icalproperty_new_requeststatus(rst)); icalcomponent_remove_property(component,p); } } } for(c = icalcomponent_get_first_component(component,ICAL_ANY_COMPONENT); c != 0; c = icalcomponent_get_next_component(component,ICAL_ANY_COMPONENT)){ icalcomponent_convert_errors(c); } } icalcomponent* icalcomponent_get_parent(icalcomponent* component) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - - return c->parent; + return component->parent; } void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent) { - struct icalcomponent_impl *c = (struct icalcomponent_impl*)component; - - c->parent = parent; + component->parent = parent; } icalcompiter icalcompiter_null = {ICAL_NO_COMPONENT,0}; struct icalcomponent_kind_map { icalcomponent_kind kind; char name[20]; }; static struct icalcomponent_kind_map component_map[] = { { ICAL_VEVENT_COMPONENT, "VEVENT" }, { ICAL_VTODO_COMPONENT, "VTODO" }, { ICAL_VJOURNAL_COMPONENT, "VJOURNAL" }, { ICAL_VCALENDAR_COMPONENT, "VCALENDAR" }, + { ICAL_VAGENDA_COMPONENT, "VAGENDA" }, { ICAL_VFREEBUSY_COMPONENT, "VFREEBUSY" }, { ICAL_VTIMEZONE_COMPONENT, "VTIMEZONE" }, { ICAL_VALARM_COMPONENT, "VALARM" }, { ICAL_XSTANDARD_COMPONENT, "STANDARD" }, /*These are part of RFC2445 */ { ICAL_XDAYLIGHT_COMPONENT, "DAYLIGHT" }, /*but are not really components*/ { ICAL_X_COMPONENT, "X" }, { ICAL_VSCHEDULE_COMPONENT, "SCHEDULE" }, /* CAP components */ { ICAL_VQUERY_COMPONENT, "VQUERY" }, { ICAL_VCAR_COMPONENT, "VCAR" }, { ICAL_VCOMMAND_COMPONENT, "VCOMMAND" }, /* libical private components */ { ICAL_XLICINVALID_COMPONENT, "X-LIC-UNKNOWN" }, { ICAL_XLICMIMEPART_COMPONENT, "X-LIC-MIME-PART" }, { ICAL_ANY_COMPONENT, "ANY" }, { ICAL_XROOT_COMPONENT, "XROOT" }, /* End of list */ { ICAL_NO_COMPONENT, "" }, }; +int icalcomponent_kind_is_valid(const icalcomponent_kind kind) +{ + int i = 0; + do { + if (component_map[i].kind == kind) + return 1; + } while (component_map[i++].kind != ICAL_NO_COMPONENT); + + return 0; +} const char* icalcomponent_kind_to_string(icalcomponent_kind kind) { int i; for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { if (component_map[i].kind == kind) { return component_map[i].name; } } return 0; } icalcomponent_kind icalcomponent_string_to_kind(const char* string) { int i; if (string ==0 ) { return ICAL_NO_COMPONENT; } for (i=0; component_map[i].kind != ICAL_NO_COMPONENT; i++) { if (strcmp(component_map[i].name, string) == 0) { return component_map[i].kind; } } return ICAL_NO_COMPONENT; } icalcompiter icalcomponent_begin_component(icalcomponent* component,icalcomponent_kind kind) { - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; - icalcompiter itr = icalcompiter_null; + icalcompiter itr; pvl_elem i; itr.kind = kind; + itr.iter = NULL; - icalerror_check_arg_re( (component!=0),"component",icalcompiter_null); + icalerror_check_arg_re(component!=0,"component",icalcompiter_null); - for( i = pvl_head(impl->components); i != 0; i = pvl_next(itr.iter)) { + for( i = pvl_head(component->components); i != 0; i = pvl_next(i)) { icalcomponent *c = (icalcomponent*) pvl_data(i); if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) { itr.iter = i; return itr; } } return icalcompiter_null; } icalcompiter icalcomponent_end_component(icalcomponent* component,icalcomponent_kind kind) { - struct icalcomponent_impl *impl = (struct icalcomponent_impl*)component; icalcompiter itr; pvl_elem i; itr.kind = kind; - icalerror_check_arg_re( (component!=0),"component",icalcompiter_null); + icalerror_check_arg_re(component!=0,"component",icalcompiter_null); - for( i = pvl_tail(impl->components); i != 0; i = pvl_prior(i)) { + for( i = pvl_tail(component->components); i != 0; i = pvl_prior(i)) { icalcomponent *c = (icalcomponent*) pvl_data(i); if (icalcomponent_isa(c) == kind || kind == ICAL_ANY_COMPONENT) { itr.iter = pvl_next(i); return itr; } } return icalcompiter_null;; } icalcomponent* icalcompiter_next(icalcompiter* i) { if (i->iter == 0){ return 0; } icalerror_check_arg_rz( (i!=0),"i"); for( i->iter = pvl_next(i->iter); i->iter != 0; i->iter = pvl_next(i->iter)) { icalcomponent *c = (icalcomponent*) pvl_data(i->iter); if (icalcomponent_isa(c) == i->kind || i->kind == ICAL_ANY_COMPONENT) { return icalcompiter_deref(i);; } } return 0; } icalcomponent* icalcompiter_prior(icalcompiter* i) { if (i->iter == 0){ return 0; } for( i->iter = pvl_prior(i->iter); i->iter != 0; i->iter = pvl_prior(i->iter)) { icalcomponent *c = (icalcomponent*) pvl_data(i->iter); if (icalcomponent_isa(c) == i->kind || i->kind == ICAL_ANY_COMPONENT) { return icalcompiter_deref(i);; } } return 0; } icalcomponent* icalcompiter_deref(icalcompiter* i) { if(i->iter ==0){ return 0; } return pvl_data(i->iter); } icalcomponent* icalcomponent_get_inner(icalcomponent* comp) { if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){ return icalcomponent_get_first_real_component(comp); } else { return comp; } } +/** @brief sets the METHOD property to the given method + */ -void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v) +void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method) { + icalproperty *prop + = icalcomponent_get_first_property(comp, ICAL_METHOD_PROPERTY); - icalcomponent *inner = icalcomponent_get_inner(comp); + + if (prop == 0){ + prop = icalproperty_new_method(method); + icalcomponent_add_property(comp, prop); + } + + icalproperty_set_method(prop,method); + +} + +/** @brief returns the METHOD property + */ + +icalproperty_method icalcomponent_get_method(icalcomponent* comp) +{ icalproperty *prop - = icalcomponent_get_first_property(inner, ICAL_DTSTART_PROPERTY); + = icalcomponent_get_first_property(comp,ICAL_METHOD_PROPERTY); + if (prop == 0){ + return ICAL_METHOD_NONE; + } + + return icalproperty_get_method(prop); +} + +#define ICALSETUPSET(p_kind) \ + icalcomponent *inner; \ + icalproperty *prop; \ + icalerror_check_arg_rv(comp!=0,"comp");\ + inner = icalcomponent_get_inner(comp); \ + if(inner == 0){\ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);\ + return;\ + }\ + prop = icalcomponent_get_first_property(inner, p_kind); + + +/** @brief Set DTSTART property to given icaltime + * + * This method respects the icaltime type (DATE vs DATE-TIME) and + * timezone (or lack thereof). + */ +void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v) +{ + char *tzid; + ICALSETUPSET(ICAL_DTSTART_PROPERTY); if (prop == 0){ prop = icalproperty_new_dtstart(v); icalcomponent_add_property(inner, prop); + } else { + icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER); } icalproperty_set_dtstart(prop,v); + if ((tzid = icaltime_get_tzid(v)) != NULL && !icaltime_is_utc(v)) { + icalproperty_add_parameter(prop, icalparameter_new_tzid(tzid)); + } } +/** @brief Get a DATE or DATE-TIME property as an icaltime + * + * If the property is a DATE-TIME with a timezone parameter and a + * corresponding VTIMEZONE is present in the component, the + * returned component will already be in the correct timezone; + * otherwise the caller is responsible for converting it. + * + * FIXME this is useless until we can flag the failure + */ +static struct icaltimetype +icalcomponent_get_datetime(icalcomponent *comp, icalproperty *prop) { + + icalparameter *param; + struct icaltimetype ret; + + ret = icalvalue_get_datetime(icalproperty_get_value(prop)); + + if ((param = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER)) + != NULL) { + const char *tzid = icalparameter_get_tzid(param); + icaltimezone *tz; + + if ((tz = icalcomponent_get_timezone(comp, tzid)) != NULL) { + icaltime_set_timezone(&ret, tz); + } + } + + return ret; +} +/** @brief Get DTSTART property as an icaltime + * + * If DTSTART is a DATE-TIME with a timezone parameter and a + * corresponding VTIMEZONE is present in the component, the + * returned component will already be in the correct timezone; + * otherwise the caller is responsible for converting it. + * + * FIXME this is useless until we can flag the failure + */ struct icaltimetype icalcomponent_get_dtstart(icalcomponent* comp) { icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *prop - = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); + icalproperty *prop; + prop = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); if (prop == 0){ return icaltime_null_time(); } - - return icalproperty_get_dtstart(prop); -} + return icalcomponent_get_datetime(comp, prop); +} +/** @brief Get DTEND property as an icaltime + * + * If a DTEND property is not present but a DURATION is, we use + * that to determine the proper end. + * + * If DTSTART is a DATE-TIME with a timezone parameter and a + * corresponding VTIMEZONE is present in the component, the + * returned component will already be in the correct timezone; + * otherwise the caller is responsible for converting it. + * + * FIXME this is useless until we can flag the failure + */ struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp) { icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *end_prop = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); - icalproperty *dur_prop = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); + struct icaltimetype ret = icaltime_null_time(); - - if( end_prop == 0 && dur_prop == 0){ - return icaltime_null_time(); - } else if ( end_prop != 0) { - return icalproperty_get_dtend(end_prop); + if ( end_prop != 0) { + ret = icalcomponent_get_datetime(comp, end_prop); } else if ( dur_prop != 0) { - + struct icaltimetype start = icalcomponent_get_dtstart(inner); struct icaldurationtype duration = icalproperty_get_duration(dur_prop); - - struct icaltimetype end = icaltime_add(start,duration); - return end; - - } else { - /* Error, both duration and dtend have been specified */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return icaltime_null_time(); + struct icaltimetype end = icaltime_add(start,duration); + ret = end; } - -} + return ret; +} +/** @brief Set DTEND property to given icaltime + * + * This method respects the icaltime type (DATE vs DATE-TIME) and + * timezone (or lack thereof). + * + * This also checks that a DURATION property isn't already there, + * and returns an error if it is. It's the caller's responsibility + * to remove it. + */ void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v) { - icalcomponent *inner = icalcomponent_get_inner(comp); - - icalproperty *end_prop - = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); - - icalproperty *dur_prop - = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); - + char *tzid; + ICALSETUPSET(ICAL_DTEND_PROPERTY); - if( end_prop == 0 && dur_prop == 0){ - end_prop = icalproperty_new_dtend(v); - icalcomponent_add_property(inner,end_prop); - } else if ( end_prop != 0) { - icalproperty_set_dtend(end_prop,v); - } else if ( dur_prop != 0) { - struct icaltimetype start = - icalcomponent_get_dtstart(inner); - - struct icaltimetype end = - icalcomponent_get_dtend(inner); + if (icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY) + != NULL) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return; + } - struct icaldurationtype dur - = icaltime_subtract(end,start); + if (prop == 0) { + prop = icalproperty_new_dtend(v); + icalcomponent_add_property(inner, prop); + } else { + icalproperty_remove_parameter_by_kind(prop, ICAL_TZID_PARAMETER); + } - icalproperty_set_duration(dur_prop,dur); + icalproperty_set_dtend(prop,v); - } else { - /* Error, both duration and dtend have been specified */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + if ((tzid = icaltime_get_tzid(v)) != NULL && !icaltime_is_utc(v)) { + icalproperty_add_parameter(prop, icalparameter_new_tzid(tzid)); } } +/** @brief Set DURATION property to given icalduration + * + * This method respects the icaltime type (DATE vs DATE-TIME) and + * timezone (or lack thereof). + * + * This also checks that a DTEND property isn't already there, + * and returns an error if it is. It's the caller's responsibility + * to remove it. + */ void icalcomponent_set_duration(icalcomponent* comp, struct icaldurationtype v) { - icalcomponent *inner = icalcomponent_get_inner(comp); - - icalproperty *end_prop - = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); - - icalproperty *dur_prop - = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); - - - if( end_prop == 0 && dur_prop == 0){ - dur_prop = icalproperty_new_duration(v); - icalcomponent_add_property(inner, dur_prop); - } else if ( end_prop != 0) { - struct icaltimetype start = - icalcomponent_get_dtstart(inner); - - struct icaltimetype new_end = icaltime_add(start,v); + ICALSETUPSET(ICAL_DURATION_PROPERTY); - icalproperty_set_dtend(end_prop,new_end); + if (icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY) != NULL) { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return; + } - } else if ( dur_prop != 0) { - icalproperty_set_duration(dur_prop,v); + if (prop == 0) { + prop = icalproperty_new_duration(v); + icalcomponent_add_property(inner, prop); } else { - /* Error, both duration and dtend have been specified */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + icalproperty_set_duration(prop,v); } } +/** @brief Get DURATION property as an icalduration + * + * If a DURATION property is not present but a DTEND is, we use + * that to determine the proper end. + */ struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp) { icalcomponent *inner = icalcomponent_get_inner(comp); icalproperty *end_prop = icalcomponent_get_first_property(inner,ICAL_DTEND_PROPERTY); icalproperty *dur_prop = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); - struct icaldurationtype null_duration; - memset(&null_duration,0,sizeof(struct icaldurationtype)); + struct icaldurationtype ret = icaldurationtype_null_duration(); + if ( dur_prop != 0 && end_prop == 0) { + ret = icalproperty_get_duration(dur_prop); - if( end_prop == 0 && dur_prop == 0){ - return null_duration; - } else if ( end_prop != 0) { + } else if ( end_prop != 0 && dur_prop == 0) { + /** + * FIXME + * We assume DTSTART and DTEND are not in different time zones. + * Does the standard actually guarantee this? + */ struct icaltimetype start = icalcomponent_get_dtstart(inner); - time_t startt = icaltime_as_timet(start); - struct icaltimetype end = icalcomponent_get_dtend(inner); - time_t endt = icaltime_as_timet(end); - - return icaldurationtype_from_int(endt-startt); - } else if ( dur_prop != 0) { - return icalproperty_get_duration(dur_prop); + + ret = icaltime_subtract(end, start); } else { /* Error, both duration and dtend have been specified */ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return null_duration; } + return ret; } -void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method) +void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v) { - icalproperty *prop - = icalcomponent_get_first_property(comp, ICAL_METHOD_PROPERTY); + ICALSETUPSET(ICAL_DTSTAMP_PROPERTY); if (prop == 0){ - prop = icalproperty_new_method(method); - icalcomponent_add_property(comp, prop); + prop = icalproperty_new_dtstamp(v); + icalcomponent_add_property(inner, prop); } - icalproperty_set_method(prop,method); + icalproperty_set_dtstamp(prop,v); } -icalproperty_method icalcomponent_get_method(icalcomponent* comp) + +struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp) { + icalcomponent *inner = icalcomponent_get_inner(comp); icalproperty *prop - = icalcomponent_get_first_property(comp,ICAL_METHOD_PROPERTY); + = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); if (prop == 0){ - return ICAL_METHOD_NONE; + return icaltime_null_time(); } - return icalproperty_get_method(prop); + return icalproperty_get_dtstamp(prop); } -void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v) + +void icalcomponent_set_summary(icalcomponent* comp, const char* v) +{ + ICALSETUPSET(ICAL_SUMMARY_PROPERTY) + + if (prop == 0){ + prop = icalproperty_new_summary(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_summary(prop,v); +} + + +const char* icalcomponent_get_summary(icalcomponent* comp) { + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); - icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *prop - = icalcomponent_get_first_property(inner, ICAL_DTSTAMP_PROPERTY); + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + prop= icalcomponent_get_first_property(inner,ICAL_SUMMARY_PROPERTY); if (prop == 0){ - prop = icalproperty_new_dtstamp(v); - icalcomponent_add_property(inner, prop); + return 0; } - icalproperty_set_dtstamp(prop,v); + return icalproperty_get_summary(prop); } - -struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp) +void icalcomponent_set_comment(icalcomponent* comp, const char* v) { - icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *prop - = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); + ICALSETUPSET(ICAL_COMMENT_PROPERTY); if (prop == 0){ - return icaltime_null_time(); + prop = icalproperty_new_comment(v); + icalcomponent_add_property(inner, prop); } - - return icalproperty_get_dtstamp(prop); + + icalproperty_set_summary(prop,v); + } +const char* icalcomponent_get_comment(icalcomponent* comp){ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + inner = icalcomponent_get_inner(comp); -void icalcomponent_set_summary(icalcomponent* comp, const char* v) + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_COMMENT_PROPERTY); + + if (prop == 0){ + return 0; + } + + return icalproperty_get_comment(prop); +} + +void icalcomponent_set_uid(icalcomponent* comp, const char* v) { - icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *prop - = icalcomponent_get_first_property(inner, ICAL_SUMMARY_PROPERTY); + ICALSETUPSET(ICAL_UID_PROPERTY); if (prop == 0){ - prop = icalproperty_new_summary(v); + prop = icalproperty_new_uid(v); icalcomponent_add_property(inner, prop); } - + icalproperty_set_summary(prop,v); + } +const char* icalcomponent_get_uid(icalcomponent* comp){ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + inner = icalcomponent_get_inner(comp); -const char* icalcomponent_get_summary(icalcomponent* comp) -{ - icalcomponent *inner = icalcomponent_get_inner(comp); - icalproperty *prop - = icalcomponent_get_first_property(inner,ICAL_SUMMARY_PROPERTY); + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); if (prop == 0){ return 0; } - return icalproperty_get_summary(prop); + return icalproperty_get_uid(prop); +} +void icalcomponent_set_recurrenceid(icalcomponent* comp, struct icaltimetype v) +{ + ICALSETUPSET(ICAL_RECURRENCEID_PROPERTY); + + if (prop == 0){ + prop = icalproperty_new_recurrenceid(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_recurrenceid(prop,v); } +struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp) +{ + icalcomponent *inner; + icalproperty *prop; + if (comp == 0) { + icalerror_set_errno(ICAL_BADARG_ERROR); + return icaltime_null_time(); + } -void icalcomponent_set_comment(icalcomponent* comp, const char* v); -const char* icalcomponent_get_comment(icalcomponent* comp); + inner = icalcomponent_get_inner(comp); -void icalcomponent_set_uid(icalcomponent* comp, const char* v); -const char* icalcomponent_get_uid(icalcomponent* comp); + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return icaltime_null_time(); + } -void icalcomponent_set_recurrenceid(icalcomponent* comp, - struct icaltimetype v); -struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp); + prop= icalcomponent_get_first_property(inner, ICAL_RECURRENCEID_PROPERTY); + if (prop == 0){ + return icaltime_null_time(); + } + + return icalproperty_get_recurrenceid(prop); +} + +void icalcomponent_set_description(icalcomponent* comp, const char* v) +{ + ICALSETUPSET(ICAL_DESCRIPTION_PROPERTY); + + if (prop == 0){ + prop = icalproperty_new_description(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_description(prop,v); +} +const char* icalcomponent_get_description(icalcomponent* comp) +{ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_DESCRIPTION_PROPERTY); + + if (prop == 0){ + return 0; + } + + return icalproperty_get_description(prop); +} + +void icalcomponent_set_location(icalcomponent* comp, const char* v) +{ + ICALSETUPSET(ICAL_LOCATION_PROPERTY) + + if (prop == 0){ + prop = icalproperty_new_location(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_location(prop,v); +} +const char* icalcomponent_get_location(icalcomponent* comp) +{ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_LOCATION_PROPERTY); + if (prop == 0){ + return 0; + } + + return icalproperty_get_location(prop); +} + +void icalcomponent_set_sequence(icalcomponent* comp, int v) +{ + ICALSETUPSET(ICAL_SEQUENCE_PROPERTY); + + if (prop == 0){ + prop = icalproperty_new_sequence(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_sequence(prop,v); + +} +int icalcomponent_get_sequence(icalcomponent* comp){ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_SEQUENCE_PROPERTY); + + if (prop == 0){ + return 0; + } + + return icalproperty_get_sequence(prop); +} + + +void icalcomponent_set_status(icalcomponent* comp, enum icalproperty_status v) +{ + ICALSETUPSET(ICAL_STATUS_PROPERTY); + + if (prop == 0){ + prop = icalproperty_new_status(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_status(prop,v); + +} +enum icalproperty_status icalcomponent_get_status(icalcomponent* comp){ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + prop= icalcomponent_get_first_property(inner,ICAL_STATUS_PROPERTY); + + if (prop == 0){ + return 0; + } + + return icalproperty_get_status(prop); +} icalcomponent* icalcomponent_new_vcalendar() { return icalcomponent_new(ICAL_VCALENDAR_COMPONENT); } icalcomponent* icalcomponent_new_vevent() { return icalcomponent_new(ICAL_VEVENT_COMPONENT); } icalcomponent* icalcomponent_new_vtodo() { return icalcomponent_new(ICAL_VTODO_COMPONENT); } icalcomponent* icalcomponent_new_vjournal() { return icalcomponent_new(ICAL_VJOURNAL_COMPONENT); } icalcomponent* icalcomponent_new_valarm() { return icalcomponent_new(ICAL_VALARM_COMPONENT); } icalcomponent* icalcomponent_new_vfreebusy() { return icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); } icalcomponent* icalcomponent_new_vtimezone() { return icalcomponent_new(ICAL_VTIMEZONE_COMPONENT); } icalcomponent* icalcomponent_new_xstandard() { return icalcomponent_new(ICAL_XSTANDARD_COMPONENT); } icalcomponent* icalcomponent_new_xdaylight() { return icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT); } +icalcomponent* icalcomponent_new_vagenda() +{ + return icalcomponent_new(ICAL_VAGENDA_COMPONENT); +} +icalcomponent* icalcomponent_new_vquery() +{ + return icalcomponent_new(ICAL_VQUERY_COMPONENT); +} + +/* + * Timezone stuff. + */ + + +/** + * This takes 2 VCALENDAR components and merges the second one into the first, + * resolving any problems with conflicting TZIDs. comp_to_merge will no + * longer exist after calling this function. + */ +void icalcomponent_merge_component(icalcomponent* comp, + icalcomponent* comp_to_merge) +{ + icalcomponent *subcomp, *next_subcomp; + icalarray *tzids_to_rename; + int i; + + /* Check that both components are VCALENDAR components. */ + assert (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT); + assert (icalcomponent_isa(comp_to_merge) == ICAL_VCALENDAR_COMPONENT); + + /* Step through each subcomponent of comp_to_merge, looking for VTIMEZONEs. + For each VTIMEZONE found, check if we need to add it to comp and if we + need to rename it and all TZID references to it. */ + tzids_to_rename = icalarray_new (sizeof (char*), 16); + subcomp = icalcomponent_get_first_component (comp_to_merge, + ICAL_VTIMEZONE_COMPONENT); + while (subcomp) { + next_subcomp = icalcomponent_get_next_component (comp_to_merge, + ICAL_VTIMEZONE_COMPONENT); + /* This will add the VTIMEZONE to comp, if necessary, and also update + the array of TZIDs we need to rename. */ + icalcomponent_merge_vtimezone (comp, subcomp, tzids_to_rename); + /* FIXME: Handle possible NEWFAILED error. */ + + subcomp = next_subcomp; + } + + /* If we need to do any renaming of TZIDs, do it now. */ + if (tzids_to_rename->num_elements != 0) { + icalcomponent_rename_tzids (comp_to_merge, tzids_to_rename); + + /* Now free the tzids_to_rename array. */ + for (i = 0; i < tzids_to_rename->num_elements; i++) { + free (icalarray_element_at (tzids_to_rename, i)); + } + icalarray_free (tzids_to_rename); + } + + /* Now move all the components from comp_to_merge to comp, excluding + VTIMEZONE components. */ + subcomp = icalcomponent_get_first_component (comp_to_merge, + ICAL_ANY_COMPONENT); + while (subcomp) { + next_subcomp = icalcomponent_get_next_component (comp_to_merge, + ICAL_ANY_COMPONENT); + if (icalcomponent_isa(subcomp) != ICAL_VTIMEZONE_COMPONENT) { + icalcomponent_remove_component (comp_to_merge, subcomp); + icalcomponent_add_component (comp, subcomp); + } + subcomp = next_subcomp; + } + + /* Free comp_to_merge. We have moved most of the subcomponents over to + comp now. */ + icalcomponent_free (comp_to_merge); +} + + +static void icalcomponent_merge_vtimezone (icalcomponent *comp, + icalcomponent *vtimezone, + icalarray *tzids_to_rename) +{ + icalproperty *tzid_prop; + const char *tzid; + char *tzid_copy; + icaltimezone *existing_vtimezone; + + /* Get the TZID of the VTIMEZONE. */ + tzid_prop = icalcomponent_get_first_property (vtimezone, ICAL_TZID_PROPERTY); + if (!tzid_prop) + return; + + tzid = icalproperty_get_tzid (tzid_prop); + if (!tzid) + return; + + /* See if there is already a VTIMEZONE in comp with the same TZID. */ + existing_vtimezone = icalcomponent_get_timezone (comp, tzid); + + /* If there is no existing VTIMEZONE with the same TZID, we can just move + the VTIMEZONE to comp and return. */ + if (!existing_vtimezone) { + icalcomponent_remove_component (icalcomponent_get_parent (vtimezone), + vtimezone); + icalcomponent_add_component (comp, vtimezone); + return; + } + + /* If the TZID has a '/' prefix, then we don't have to worry about the + clashing TZIDs, as they are supposed to be exactly the same VTIMEZONE. */ + if (tzid[0] == '/') + return; + + /* Now we have two VTIMEZONEs with the same TZID (which isn't a globally + unique one), so we compare the VTIMEZONE components to see if they are + the same. If they are, we don't need to do anything. We make a copy of + the tzid, since the parameter may get modified in these calls. */ + tzid_copy = strdup (tzid); + if (!tzid_copy) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + if (!icalcomponent_compare_vtimezones (comp, vtimezone)) { + /* FIXME: Handle possible NEWFAILED error. */ + + /* Now we have two different VTIMEZONEs with the same TZID. */ + icalcomponent_handle_conflicting_vtimezones (comp, vtimezone, tzid_prop, + tzid_copy, tzids_to_rename); + } + free (tzid_copy); +} + + +static void +icalcomponent_handle_conflicting_vtimezones (icalcomponent *comp, + icalcomponent *vtimezone, + icalproperty *tzid_prop, + const char *tzid, + icalarray *tzids_to_rename) +{ + int i, suffix, max_suffix = 0, num_elements; + unsigned int tzid_len; + char *tzid_copy, *new_tzid, suffix_buf[32]; + + /* Find the length of the TZID without any trailing digits. */ + tzid_len = icalcomponent_get_tzid_prefix_len (tzid); + + /* Step through each of the VTIMEZONEs in comp. We may already have the + clashing VTIMEZONE in the calendar, but it may have been renamed + (i.e. a unique number added on the end of the TZID, e.g. 'London2'). + So we compare the new VTIMEZONE with any VTIMEZONEs that have the + same prefix (e.g. 'London'). If it matches any of those, we have to + rename the TZIDs to that TZID, else we rename to a new TZID, using + the biggest numeric suffix found + 1. */ + num_elements = comp->timezones ? comp->timezones->num_elements : 0; + for (i = 0; i < num_elements; i++) { + icaltimezone *zone; + char *existing_tzid, *existing_tzid_copy; + unsigned int existing_tzid_len; + + zone = icalarray_element_at (comp->timezones, i); + existing_tzid = icaltimezone_get_tzid (zone); + + /* Find the length of the TZID without any trailing digits. */ + existing_tzid_len = icalcomponent_get_tzid_prefix_len (existing_tzid); + + /* Check if we have the same prefix. */ + if (tzid_len == existing_tzid_len + && !strncmp (tzid, existing_tzid, tzid_len)) { + /* Compare the VTIMEZONEs. */ + if (icalcomponent_compare_vtimezones (icaltimezone_get_component (zone), + vtimezone)) { + /* The VTIMEZONEs match, so we can use the existing VTIMEZONE. But + we have to rename TZIDs to this TZID. */ + tzid_copy = strdup (tzid); + existing_tzid_copy = strdup (existing_tzid); + if (!tzid_copy || !existing_tzid_copy) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + } else { + icalarray_append (tzids_to_rename, tzid_copy); + icalarray_append (tzids_to_rename, existing_tzid_copy); + } + return; + } else { + /* FIXME: Handle possible NEWFAILED error. */ + + /* Convert the suffix to an integer and remember the maximum numeric + suffix found. */ + suffix = atoi (existing_tzid + existing_tzid_len); + if (max_suffix < suffix) + max_suffix = suffix; + } + } + } + + /* We didn't find a VTIMEZONE that matched, so we have to rename the TZID, + using the maximum numerical suffix found + 1. */ + tzid_copy = strdup (tzid); + sprintf (suffix_buf, "%i", max_suffix + 1); + new_tzid = malloc (tzid_len + strlen (suffix_buf) + 1); + if (!new_tzid || !tzid_copy) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + strncpy (new_tzid, tzid, tzid_len); + strcpy (new_tzid + tzid_len, suffix_buf); + icalarray_append (tzids_to_rename, tzid_copy); + icalarray_append (tzids_to_rename, new_tzid); +} + + +/* Returns the length of the TZID, without any trailing digits. */ +static unsigned int icalcomponent_get_tzid_prefix_len (const char *tzid) +{ + int len; + const char *p; + + len = strlen (tzid); + p = tzid + len - 1; + while (len > 0 && *p >= '0' && *p <= '9') { + p--; + len--; + } + + return len; +} + + +/** + * Renames all references to the given TZIDs to a new name. rename_table + * contains pairs of strings - a current TZID, and the new TZID to rename it + * to. + */ +static void icalcomponent_rename_tzids(icalcomponent* comp, + icalarray* rename_table) +{ + icalcomponent_foreach_tzid (comp, icalcomponent_rename_tzids_callback, + rename_table); +} + + +static void icalcomponent_rename_tzids_callback(icalparameter *param, void *data) +{ + icalarray *rename_table = data; + const char *tzid; + int i; + + tzid = icalparameter_get_tzid (param); + if (!tzid) + return; + + /* Step through the rename table to see if the current TZID matches + any of the ones we want to rename. */ + for (i = 0; i < rename_table->num_elements - 1; i += 2) { + if (!strcmp (tzid, icalarray_element_at (rename_table, i))) { + icalparameter_set_tzid (param, icalarray_element_at (rename_table, i + 1)); + break; + } + } +} + + +/** + * Calls the given function for each TZID parameter found in the component. + */ +void icalcomponent_foreach_tzid(icalcomponent* comp, + void (*callback)(icalparameter *param, void *data), + void *callback_data) +{ + icalproperty *prop; + icalproperty_kind kind; + icalparameter *param; + icalcomponent *subcomp; + + /* First look for any TZID parameters used in this component itself. */ + prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY); + while (prop) { + kind = icalproperty_isa (prop); + + /* These are the only properties that can have a TZID. Note that + COMPLETED, CREATED, DTSTAMP & LASTMODIFIED must be in UTC. */ + if (kind == ICAL_DTSTART_PROPERTY || kind == ICAL_DTEND_PROPERTY + || kind == ICAL_DUE_PROPERTY || kind == ICAL_EXDATE_PROPERTY + || kind == ICAL_RDATE_PROPERTY) { + param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); + if (param) + (*callback) (param, callback_data); + } + + prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY); + } + + /* Now recursively check child components. */ + subcomp = icalcomponent_get_first_component (comp, ICAL_ANY_COMPONENT); + while (subcomp) { + icalcomponent_foreach_tzid (subcomp, callback, callback_data); + subcomp = icalcomponent_get_next_component (comp, ICAL_ANY_COMPONENT); + } +} + + + +/** + * Returns the icaltimezone from the component corresponding to the given + * TZID, or NULL if the component does not have a corresponding VTIMEZONE. + */ +icaltimezone* icalcomponent_get_timezone(icalcomponent* comp, const char *tzid) +{ + icaltimezone *zone; + int lower, upper, middle, cmp; + char *zone_tzid; + + if (!comp->timezones) + return NULL; + + /* Sort the array if necessary (by the TZID string). */ + if (!comp->timezones_sorted) { + icalarray_sort (comp->timezones, icalcomponent_compare_timezone_fn); + comp->timezones_sorted = 1; + } + + /* Do a simple binary search. */ + lower = middle = 0; + upper = comp->timezones->num_elements; + + while (lower < upper) { + middle = (lower + upper) >> 1; + zone = icalarray_element_at (comp->timezones, middle); + zone_tzid = icaltimezone_get_tzid (zone); + cmp = strcmp (tzid, zone_tzid); + if (cmp == 0) + return zone; + else if (cmp < 0) + upper = middle; + else + lower = middle + 1; + } + + return NULL; +} + + +/** + * A function to compare 2 icaltimezone elements, used for qsort(). + */ +static int icalcomponent_compare_timezone_fn (const void *elem1, + const void *elem2) +{ + icaltimezone *zone1, *zone2; + const char *zone1_tzid, *zone2_tzid; + + zone1 = (icaltimezone*) elem1; + zone2 = (icaltimezone*) elem2; + + zone1_tzid = icaltimezone_get_tzid (zone1); + zone2_tzid = icaltimezone_get_tzid (zone2); + + return strcmp (zone1_tzid, zone2_tzid); +} + + +/** + * Compares 2 VTIMEZONE components to see if they match, ignoring their TZIDs. + * It returns 1 if they match, 0 if they don't, or -1 on error. + */ +static int icalcomponent_compare_vtimezones (icalcomponent *vtimezone1, + icalcomponent *vtimezone2) +{ + icalproperty *prop1, *prop2; + const char *tzid1, *tzid2; + char *tzid2_copy, *string1, *string2; + int cmp; + + /* Get the TZID property of the first VTIMEZONE. */ + prop1 = icalcomponent_get_first_property (vtimezone1, ICAL_TZID_PROPERTY); + if (!prop1) + return -1; + + tzid1 = icalproperty_get_tzid (prop1); + if (!tzid1) + return -1; + + /* Get the TZID property of the second VTIMEZONE. */ + prop2 = icalcomponent_get_first_property (vtimezone2, ICAL_TZID_PROPERTY); + if (!prop2) + return -1; + + tzid2 = icalproperty_get_tzid (prop2); + if (!tzid2) + return -1; + + /* Copy the second TZID, and set the property to the same as the first + TZID, since we don't care if these match of not. */ + tzid2_copy = strdup (tzid2); + if (!tzid2_copy) { + icalerror_set_errno (ICAL_NEWFAILED_ERROR); + return 0; + } + + icalproperty_set_tzid (prop2, tzid1); + + /* Now convert both VTIMEZONEs to strings and compare them. */ + string1 = icalcomponent_as_ical_string (vtimezone1); + if (!string1) { + free (tzid2_copy); + return -1; + } + + string2 = icalcomponent_as_ical_string (vtimezone2); + if (!string2) { + free (string1); + free (tzid2_copy); + return -1; + } + + cmp = strcmp (string1, string2); + + free (string1); + free (string2); + + /* Now reset the second TZID. */ + icalproperty_set_tzid (prop2, tzid2_copy); + free (tzid2_copy); + + return (cmp == 0) ? 1 : 0; +} + + + + + + +/** + * @brief set the RELCALID property of a component. + * + * @param comp Valid calendar component. + * @param v Relcalid URL value + */ + +void icalcomponent_set_relcalid(icalcomponent* comp, const char* v) +{ + ICALSETUPSET(ICAL_RELCALID_PROPERTY); + + if (prop == 0){ + prop = icalproperty_new_relcalid(v); + icalcomponent_add_property(inner, prop); + } + + icalproperty_set_relcalid(prop,v); + +} + + +/** + * @brief get the RELCALID property of a component. + * + * @param comp Valid calendar component. + */ + +const char* icalcomponent_get_relcalid(icalcomponent* comp){ + icalcomponent *inner; + icalproperty *prop; + icalerror_check_arg_rz(comp!=0,"comp"); + + inner = icalcomponent_get_inner(comp); + + if(inner == 0){ + return 0; + } + + prop= icalcomponent_get_first_property(inner,ICAL_RELCALID_PROPERTY); + + if (prop == 0){ + return 0; + } + + return icalproperty_get_relcalid(prop); +} + + +/** @brief Return the time a TODO task is DUE. + * + * @param comp Valid calendar component. + * + * Uses the DUE: property if it exists, otherwise we calculate the DUE + * value by adding the task's duration to the DTSTART time + */ + +struct icaltimetype icalcomponent_get_due(icalcomponent* comp) +{ + icalcomponent *inner = icalcomponent_get_inner(comp); + + icalproperty *due_prop + = icalcomponent_get_first_property(inner,ICAL_DUE_PROPERTY); + + icalproperty *dur_prop + = icalcomponent_get_first_property(inner, ICAL_DURATION_PROPERTY); + + if( due_prop == 0 && dur_prop == 0){ + return icaltime_null_time(); + } else if ( due_prop != 0) { + return icalproperty_get_due(due_prop); + } else if ( dur_prop != 0) { + + struct icaltimetype start = + icalcomponent_get_dtstart(inner); + struct icaldurationtype duration = + icalproperty_get_duration(dur_prop); + + struct icaltimetype due = icaltime_add(start,duration); + + return due; + + } else { + /* Error, both duration and due have been specified */ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return icaltime_null_time(); + + } + +} + +/** @brief Set the due date of a VTODO task. + * + * @param comp Valid VTODO component. + * @param v Valid due date time. + * + * - If no duration or due properties then set the DUE property. + * - If a DUE property is already set, then reset it to the value v. + * - If a DURATION property is already set, then calculate the new + * duration based on the supplied value of v. + */ + +void icalcomponent_set_due(icalcomponent* comp, struct icaltimetype v) +{ + icalcomponent *inner = icalcomponent_get_inner(comp); + + icalproperty *due_prop + = icalcomponent_get_first_property(inner,ICAL_DUE_PROPERTY); + + icalproperty *dur_prop + = icalcomponent_get_first_property(inner,ICAL_DURATION_PROPERTY); + + + if( due_prop == 0 && dur_prop == 0){ + due_prop = icalproperty_new_due(v); + icalcomponent_add_property(inner,due_prop); + } else if ( due_prop != 0) { + icalproperty_set_due(due_prop,v); + } else if ( dur_prop != 0) { + struct icaltimetype start = + icalcomponent_get_dtstart(inner); + + struct icaltimetype due = + icalcomponent_get_due(inner); + + struct icaldurationtype dur + = icaltime_subtract(due,start); + + icalproperty_set_duration(dur_prop,dur); + + } else { + /* Error, both duration and due have been specified */ + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + } +} diff --git a/libical/src/libical/icalcomponent.h b/libical/src/libical/icalcomponent.h index 6046bbe..be9bf8c 100644 --- a/libical/src/libical/icalcomponent.h +++ b/libical/src/libical/icalcomponent.h @@ -1,240 +1,282 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalcomponent.h CREATOR: eric 20 March 1999 (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 icalcomponent.h ======================================================================*/ #ifndef ICALCOMPONENT_H #define ICALCOMPONENT_H #include "icalproperty.h" #include "icalvalue.h" #include "icalenums.h" /* defines icalcomponent_kind */ -#include "icalattendee.h" #include "pvl.h" -typedef void icalcomponent; +typedef struct icalcomponent_impl icalcomponent; + +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +/** @brief An opaque struct representing a timezone. + * We declare this here to avoid a circular dependancy. + */ +typedef struct _icaltimezone icaltimezone; +#endif + /* This is exposed so that callers will not have to allocate and deallocate iterators. Pretend that you can't see it. */ typedef struct icalcompiter { icalcomponent_kind kind; pvl_elem iter; } icalcompiter; icalcomponent* icalcomponent_new(icalcomponent_kind kind); icalcomponent* icalcomponent_new_clone(icalcomponent* component); icalcomponent* icalcomponent_new_from_string(char* str); icalcomponent* icalcomponent_vanew(icalcomponent_kind kind, ...); void icalcomponent_free(icalcomponent* component); char* icalcomponent_as_ical_string(icalcomponent* component); int icalcomponent_is_valid(icalcomponent* component); -icalcomponent_kind icalcomponent_isa(icalcomponent* component); +icalcomponent_kind icalcomponent_isa(const icalcomponent* component); int icalcomponent_isa_component (void* component); /* * Working with properties */ void icalcomponent_add_property(icalcomponent* component, icalproperty* property); void icalcomponent_remove_property(icalcomponent* component, icalproperty* property); int icalcomponent_count_properties(icalcomponent* component, icalproperty_kind kind); /* Iterate through the properties */ icalproperty* icalcomponent_get_current_property(icalcomponent* component); icalproperty* icalcomponent_get_first_property(icalcomponent* component, icalproperty_kind kind); icalproperty* icalcomponent_get_next_property(icalcomponent* component, icalproperty_kind kind); /* * Working with components */ /* Return the first VEVENT, VTODO or VJOURNAL sub-component of cop, or comp if it is one of those types */ icalcomponent* icalcomponent_get_inner(icalcomponent* comp); void icalcomponent_add_component(icalcomponent* parent, icalcomponent* child); void icalcomponent_remove_component(icalcomponent* parent, icalcomponent* child); int icalcomponent_count_components(icalcomponent* component, icalcomponent_kind kind); +/** + This takes 2 VCALENDAR components and merges the second one into the first, + resolving any problems with conflicting TZIDs. comp_to_merge will no + longer exist after calling this function. */ +void icalcomponent_merge_component(icalcomponent* comp, + icalcomponent* comp_to_merge); + + /* Iteration Routines. There are two forms of iterators, internal and external. The internal ones came first, and are almost completely sufficient, but they fail badly when you want to construct a loop that removes components from the container.*/ /* Iterate through components */ icalcomponent* icalcomponent_get_current_component (icalcomponent* component); icalcomponent* icalcomponent_get_first_component(icalcomponent* component, icalcomponent_kind kind); icalcomponent* icalcomponent_get_next_component(icalcomponent* component, icalcomponent_kind kind); /* Using external iterators */ icalcompiter icalcomponent_begin_component(icalcomponent* component, icalcomponent_kind kind); icalcompiter icalcomponent_end_component(icalcomponent* component, icalcomponent_kind kind); icalcomponent* icalcompiter_next(icalcompiter* i); icalcomponent* icalcompiter_prior(icalcompiter* i); icalcomponent* icalcompiter_deref(icalcompiter* i); +/* Working with embedded error properties */ +/* Check the component against itip rules and insert error properties*/ /* Working with embedded error properties */ +int icalcomponent_check_restrictions(icalcomponent* comp); +/** Count embedded errors. */ int icalcomponent_count_errors(icalcomponent* component); -/* Remove all X-LIC-ERROR properties*/ +/** Remove all X-LIC-ERROR properties*/ void icalcomponent_strip_errors(icalcomponent* component); -/* Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ +/** Convert some X-LIC-ERROR properties into RETURN-STATUS properties*/ void icalcomponent_convert_errors(icalcomponent* component); /* Internal operations. They are private, and you should not be using them. */ icalcomponent* icalcomponent_get_parent(icalcomponent* component); void icalcomponent_set_parent(icalcomponent* component, icalcomponent* parent); -/* Kind conversion routiens */ +/* Kind conversion routines */ + +int icalcomponent_kind_is_valid(const icalcomponent_kind kind); icalcomponent_kind icalcomponent_string_to_kind(const char* string); const char* icalcomponent_kind_to_string(icalcomponent_kind kind); /************* Derived class methods. **************************** If the code was in an OO language, the remaining routines would be members of classes derived from icalcomponent. Don't call them on the wrong component subtypes. */ -/* For VCOMPONENT: Return a reference to the first VEVENT, VTODO or +/** For VCOMPONENT: Return a reference to the first VEVENT, VTODO or VJOURNAL */ icalcomponent* icalcomponent_get_first_real_component(icalcomponent *c); -/* For VEVENT, VTODO, VJOURNAL and VTIMEZONE: report the start and end +/** For VEVENT, VTODO, VJOURNAL and VTIMEZONE: report the start and end times of an event in UTC */ struct icaltime_span icalcomponent_get_span(icalcomponent* comp); /******************** Convienience routines **********************/ void icalcomponent_set_dtstart(icalcomponent* comp, struct icaltimetype v); struct icaltimetype icalcomponent_get_dtstart(icalcomponent* comp); /* For the icalcomponent routines only, dtend and duration are tied together. If you call the set routine for one and the other exists, the routine will calculate the change to the other. That is, if there is a DTEND and you call set_duration, the routine will modify DTEND to be the sum of DTSTART and the duration. If you call a get routine for one and the other exists, the routine will calculate the return value. If you call a set routine and neither exists, the routine will create the apcompriate comperty */ struct icaltimetype icalcomponent_get_dtend(icalcomponent* comp); void icalcomponent_set_dtend(icalcomponent* comp, struct icaltimetype v); +struct icaltimetype icalcomponent_get_due(icalcomponent* comp); +void icalcomponent_set_due(icalcomponent* comp, struct icaltimetype v); + void icalcomponent_set_duration(icalcomponent* comp, struct icaldurationtype v); struct icaldurationtype icalcomponent_get_duration(icalcomponent* comp); void icalcomponent_set_method(icalcomponent* comp, icalproperty_method method); icalproperty_method icalcomponent_get_method(icalcomponent* comp); struct icaltimetype icalcomponent_get_dtstamp(icalcomponent* comp); void icalcomponent_set_dtstamp(icalcomponent* comp, struct icaltimetype v); - void icalcomponent_set_summary(icalcomponent* comp, const char* v); const char* icalcomponent_get_summary(icalcomponent* comp); void icalcomponent_set_comment(icalcomponent* comp, const char* v); const char* icalcomponent_get_comment(icalcomponent* comp); void icalcomponent_set_uid(icalcomponent* comp, const char* v); const char* icalcomponent_get_uid(icalcomponent* comp); +void icalcomponent_set_relcalid(icalcomponent* comp, const char* v); +const char* icalcomponent_get_relcalid(icalcomponent* comp); + void icalcomponent_set_recurrenceid(icalcomponent* comp, struct icaltimetype v); struct icaltimetype icalcomponent_get_recurrenceid(icalcomponent* comp); +void icalcomponent_set_description(icalcomponent* comp, const char* v); +const char* icalcomponent_get_description(icalcomponent* comp); -void icalcomponent_set_organizer(icalcomponent* comp, - struct icalorganizertype org); - struct icalorganizertype icalcomponent_get_organizer(icalcomponent* comp); +void icalcomponent_set_location(icalcomponent* comp, const char* v); +const char* icalcomponent_get_location(icalcomponent* comp); +void icalcomponent_set_sequence(icalcomponent* comp, int v); +int icalcomponent_get_sequence(icalcomponent* comp); -void icalcomponent_add_attendee(icalcomponent *comp, - struct icalattendeetype attendee); +void icalcomponent_set_status(icalcomponent* comp, enum icalproperty_status v); +enum icalproperty_status icalcomponent_get_status(icalcomponent* comp); -int icalcomponent_remove_attendee(icalcomponent *comp, char* cuid); -/* Get the Nth attendee. Out of range indices return an attendee - with cuid == 0 */ -struct icalattendeetype icalcomponent_get_attendee(icalcomponent *comp, - int index); +/** Calls the given function for each TZID parameter found in the + component, and any subcomponents. */ +void icalcomponent_foreach_tzid(icalcomponent* comp, + void (*callback)(icalparameter *param, void *data), + void *callback_data); +/** Returns the icaltimezone in the component corresponding to the + TZID, or NULL if it can't be found. */ +icaltimezone* icalcomponent_get_timezone(icalcomponent* comp, + const char *tzid); +int icalproperty_recurrence_is_excluded(icalcomponent *comp, + struct icaltimetype *dtstart, + struct icaltimetype *recurtime); + +void icalcomponent_foreach_recurrence(icalcomponent* comp, + struct icaltimetype start, + struct icaltimetype end, + void (*callback)(icalcomponent *comp, + struct icaltime_span *span, + void *data), + void *callback_data); /*************** Type Specific routines ***************/ icalcomponent* icalcomponent_new_vcalendar(); icalcomponent* icalcomponent_new_vevent(); icalcomponent* icalcomponent_new_vtodo(); icalcomponent* icalcomponent_new_vjournal(); icalcomponent* icalcomponent_new_valarm(); icalcomponent* icalcomponent_new_vfreebusy(); icalcomponent* icalcomponent_new_vtimezone(); icalcomponent* icalcomponent_new_xstandard(); icalcomponent* icalcomponent_new_xdaylight(); - - +icalcomponent* icalcomponent_new_vagenda(); +icalcomponent* icalcomponent_new_vquery(); #endif /* !ICALCOMPONENT_H */ - - - diff --git a/libical/src/libical/icalderivedparameter.c b/libical/src/libical/icalderivedparameter.c index 6898eb6..91604f0 100644 --- a/libical/src/libical/icalderivedparameter.c +++ b/libical/src/libical/icalderivedparameter.c @@ -1,1205 +1,1202 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalderivedparameters.{c,h} CREATOR: eric 09 May 1999 $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 icalderivedparameters.{c,h} Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ /*#line 29 "icalparameter.c.in"*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalparameter.h" #include "icalparameterimpl.h" #include "icalproperty.h" #include "icalerror.h" #include "icalmemory.h" #include <stdlib.h> /* for malloc() */ #include <errno.h> #include <string.h> /* for memset() */ icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value); struct icalparameter_impl* icalparameter_new_impl(icalparameter_kind kind); /* This map associates each of the parameters with the string representation of the paramter's name */ struct icalparameter_kind_map { icalparameter_kind kind; char *name; }; -extern struct icalparameter_kind_map parameter_map[]; - - -const char* icalparameter_kind_to_string(icalparameter_kind kind) -{ - int i; - - for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { - if (parameter_map[i].kind == kind) { - return parameter_map[i].name; - } - } - - return 0; - -} - -icalparameter_kind icalparameter_string_to_kind(const char* string) -{ - int i; - - if (string ==0 ) { - return ICAL_NO_PARAMETER; - } - - for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { - - if (strcmp(parameter_map[i].name, string) == 0) { - return parameter_map[i].kind; - } - } - - if(strncmp(string,"X-",2)==0){ - return ICAL_X_PARAMETER; - } - - return ICAL_NO_PARAMETER; -} - /* This map associates the enumerations for the VALUE parameter with the kinds of VALUEs. */ struct icalparameter_value_kind_map { icalparameter_value value; icalvalue_kind kind; }; -extern struct icalparameter_value_kind_map value_kind_map[]; - - -icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value) -{ - int i; - - for (i=0; value_kind_map[i].kind != ICAL_NO_VALUE; i++) { - - if (value_kind_map[i].value == value) { - return value_kind_map[i].kind; - } - } - - return ICAL_NO_VALUE; -} - - /* This map associates the parameter enumerations with a specific parameter and the string representation of the enumeration */ struct icalparameter_map { icalparameter_kind kind; int enumeration; const char* str; }; -extern struct icalparameter_map icalparameter_map[]; - - -const char* icalparameter_enum_to_string(int e) -{ - int i; - - icalerror_check_arg_rz(e >= ICALPARAMETER_FIRST_ENUM,"e"); - icalerror_check_arg_rz(e <= ICALPARAMETER_LAST_ENUM,"e"); - - for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ - if(e == icalparameter_map[i].enumeration){ - return icalparameter_map[i].str; - } - } - - return 0; -} - -int icalparameter_string_to_enum(const char* str) -{ - int i; - - icalerror_check_arg_rz(str != 0,"str"); - - for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ - if(strcmp(str,icalparameter_map[i].str) == 0) { - return icalparameter_map[i].enumeration; - } - } - - return 0; -} -icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind,const char* val) -{ - - struct icalparameter_impl* param=0; - int found_kind = 0; - int i; - - icalerror_check_arg_rz((val!=0),"val"); - - /* Search through the parameter map to find a matching kind */ - - param = icalparameter_new_impl(kind); - - for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ - if(kind == icalparameter_map[i].kind) { - found_kind = 1; - if(strcmp(val,icalparameter_map[i].str) == 0) { - - param->data = (int)icalparameter_map[i].enumeration; - return param; - } - } - } - - if(found_kind == 1){ - /* The kind was in the parameter map, but the string did not - match, so assume that it is an alternate value, like an - X-value.*/ - - icalparameter_set_xvalue(param, val); - - } else { - - /* If the kind was not found, then it must be a string type */ - - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(val); - - } - - return param; -} - - - - -/* Everything below this line is machine generated. Do not edit. */ -struct icalparameter_value_kind_map value_kind_map[] = { +static struct icalparameter_value_kind_map value_kind_map[15] = { {ICAL_VALUE_BINARY,ICAL_BINARY_VALUE}, {ICAL_VALUE_BOOLEAN,ICAL_BOOLEAN_VALUE}, {ICAL_VALUE_DATE,ICAL_DATE_VALUE}, {ICAL_VALUE_DURATION,ICAL_DURATION_VALUE}, {ICAL_VALUE_FLOAT,ICAL_FLOAT_VALUE}, {ICAL_VALUE_INTEGER,ICAL_INTEGER_VALUE}, {ICAL_VALUE_PERIOD,ICAL_PERIOD_VALUE}, {ICAL_VALUE_RECUR,ICAL_RECUR_VALUE}, {ICAL_VALUE_TEXT,ICAL_TEXT_VALUE}, {ICAL_VALUE_URI,ICAL_URI_VALUE}, {ICAL_VALUE_DATETIME,ICAL_DATETIME_VALUE}, {ICAL_VALUE_UTCOFFSET,ICAL_UTCOFFSET_VALUE}, {ICAL_VALUE_CALADDRESS,ICAL_CALADDRESS_VALUE}, {ICAL_VALUE_X,ICAL_X_VALUE}, {ICAL_VALUE_NONE,ICAL_NO_VALUE} }; -static struct icalparameter_kind_map parameter_map[] = { +static struct icalparameter_kind_map parameter_map[24] = { {ICAL_ALTREP_PARAMETER,"ALTREP"}, {ICAL_CN_PARAMETER,"CN"}, {ICAL_CUTYPE_PARAMETER,"CUTYPE"}, {ICAL_DELEGATEDFROM_PARAMETER,"DELEGATED-FROM"}, {ICAL_DELEGATEDTO_PARAMETER,"DELEGATED-TO"}, {ICAL_DIR_PARAMETER,"DIR"}, {ICAL_ENCODING_PARAMETER,"ENCODING"}, {ICAL_FBTYPE_PARAMETER,"FBTYPE"}, {ICAL_FMTTYPE_PARAMETER,"FMTTYPE"}, {ICAL_LANGUAGE_PARAMETER,"LANGUAGE"}, {ICAL_MEMBER_PARAMETER,"MEMBER"}, {ICAL_PARTSTAT_PARAMETER,"PARTSTAT"}, {ICAL_RANGE_PARAMETER,"RANGE"}, {ICAL_RELATED_PARAMETER,"RELATED"}, {ICAL_RELTYPE_PARAMETER,"RELTYPE"}, {ICAL_ROLE_PARAMETER,"ROLE"}, {ICAL_RSVP_PARAMETER,"RSVP"}, {ICAL_SENTBY_PARAMETER,"SENT-BY"}, {ICAL_TZID_PARAMETER,"TZID"}, {ICAL_VALUE_PARAMETER,"VALUE"}, {ICAL_X_PARAMETER,"X"}, {ICAL_XLICCOMPARETYPE_PARAMETER,"X-LIC-COMPARETYPE"}, {ICAL_XLICERRORTYPE_PARAMETER,"X-LIC-ERRORTYPE"}, { ICAL_NO_PARAMETER, ""} }; static struct icalparameter_map icalparameter_map[] = { {ICAL_ANY_PARAMETER,0,""}, {ICAL_CUTYPE_PARAMETER,ICAL_CUTYPE_INDIVIDUAL,"INDIVIDUAL"}, {ICAL_CUTYPE_PARAMETER,ICAL_CUTYPE_GROUP,"GROUP"}, {ICAL_CUTYPE_PARAMETER,ICAL_CUTYPE_RESOURCE,"RESOURCE"}, {ICAL_CUTYPE_PARAMETER,ICAL_CUTYPE_ROOM,"ROOM"}, {ICAL_CUTYPE_PARAMETER,ICAL_CUTYPE_UNKNOWN,"UNKNOWN"}, {ICAL_ENCODING_PARAMETER,ICAL_ENCODING_8BIT,"8BIT"}, {ICAL_ENCODING_PARAMETER,ICAL_ENCODING_BASE64,"BASE64"}, {ICAL_FBTYPE_PARAMETER,ICAL_FBTYPE_FREE,"FREE"}, {ICAL_FBTYPE_PARAMETER,ICAL_FBTYPE_BUSY,"BUSY"}, {ICAL_FBTYPE_PARAMETER,ICAL_FBTYPE_BUSYUNAVAILABLE,"BUSYUNAVAILABLE"}, {ICAL_FBTYPE_PARAMETER,ICAL_FBTYPE_BUSYTENTATIVE,"BUSYTENTATIVE"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_NEEDSACTION,"NEEDS-ACTION"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_ACCEPTED,"ACCEPTED"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_DECLINED,"DECLINED"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_TENTATIVE,"TENTATIVE"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_DELEGATED,"DELEGATED"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_COMPLETED,"COMPLETED"}, {ICAL_PARTSTAT_PARAMETER,ICAL_PARTSTAT_INPROCESS,"INPROCESS"}, {ICAL_RANGE_PARAMETER,ICAL_RANGE_THISANDPRIOR,"THISANDPRIOR"}, {ICAL_RANGE_PARAMETER,ICAL_RANGE_THISANDFUTURE,"THISANDFUTURE"}, {ICAL_RELATED_PARAMETER,ICAL_RELATED_START,"START"}, - {ICAL_RELATED_PARAMETER,ICAL_RELATED_END ,"END "}, + {ICAL_RELATED_PARAMETER,ICAL_RELATED_END,"END"}, {ICAL_RELTYPE_PARAMETER,ICAL_RELTYPE_PARENT,"PARENT"}, {ICAL_RELTYPE_PARAMETER,ICAL_RELTYPE_CHILD,"CHILD"}, {ICAL_RELTYPE_PARAMETER,ICAL_RELTYPE_SIBLING,"SIBLING"}, {ICAL_ROLE_PARAMETER,ICAL_ROLE_CHAIR,"CHAIR"}, {ICAL_ROLE_PARAMETER,ICAL_ROLE_REQPARTICIPANT,"REQ-PARTICIPANT"}, {ICAL_ROLE_PARAMETER,ICAL_ROLE_OPTPARTICIPANT,"OPT-PARTICIPANT"}, {ICAL_ROLE_PARAMETER,ICAL_ROLE_NONPARTICIPANT,"NON-PARTICIPANT"}, {ICAL_RSVP_PARAMETER,ICAL_RSVP_TRUE,"TRUE"}, {ICAL_RSVP_PARAMETER,ICAL_RSVP_FALSE,"FALSE"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_BINARY,"BINARY"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_BOOLEAN,"BOOLEAN"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_DATE,"DATE"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_DURATION,"DURATION"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_FLOAT,"FLOAT"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_INTEGER,"INTEGER"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_PERIOD,"PERIOD"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_RECUR,"RECUR"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_TEXT,"TEXT"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_URI,"URI"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_ERROR,"ERROR"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_DATETIME,"DATE-TIME"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_UTCOFFSET,"UTC-OFFSET"}, {ICAL_VALUE_PARAMETER,ICAL_VALUE_CALADDRESS,"CAL-ADDRESS"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_EQUAL,"EQUAL"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_NOTEQUAL,"NOTEQUAL"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_LESS,"LESS"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_GREATER,"GREATER"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_LESSEQUAL,"LESSEQUAL"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_GREATEREQUAL,"GREATEREQUAL"}, {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_REGEX,"REGEX"}, + {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_ISNULL,"ISNULL"}, + {ICAL_XLICCOMPARETYPE_PARAMETER,ICAL_XLICCOMPARETYPE_ISNOTNULL,"ISNOTNULL"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_COMPONENTPARSEERROR,"COMPONENT-PARSE-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_PROPERTYPARSEERROR,"PROPERTY-PARSE-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR,"PARAMETER-NAME-PARSE-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR,"PARAMETER-VALUE-PARSE-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_VALUEPARSEERROR,"VALUE-PARSE-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_INVALIDITIP,"INVALID-ITIP"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR,"UNKNOWN-VCAL-PROP-ERROR"}, {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_MIMEPARSEERROR,"MIME-PARSE-ERROR"}, + {ICAL_XLICERRORTYPE_PARAMETER,ICAL_XLICERRORTYPE_VCALPROPPARSEERROR,"VCAL-PROP-PARSE-ERROR"}, {ICAL_NO_PARAMETER,0,""}}; -/* DELEGATED-FROM */ -icalparameter* icalparameter_new_delegatedfrom(const char* v) +/* LANGUAGE */ +icalparameter* icalparameter_new_language(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_DELEGATEDFROM_PARAMETER); + impl = icalparameter_new_impl(ICAL_LANGUAGE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_delegatedfrom((icalparameter*) impl,v); + icalparameter_set_language((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_delegatedfrom(icalparameter* param) +const char* icalparameter_get_language(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_delegatedfrom(icalparameter* param, const char* v) +void icalparameter_set_language(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* DELEGATED-TO */ -icalparameter* icalparameter_new_delegatedto(const char* v) +/* DIR */ +icalparameter* icalparameter_new_dir(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_DELEGATEDTO_PARAMETER); + impl = icalparameter_new_impl(ICAL_DIR_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_delegatedto((icalparameter*) impl,v); + icalparameter_set_dir((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_delegatedto(icalparameter* param) +const char* icalparameter_get_dir(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_delegatedto(icalparameter* param, const char* v) +void icalparameter_set_dir(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* RANGE */ -icalparameter* icalparameter_new_range(icalparameter_range v) +/* RELTYPE */ +icalparameter* icalparameter_new_reltype(icalparameter_reltype v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_RANGE_X,"v"); - icalerror_check_arg_rz(v < ICAL_RANGE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_RANGE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_RELTYPE_X,"v"); + icalerror_check_arg_rz(v < ICAL_RELTYPE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_RELTYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_range((icalparameter*) impl,v); + icalparameter_set_reltype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_range icalparameter_get_range(icalparameter* param) +icalparameter_reltype icalparameter_get_reltype(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); + if (param->string != 0){ + return ICAL_RELTYPE_X; + } -return (icalparameter_range)((struct icalparameter_impl*)param)->data; +return (icalparameter_reltype)(param->data); } -void icalparameter_set_range(icalparameter* param, icalparameter_range v) +void icalparameter_set_reltype(icalparameter* param, icalparameter_reltype v) { - icalerror_check_arg_rv(v >= ICAL_RANGE_X,"v"); - icalerror_check_arg_rv(v < ICAL_RANGE_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_RELTYPE_X,"v"); + icalerror_check_arg_rv(v < ICAL_RELTYPE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* ENCODING */ -icalparameter* icalparameter_new_encoding(icalparameter_encoding v) +/* FMTTYPE */ +icalparameter* icalparameter_new_fmttype(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_ENCODING_X,"v"); - icalerror_check_arg_rz(v < ICAL_ENCODING_NONE,"v"); - impl = icalparameter_new_impl(ICAL_ENCODING_PARAMETER); + icalerror_check_arg_rz( (v!=0),"v"); + impl = icalparameter_new_impl(ICAL_FMTTYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_encoding((icalparameter*) impl,v); + icalparameter_set_fmttype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_encoding icalparameter_get_encoding(icalparameter* param) +const char* icalparameter_get_fmttype(const icalparameter* param) { icalerror_clear_errno(); -icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_ENCODING_X; - } + icalerror_check_arg_rz( (param!=0), "param"); + return param->string; +} -return (icalparameter_encoding)((struct icalparameter_impl*)param)->data; +void icalparameter_set_fmttype(icalparameter* param, const char* v) +{ + icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv( (param!=0), "param"); + icalerror_clear_errno(); + + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -void icalparameter_set_encoding(icalparameter* param, icalparameter_encoding v) +/* TZID */ +icalparameter* icalparameter_new_tzid(const char* v) { - icalerror_check_arg_rv(v >= ICAL_ENCODING_X,"v"); - icalerror_check_arg_rv(v < ICAL_ENCODING_NONE,"v"); + struct icalparameter_impl *impl; + icalerror_clear_errno(); + icalerror_check_arg_rz( (v!=0),"v"); + impl = icalparameter_new_impl(ICAL_TZID_PARAMETER); + if (impl == 0) { + return 0; + } + + icalparameter_set_tzid((icalparameter*) impl,v); + if (icalerrno != ICAL_NO_ERROR) { + icalparameter_free((icalparameter*) impl); + return 0; + } + + return (icalparameter*) impl; +} + +const char* icalparameter_get_tzid(const icalparameter* param) +{ + icalerror_clear_errno(); + icalerror_check_arg_rz( (param!=0), "param"); + return param->string; +} + +void icalparameter_set_tzid(icalparameter* param, const char* v) +{ + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->data = (int)v; + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* RSVP */ -icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v) +/* RANGE */ +icalparameter* icalparameter_new_range(icalparameter_range v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_RSVP_X,"v"); - icalerror_check_arg_rz(v < ICAL_RSVP_NONE,"v"); - impl = icalparameter_new_impl(ICAL_RSVP_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_RANGE_X,"v"); + icalerror_check_arg_rz(v < ICAL_RANGE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_RANGE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_rsvp((icalparameter*) impl,v); + icalparameter_set_range((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_rsvp icalparameter_get_rsvp(icalparameter* param) +icalparameter_range icalparameter_get_range(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); -return (icalparameter_rsvp)((struct icalparameter_impl*)param)->data; +return (icalparameter_range)(param->data); } -void icalparameter_set_rsvp(icalparameter* param, icalparameter_rsvp v) +void icalparameter_set_range(icalparameter* param, icalparameter_range v) { - icalerror_check_arg_rv(v >= ICAL_RSVP_X,"v"); - icalerror_check_arg_rv(v < ICAL_RSVP_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_RANGE_X,"v"); + icalerror_check_arg_rv(v < ICAL_RANGE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* PARTSTAT */ -icalparameter* icalparameter_new_partstat(icalparameter_partstat v) +/* DELEGATED-TO */ +icalparameter* icalparameter_new_delegatedto(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_PARTSTAT_X,"v"); - icalerror_check_arg_rz(v < ICAL_PARTSTAT_NONE,"v"); - impl = icalparameter_new_impl(ICAL_PARTSTAT_PARAMETER); + icalerror_check_arg_rz( (v!=0),"v"); + impl = icalparameter_new_impl(ICAL_DELEGATEDTO_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_partstat((icalparameter*) impl,v); + icalparameter_set_delegatedto((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_partstat icalparameter_get_partstat(icalparameter* param) +const char* icalparameter_get_delegatedto(const icalparameter* param) { icalerror_clear_errno(); -icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_PARTSTAT_X; - } + icalerror_check_arg_rz( (param!=0), "param"); + return param->string; +} -return (icalparameter_partstat)((struct icalparameter_impl*)param)->data; +void icalparameter_set_delegatedto(icalparameter* param, const char* v) +{ + icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv( (param!=0), "param"); + icalerror_clear_errno(); + + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -void icalparameter_set_partstat(icalparameter* param, icalparameter_partstat v) +/* CN */ +icalparameter* icalparameter_new_cn(const char* v) { - icalerror_check_arg_rv(v >= ICAL_PARTSTAT_X,"v"); - icalerror_check_arg_rv(v < ICAL_PARTSTAT_NONE,"v"); + struct icalparameter_impl *impl; + icalerror_clear_errno(); + icalerror_check_arg_rz( (v!=0),"v"); + impl = icalparameter_new_impl(ICAL_CN_PARAMETER); + if (impl == 0) { + return 0; + } + + icalparameter_set_cn((icalparameter*) impl,v); + if (icalerrno != ICAL_NO_ERROR) { + icalparameter_free((icalparameter*) impl); + return 0; + } + + return (icalparameter*) impl; +} + +const char* icalparameter_get_cn(const icalparameter* param) +{ + icalerror_clear_errno(); + icalerror_check_arg_rz( (param!=0), "param"); + return param->string; +} + +void icalparameter_set_cn(icalparameter* param, const char* v) +{ + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->data = (int)v; + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* RELTYPE */ -icalparameter* icalparameter_new_reltype(icalparameter_reltype v) +/* VALUE */ +icalparameter* icalparameter_new_value(icalparameter_value v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_RELTYPE_X,"v"); - icalerror_check_arg_rz(v < ICAL_RELTYPE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_RELTYPE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_VALUE_X,"v"); + icalerror_check_arg_rz(v < ICAL_VALUE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_VALUE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_reltype((icalparameter*) impl,v); + icalparameter_set_value((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_reltype icalparameter_get_reltype(icalparameter* param) +icalparameter_value icalparameter_get_value(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_RELTYPE_X; + if (param->string != 0){ + return ICAL_VALUE_X; } -return (icalparameter_reltype)((struct icalparameter_impl*)param)->data; +return (icalparameter_value)(param->data); } -void icalparameter_set_reltype(icalparameter* param, icalparameter_reltype v) +void icalparameter_set_value(icalparameter* param, icalparameter_value v) { - icalerror_check_arg_rv(v >= ICAL_RELTYPE_X,"v"); - icalerror_check_arg_rv(v < ICAL_RELTYPE_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_VALUE_X,"v"); + icalerror_check_arg_rv(v < ICAL_VALUE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* CUTYPE */ -icalparameter* icalparameter_new_cutype(icalparameter_cutype v) +/* X-LIC-COMPARETYPE */ +icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_CUTYPE_X,"v"); - icalerror_check_arg_rz(v < ICAL_CUTYPE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_CUTYPE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_XLICCOMPARETYPE_X,"v"); + icalerror_check_arg_rz(v < ICAL_XLICCOMPARETYPE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_XLICCOMPARETYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_cutype((icalparameter*) impl,v); + icalparameter_set_xliccomparetype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_cutype icalparameter_get_cutype(icalparameter* param) +icalparameter_xliccomparetype icalparameter_get_xliccomparetype(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_CUTYPE_X; - } -return (icalparameter_cutype)((struct icalparameter_impl*)param)->data; +return (icalparameter_xliccomparetype)(param->data); } -void icalparameter_set_cutype(icalparameter* param, icalparameter_cutype v) +void icalparameter_set_xliccomparetype(icalparameter* param, icalparameter_xliccomparetype v) { - icalerror_check_arg_rv(v >= ICAL_CUTYPE_X,"v"); - icalerror_check_arg_rv(v < ICAL_CUTYPE_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_XLICCOMPARETYPE_X,"v"); + icalerror_check_arg_rv(v < ICAL_XLICCOMPARETYPE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* MEMBER */ -icalparameter* icalparameter_new_member(const char* v) +/* X */ +icalparameter* icalparameter_new_x(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_MEMBER_PARAMETER); + impl = icalparameter_new_impl(ICAL_X_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_member((icalparameter*) impl,v); + icalparameter_set_x((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_member(icalparameter* param) +const char* icalparameter_get_x(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_member(icalparameter* param, const char* v) +void icalparameter_set_x(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* FMTTYPE */ -icalparameter* icalparameter_new_fmttype(const char* v) +/* SENT-BY */ +icalparameter* icalparameter_new_sentby(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_FMTTYPE_PARAMETER); + impl = icalparameter_new_impl(ICAL_SENTBY_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_fmttype((icalparameter*) impl,v); + icalparameter_set_sentby((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_fmttype(icalparameter* param) +const char* icalparameter_get_sentby(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_fmttype(icalparameter* param, const char* v) +void icalparameter_set_sentby(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* SENT-BY */ -icalparameter* icalparameter_new_sentby(const char* v) +/* MEMBER */ +icalparameter* icalparameter_new_member(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_SENTBY_PARAMETER); + impl = icalparameter_new_impl(ICAL_MEMBER_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_sentby((icalparameter*) impl,v); + icalparameter_set_member((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_sentby(icalparameter* param) +const char* icalparameter_get_member(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_sentby(icalparameter* param, const char* v) +void icalparameter_set_member(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* VALUE */ -icalparameter* icalparameter_new_value(icalparameter_value v) +/* RSVP */ +icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_VALUE_X,"v"); - icalerror_check_arg_rz(v < ICAL_VALUE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_VALUE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_RSVP_X,"v"); + icalerror_check_arg_rz(v < ICAL_RSVP_NONE,"v"); + impl = icalparameter_new_impl(ICAL_RSVP_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_value((icalparameter*) impl,v); + icalparameter_set_rsvp((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_value icalparameter_get_value(icalparameter* param) +icalparameter_rsvp icalparameter_get_rsvp(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_VALUE_X; - } -return (icalparameter_value)((struct icalparameter_impl*)param)->data; +return (icalparameter_rsvp)(param->data); } -void icalparameter_set_value(icalparameter* param, icalparameter_value v) +void icalparameter_set_rsvp(icalparameter* param, icalparameter_rsvp v) { - icalerror_check_arg_rv(v >= ICAL_VALUE_X,"v"); - icalerror_check_arg_rv(v < ICAL_VALUE_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_RSVP_X,"v"); + icalerror_check_arg_rv(v < ICAL_RSVP_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* ALTREP */ -icalparameter* icalparameter_new_altrep(const char* v) +/* CUTYPE */ +icalparameter* icalparameter_new_cutype(icalparameter_cutype v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_ALTREP_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_CUTYPE_X,"v"); + icalerror_check_arg_rz(v < ICAL_CUTYPE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_CUTYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_altrep((icalparameter*) impl,v); + icalparameter_set_cutype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_altrep(icalparameter* param) +icalparameter_cutype icalparameter_get_cutype(const icalparameter* param) { icalerror_clear_errno(); - icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; +icalerror_check_arg( (param!=0), "param"); + if (param->string != 0){ + return ICAL_CUTYPE_X; + } + +return (icalparameter_cutype)(param->data); } -void icalparameter_set_altrep(icalparameter* param, const char* v) +void icalparameter_set_cutype(icalparameter* param, icalparameter_cutype v) { - icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv(v >= ICAL_CUTYPE_X,"v"); + icalerror_check_arg_rv(v < ICAL_CUTYPE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); + ((struct icalparameter_impl*)param)->data = (int)v; } -/* DIR */ -icalparameter* icalparameter_new_dir(const char* v) +/* X-LIC-ERRORTYPE */ +icalparameter* icalparameter_new_xlicerrortype(icalparameter_xlicerrortype v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_DIR_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_XLICERRORTYPE_X,"v"); + icalerror_check_arg_rz(v < ICAL_XLICERRORTYPE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_XLICERRORTYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_dir((icalparameter*) impl,v); + icalparameter_set_xlicerrortype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_dir(icalparameter* param) +icalparameter_xlicerrortype icalparameter_get_xlicerrortype(const icalparameter* param) { icalerror_clear_errno(); - icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; +icalerror_check_arg( (param!=0), "param"); + +return (icalparameter_xlicerrortype)(param->data); } -void icalparameter_set_dir(icalparameter* param, const char* v) +void icalparameter_set_xlicerrortype(icalparameter* param, icalparameter_xlicerrortype v) { - icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv(v >= ICAL_XLICERRORTYPE_X,"v"); + icalerror_check_arg_rv(v < ICAL_XLICERRORTYPE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); + ((struct icalparameter_impl*)param)->data = (int)v; } /* RELATED */ icalparameter* icalparameter_new_related(icalparameter_related v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz(v >= ICAL_RELATED_X,"v"); icalerror_check_arg_rz(v < ICAL_RELATED_NONE,"v"); impl = icalparameter_new_impl(ICAL_RELATED_PARAMETER); if (impl == 0) { return 0; } icalparameter_set_related((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_related icalparameter_get_related(icalparameter* param) +icalparameter_related icalparameter_get_related(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); -return (icalparameter_related)((struct icalparameter_impl*)param)->data; +return (icalparameter_related)(param->data); } void icalparameter_set_related(icalparameter* param, icalparameter_related v) { icalerror_check_arg_rv(v >= ICAL_RELATED_X,"v"); icalerror_check_arg_rv(v < ICAL_RELATED_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* CN */ -icalparameter* icalparameter_new_cn(const char* v) +/* ENCODING */ +icalparameter* icalparameter_new_encoding(icalparameter_encoding v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_CN_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_ENCODING_X,"v"); + icalerror_check_arg_rz(v < ICAL_ENCODING_NONE,"v"); + impl = icalparameter_new_impl(ICAL_ENCODING_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_cn((icalparameter*) impl,v); + icalparameter_set_encoding((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_cn(icalparameter* param) +icalparameter_encoding icalparameter_get_encoding(const icalparameter* param) { icalerror_clear_errno(); - icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; +icalerror_check_arg( (param!=0), "param"); + if (param->string != 0){ + return ICAL_ENCODING_X; + } + +return (icalparameter_encoding)(param->data); } -void icalparameter_set_cn(icalparameter* param, const char* v) +void icalparameter_set_encoding(icalparameter* param, icalparameter_encoding v) { - icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv(v >= ICAL_ENCODING_X,"v"); + icalerror_check_arg_rv(v < ICAL_ENCODING_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); + ((struct icalparameter_impl*)param)->data = (int)v; } -/* X-LIC-ERRORTYPE */ -icalparameter* icalparameter_new_xlicerrortype(icalparameter_xlicerrortype v) +/* ALTREP */ +icalparameter* icalparameter_new_altrep(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_XLICERRORTYPE_X,"v"); - icalerror_check_arg_rz(v < ICAL_XLICERRORTYPE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_XLICERRORTYPE_PARAMETER); + icalerror_check_arg_rz( (v!=0),"v"); + impl = icalparameter_new_impl(ICAL_ALTREP_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_xlicerrortype((icalparameter*) impl,v); + icalparameter_set_altrep((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_xlicerrortype icalparameter_get_xlicerrortype(icalparameter* param) +const char* icalparameter_get_altrep(const icalparameter* param) { icalerror_clear_errno(); -icalerror_check_arg( (param!=0), "param"); - -return (icalparameter_xlicerrortype)((struct icalparameter_impl*)param)->data; + icalerror_check_arg_rz( (param!=0), "param"); + return param->string; } -void icalparameter_set_xlicerrortype(icalparameter* param, icalparameter_xlicerrortype v) +void icalparameter_set_altrep(icalparameter* param, const char* v) { - icalerror_check_arg_rv(v >= ICAL_XLICERRORTYPE_X,"v"); - icalerror_check_arg_rv(v < ICAL_XLICERRORTYPE_NONE,"v"); + icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->data = (int)v; + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* X */ -icalparameter* icalparameter_new_x(const char* v) +/* DELEGATED-FROM */ +icalparameter* icalparameter_new_delegatedfrom(const char* v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_X_PARAMETER); + impl = icalparameter_new_impl(ICAL_DELEGATEDFROM_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_x((icalparameter*) impl,v); + icalparameter_set_delegatedfrom((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_x(icalparameter* param) +const char* icalparameter_get_delegatedfrom(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + return param->string; } -void icalparameter_set_x(icalparameter* param, const char* v) +void icalparameter_set_delegatedfrom(icalparameter* param, const char* v) { icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); } -/* LANGUAGE */ -icalparameter* icalparameter_new_language(const char* v) +/* FBTYPE */ +icalparameter* icalparameter_new_fbtype(icalparameter_fbtype v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_LANGUAGE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_FBTYPE_X,"v"); + icalerror_check_arg_rz(v < ICAL_FBTYPE_NONE,"v"); + impl = icalparameter_new_impl(ICAL_FBTYPE_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_language((icalparameter*) impl,v); + icalparameter_set_fbtype((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -const char* icalparameter_get_language(icalparameter* param) +icalparameter_fbtype icalparameter_get_fbtype(const icalparameter* param) { icalerror_clear_errno(); - icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; +icalerror_check_arg( (param!=0), "param"); + if (param->string != 0){ + return ICAL_FBTYPE_X; + } + +return (icalparameter_fbtype)(param->data); } -void icalparameter_set_language(icalparameter* param, const char* v) +void icalparameter_set_fbtype(icalparameter* param, icalparameter_fbtype v) { - icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_arg_rv(v >= ICAL_FBTYPE_X,"v"); + icalerror_check_arg_rv(v < ICAL_FBTYPE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); + ((struct icalparameter_impl*)param)->data = (int)v; } /* ROLE */ icalparameter* icalparameter_new_role(icalparameter_role v) { struct icalparameter_impl *impl; icalerror_clear_errno(); icalerror_check_arg_rz(v >= ICAL_ROLE_X,"v"); icalerror_check_arg_rz(v < ICAL_ROLE_NONE,"v"); impl = icalparameter_new_impl(ICAL_ROLE_PARAMETER); if (impl == 0) { return 0; } icalparameter_set_role((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_role icalparameter_get_role(icalparameter* param) +icalparameter_role icalparameter_get_role(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ + if (param->string != 0){ return ICAL_ROLE_X; } -return (icalparameter_role)((struct icalparameter_impl*)param)->data; +return (icalparameter_role)(param->data); } void icalparameter_set_role(icalparameter* param, icalparameter_role v) { icalerror_check_arg_rv(v >= ICAL_ROLE_X,"v"); icalerror_check_arg_rv(v < ICAL_ROLE_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* X-LIC-COMPARETYPE */ -icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v) +/* PARTSTAT */ +icalparameter* icalparameter_new_partstat(icalparameter_partstat v) { struct icalparameter_impl *impl; icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_XLICCOMPARETYPE_X,"v"); - icalerror_check_arg_rz(v < ICAL_XLICCOMPARETYPE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_XLICCOMPARETYPE_PARAMETER); + icalerror_check_arg_rz(v >= ICAL_PARTSTAT_X,"v"); + icalerror_check_arg_rz(v < ICAL_PARTSTAT_NONE,"v"); + impl = icalparameter_new_impl(ICAL_PARTSTAT_PARAMETER); if (impl == 0) { return 0; } - icalparameter_set_xliccomparetype((icalparameter*) impl,v); + icalparameter_set_partstat((icalparameter*) impl,v); if (icalerrno != ICAL_NO_ERROR) { icalparameter_free((icalparameter*) impl); return 0; } return (icalparameter*) impl; } -icalparameter_xliccomparetype icalparameter_get_xliccomparetype(icalparameter* param) +icalparameter_partstat icalparameter_get_partstat(const icalparameter* param) { icalerror_clear_errno(); icalerror_check_arg( (param!=0), "param"); + if (param->string != 0){ + return ICAL_PARTSTAT_X; + } -return (icalparameter_xliccomparetype)((struct icalparameter_impl*)param)->data; +return (icalparameter_partstat)(param->data); } -void icalparameter_set_xliccomparetype(icalparameter* param, icalparameter_xliccomparetype v) +void icalparameter_set_partstat(icalparameter* param, icalparameter_partstat v) { - icalerror_check_arg_rv(v >= ICAL_XLICCOMPARETYPE_X,"v"); - icalerror_check_arg_rv(v < ICAL_XLICCOMPARETYPE_NONE,"v"); + icalerror_check_arg_rv(v >= ICAL_PARTSTAT_X,"v"); + icalerror_check_arg_rv(v < ICAL_PARTSTAT_NONE,"v"); icalerror_check_arg_rv( (param!=0), "param"); icalerror_clear_errno(); ((struct icalparameter_impl*)param)->data = (int)v; } -/* FBTYPE */ -icalparameter* icalparameter_new_fbtype(icalparameter_fbtype v) + +const char* icalparameter_kind_to_string(icalparameter_kind kind) { - struct icalparameter_impl *impl; - icalerror_clear_errno(); - icalerror_check_arg_rz(v >= ICAL_FBTYPE_X,"v"); - icalerror_check_arg_rz(v < ICAL_FBTYPE_NONE,"v"); - impl = icalparameter_new_impl(ICAL_FBTYPE_PARAMETER); - if (impl == 0) { - return 0; - } + int i; - icalparameter_set_fbtype((icalparameter*) impl,v); - if (icalerrno != ICAL_NO_ERROR) { - icalparameter_free((icalparameter*) impl); - return 0; - } + for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { + if (parameter_map[i].kind == kind) { + return parameter_map[i].name; + } + } + + return 0; - return (icalparameter*) impl; } -icalparameter_fbtype icalparameter_get_fbtype(icalparameter* param) +icalparameter_kind icalparameter_string_to_kind(const char* string) { - icalerror_clear_errno(); -icalerror_check_arg( (param!=0), "param"); - if ( ((struct icalparameter_impl*)param)->string != 0){ - return ICAL_FBTYPE_X; - } + int i; + + if (string ==0 ) { + return ICAL_NO_PARAMETER; + } + + for (i=0; parameter_map[i].kind != ICAL_NO_PARAMETER; i++) { + + if (strcmp(parameter_map[i].name, string) == 0) { + return parameter_map[i].kind; + } + } -return (icalparameter_fbtype)((struct icalparameter_impl*)param)->data; + if(strncmp(string,"X-",2)==0){ + return ICAL_X_PARAMETER; + } + + return ICAL_NO_PARAMETER; } -void icalparameter_set_fbtype(icalparameter* param, icalparameter_fbtype v) + +icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value) { - icalerror_check_arg_rv(v >= ICAL_FBTYPE_X,"v"); - icalerror_check_arg_rv(v < ICAL_FBTYPE_NONE,"v"); - icalerror_check_arg_rv( (param!=0), "param"); - icalerror_clear_errno(); - - ((struct icalparameter_impl*)param)->data = (int)v; + int i; + + for (i=0; value_kind_map[i].kind != ICAL_NO_VALUE; i++) { + + if (value_kind_map[i].value == value) { + return value_kind_map[i].kind; + } + } + + return ICAL_NO_VALUE; } -/* TZID */ -icalparameter* icalparameter_new_tzid(const char* v) + +const char* icalparameter_enum_to_string(int e) { - struct icalparameter_impl *impl; - icalerror_clear_errno(); - icalerror_check_arg_rz( (v!=0),"v"); - impl = icalparameter_new_impl(ICAL_TZID_PARAMETER); - if (impl == 0) { - return 0; - } + int i; - icalparameter_set_tzid((icalparameter*) impl,v); - if (icalerrno != ICAL_NO_ERROR) { - icalparameter_free((icalparameter*) impl); - return 0; - } + icalerror_check_arg_rz(e >= ICALPARAMETER_FIRST_ENUM,"e"); + icalerror_check_arg_rz(e <= ICALPARAMETER_LAST_ENUM,"e"); - return (icalparameter*) impl; + for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ + if(e == icalparameter_map[i].enumeration){ + return icalparameter_map[i].str; + } + } + + return 0; } -const char* icalparameter_get_tzid(icalparameter* param) +int icalparameter_string_to_enum(const char* str) { - icalerror_clear_errno(); - icalerror_check_arg_rz( (param!=0), "param"); - return (const char*)((struct icalparameter_impl*)param)->string; + int i; + + icalerror_check_arg_rz(str != 0,"str"); + + for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ + if(strcmp(str,icalparameter_map[i].str) == 0) { + return icalparameter_map[i].enumeration; + } + } + + return 0; } -void icalparameter_set_tzid(icalparameter* param, const char* v) +icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind,const char* val) { - icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_arg_rv( (param!=0), "param"); - icalerror_clear_errno(); - - ((struct icalparameter_impl*)param)->string = icalmemory_strdup(v); + + struct icalparameter_impl* param=0; + int found_kind = 0; + int i; + + icalerror_check_arg_rz((val!=0),"val"); + + /* Search through the parameter map to find a matching kind */ + + param = icalparameter_new_impl(kind); + + for (i=0; icalparameter_map[i].kind != ICAL_NO_PARAMETER; i++){ + if(kind == icalparameter_map[i].kind) { + found_kind = 1; + if(strcmp(val,icalparameter_map[i].str) == 0) { + + param->data = (int)icalparameter_map[i].enumeration; + return param; + } + } + } + + if(found_kind == 1){ + /* The kind was in the parameter map, but the string did not + match, so assume that it is an alternate value, like an + X-value.*/ + + icalparameter_set_xvalue(param, val); + + } else { + + /* If the kind was not found, then it must be a string type */ + + ((struct icalparameter_impl*)param)->string = icalmemory_strdup(val); + + } + + return param; } + + + +/* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icalderivedparameter.h b/libical/src/libical/icalderivedparameter.h index adf4724..cbf0035 100644 --- a/libical/src/libical/icalderivedparameter.h +++ b/libical/src/libical/icalderivedparameter.h @@ -1,307 +1,310 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalparam.h CREATOR: eric 20 March 1999 $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 icalparam.h ======================================================================*/ #ifndef ICALDERIVEDPARAMETER_H #define ICALDERIVEDPARAMETER_H -typedef void icalparameter; +typedef struct icalparameter_impl icalparameter; const char* icalparameter_enum_to_string(int e); int icalparameter_string_to_enum(const char* str); -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalparameter_kind { ICAL_ANY_PARAMETER = 0, ICAL_ALTREP_PARAMETER, ICAL_CN_PARAMETER, ICAL_CUTYPE_PARAMETER, ICAL_DELEGATEDFROM_PARAMETER, ICAL_DELEGATEDTO_PARAMETER, ICAL_DIR_PARAMETER, ICAL_ENCODING_PARAMETER, ICAL_FBTYPE_PARAMETER, ICAL_FMTTYPE_PARAMETER, ICAL_LANGUAGE_PARAMETER, ICAL_MEMBER_PARAMETER, ICAL_PARTSTAT_PARAMETER, ICAL_RANGE_PARAMETER, ICAL_RELATED_PARAMETER, ICAL_RELTYPE_PARAMETER, ICAL_ROLE_PARAMETER, ICAL_RSVP_PARAMETER, ICAL_SENTBY_PARAMETER, ICAL_TZID_PARAMETER, ICAL_VALUE_PARAMETER, ICAL_X_PARAMETER, ICAL_XLICCOMPARETYPE_PARAMETER, ICAL_XLICERRORTYPE_PARAMETER, ICAL_NO_PARAMETER } icalparameter_kind; #define ICALPARAMETER_FIRST_ENUM 20000 typedef enum icalparameter_cutype { ICAL_CUTYPE_X = 20000, ICAL_CUTYPE_INDIVIDUAL = 20001, ICAL_CUTYPE_GROUP = 20002, ICAL_CUTYPE_RESOURCE = 20003, ICAL_CUTYPE_ROOM = 20004, ICAL_CUTYPE_UNKNOWN = 20005, ICAL_CUTYPE_NONE = 20006 } icalparameter_cutype; typedef enum icalparameter_encoding { ICAL_ENCODING_X = 20007, ICAL_ENCODING_8BIT = 20008, ICAL_ENCODING_BASE64 = 20009, ICAL_ENCODING_NONE = 20010 } icalparameter_encoding; typedef enum icalparameter_fbtype { ICAL_FBTYPE_X = 20011, ICAL_FBTYPE_FREE = 20012, ICAL_FBTYPE_BUSY = 20013, ICAL_FBTYPE_BUSYUNAVAILABLE = 20014, ICAL_FBTYPE_BUSYTENTATIVE = 20015, ICAL_FBTYPE_NONE = 20016 } icalparameter_fbtype; typedef enum icalparameter_partstat { ICAL_PARTSTAT_X = 20017, ICAL_PARTSTAT_NEEDSACTION = 20018, ICAL_PARTSTAT_ACCEPTED = 20019, ICAL_PARTSTAT_DECLINED = 20020, ICAL_PARTSTAT_TENTATIVE = 20021, ICAL_PARTSTAT_DELEGATED = 20022, ICAL_PARTSTAT_COMPLETED = 20023, ICAL_PARTSTAT_INPROCESS = 20024, ICAL_PARTSTAT_NONE = 20025 } icalparameter_partstat; typedef enum icalparameter_range { ICAL_RANGE_X = 20026, ICAL_RANGE_THISANDPRIOR = 20027, ICAL_RANGE_THISANDFUTURE = 20028, ICAL_RANGE_NONE = 20029 } icalparameter_range; typedef enum icalparameter_related { ICAL_RELATED_X = 20030, ICAL_RELATED_START = 20031, - ICAL_RELATED_END = 20032, + ICAL_RELATED_END = 20032, ICAL_RELATED_NONE = 20033 } icalparameter_related; typedef enum icalparameter_reltype { ICAL_RELTYPE_X = 20034, ICAL_RELTYPE_PARENT = 20035, ICAL_RELTYPE_CHILD = 20036, ICAL_RELTYPE_SIBLING = 20037, ICAL_RELTYPE_NONE = 20038 } icalparameter_reltype; typedef enum icalparameter_role { ICAL_ROLE_X = 20039, ICAL_ROLE_CHAIR = 20040, ICAL_ROLE_REQPARTICIPANT = 20041, ICAL_ROLE_OPTPARTICIPANT = 20042, ICAL_ROLE_NONPARTICIPANT = 20043, ICAL_ROLE_NONE = 20044 } icalparameter_role; typedef enum icalparameter_rsvp { ICAL_RSVP_X = 20045, ICAL_RSVP_TRUE = 20046, ICAL_RSVP_FALSE = 20047, ICAL_RSVP_NONE = 20048 } icalparameter_rsvp; typedef enum icalparameter_value { ICAL_VALUE_X = 20049, ICAL_VALUE_BINARY = 20050, ICAL_VALUE_BOOLEAN = 20051, ICAL_VALUE_DATE = 20052, ICAL_VALUE_DURATION = 20053, ICAL_VALUE_FLOAT = 20054, ICAL_VALUE_INTEGER = 20055, ICAL_VALUE_PERIOD = 20056, ICAL_VALUE_RECUR = 20057, ICAL_VALUE_TEXT = 20058, ICAL_VALUE_URI = 20059, ICAL_VALUE_ERROR = 20060, ICAL_VALUE_DATETIME = 20061, ICAL_VALUE_UTCOFFSET = 20062, ICAL_VALUE_CALADDRESS = 20063, ICAL_VALUE_NONE = 20064 } icalparameter_value; typedef enum icalparameter_xliccomparetype { ICAL_XLICCOMPARETYPE_X = 20065, ICAL_XLICCOMPARETYPE_EQUAL = 20066, ICAL_XLICCOMPARETYPE_NOTEQUAL = 20067, ICAL_XLICCOMPARETYPE_LESS = 20068, ICAL_XLICCOMPARETYPE_GREATER = 20069, ICAL_XLICCOMPARETYPE_LESSEQUAL = 20070, ICAL_XLICCOMPARETYPE_GREATEREQUAL = 20071, ICAL_XLICCOMPARETYPE_REGEX = 20072, - ICAL_XLICCOMPARETYPE_NONE = 20073 + ICAL_XLICCOMPARETYPE_ISNULL = 20073, + ICAL_XLICCOMPARETYPE_ISNOTNULL = 20074, + ICAL_XLICCOMPARETYPE_NONE = 20075 } icalparameter_xliccomparetype; typedef enum icalparameter_xlicerrortype { - ICAL_XLICERRORTYPE_X = 20074, - ICAL_XLICERRORTYPE_COMPONENTPARSEERROR = 20075, - ICAL_XLICERRORTYPE_PROPERTYPARSEERROR = 20076, - ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR = 20077, - ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR = 20078, - ICAL_XLICERRORTYPE_VALUEPARSEERROR = 20079, - ICAL_XLICERRORTYPE_INVALIDITIP = 20080, - ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR = 20081, - ICAL_XLICERRORTYPE_MIMEPARSEERROR = 20082, - ICAL_XLICERRORTYPE_NONE = 20083 + ICAL_XLICERRORTYPE_X = 20076, + ICAL_XLICERRORTYPE_COMPONENTPARSEERROR = 20077, + ICAL_XLICERRORTYPE_PROPERTYPARSEERROR = 20078, + ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR = 20079, + ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR = 20080, + ICAL_XLICERRORTYPE_VALUEPARSEERROR = 20081, + ICAL_XLICERRORTYPE_INVALIDITIP = 20082, + ICAL_XLICERRORTYPE_UNKNOWNVCALPROPERROR = 20083, + ICAL_XLICERRORTYPE_MIMEPARSEERROR = 20084, + ICAL_XLICERRORTYPE_VCALPROPPARSEERROR = 20085, + ICAL_XLICERRORTYPE_NONE = 20086 } icalparameter_xlicerrortype; -#define ICALPARAMETER_LAST_ENUM 20084 - -/* DELEGATED-FROM */ -icalparameter* icalparameter_new_delegatedfrom(const char* v); -const char* icalparameter_get_delegatedfrom(icalparameter* value); -void icalparameter_set_delegatedfrom(icalparameter* value, const char* v); - -/* DELEGATED-TO */ -icalparameter* icalparameter_new_delegatedto(const char* v); -const char* icalparameter_get_delegatedto(icalparameter* value); -void icalparameter_set_delegatedto(icalparameter* value, const char* v); - -/* RANGE */ -icalparameter* icalparameter_new_range(icalparameter_range v); -icalparameter_range icalparameter_get_range(icalparameter* value); -void icalparameter_set_range(icalparameter* value, icalparameter_range v); +#define ICALPARAMETER_LAST_ENUM 20087 -/* ENCODING */ -icalparameter* icalparameter_new_encoding(icalparameter_encoding v); -icalparameter_encoding icalparameter_get_encoding(icalparameter* value); -void icalparameter_set_encoding(icalparameter* value, icalparameter_encoding v); - -/* RSVP */ -icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v); -icalparameter_rsvp icalparameter_get_rsvp(icalparameter* value); -void icalparameter_set_rsvp(icalparameter* value, icalparameter_rsvp v); +/* LANGUAGE */ +icalparameter* icalparameter_new_language(const char* v); +const char* icalparameter_get_language(const icalparameter* value); +void icalparameter_set_language(icalparameter* value, const char* v); -/* PARTSTAT */ -icalparameter* icalparameter_new_partstat(icalparameter_partstat v); -icalparameter_partstat icalparameter_get_partstat(icalparameter* value); -void icalparameter_set_partstat(icalparameter* value, icalparameter_partstat v); +/* DIR */ +icalparameter* icalparameter_new_dir(const char* v); +const char* icalparameter_get_dir(const icalparameter* value); +void icalparameter_set_dir(icalparameter* value, const char* v); /* RELTYPE */ icalparameter* icalparameter_new_reltype(icalparameter_reltype v); -icalparameter_reltype icalparameter_get_reltype(icalparameter* value); +icalparameter_reltype icalparameter_get_reltype(const icalparameter* value); void icalparameter_set_reltype(icalparameter* value, icalparameter_reltype v); -/* CUTYPE */ -icalparameter* icalparameter_new_cutype(icalparameter_cutype v); -icalparameter_cutype icalparameter_get_cutype(icalparameter* value); -void icalparameter_set_cutype(icalparameter* value, icalparameter_cutype v); - -/* MEMBER */ -icalparameter* icalparameter_new_member(const char* v); -const char* icalparameter_get_member(icalparameter* value); -void icalparameter_set_member(icalparameter* value, const char* v); - /* FMTTYPE */ icalparameter* icalparameter_new_fmttype(const char* v); -const char* icalparameter_get_fmttype(icalparameter* value); +const char* icalparameter_get_fmttype(const icalparameter* value); void icalparameter_set_fmttype(icalparameter* value, const char* v); -/* SENT-BY */ -icalparameter* icalparameter_new_sentby(const char* v); -const char* icalparameter_get_sentby(icalparameter* value); -void icalparameter_set_sentby(icalparameter* value, const char* v); +/* TZID */ +icalparameter* icalparameter_new_tzid(const char* v); +const char* icalparameter_get_tzid(const icalparameter* value); +void icalparameter_set_tzid(icalparameter* value, const char* v); + +/* RANGE */ +icalparameter* icalparameter_new_range(icalparameter_range v); +icalparameter_range icalparameter_get_range(const icalparameter* value); +void icalparameter_set_range(icalparameter* value, icalparameter_range v); + +/* DELEGATED-TO */ +icalparameter* icalparameter_new_delegatedto(const char* v); +const char* icalparameter_get_delegatedto(const icalparameter* value); +void icalparameter_set_delegatedto(icalparameter* value, const char* v); + +/* CN */ +icalparameter* icalparameter_new_cn(const char* v); +const char* icalparameter_get_cn(const icalparameter* value); +void icalparameter_set_cn(icalparameter* value, const char* v); /* VALUE */ icalparameter* icalparameter_new_value(icalparameter_value v); -icalparameter_value icalparameter_get_value(icalparameter* value); +icalparameter_value icalparameter_get_value(const icalparameter* value); void icalparameter_set_value(icalparameter* value, icalparameter_value v); -/* ALTREP */ -icalparameter* icalparameter_new_altrep(const char* v); -const char* icalparameter_get_altrep(icalparameter* value); -void icalparameter_set_altrep(icalparameter* value, const char* v); +/* X-LIC-COMPARETYPE */ +icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v); +icalparameter_xliccomparetype icalparameter_get_xliccomparetype(const icalparameter* value); +void icalparameter_set_xliccomparetype(icalparameter* value, icalparameter_xliccomparetype v); -/* DIR */ -icalparameter* icalparameter_new_dir(const char* v); -const char* icalparameter_get_dir(icalparameter* value); -void icalparameter_set_dir(icalparameter* value, const char* v); +/* X */ +icalparameter* icalparameter_new_x(const char* v); +const char* icalparameter_get_x(const icalparameter* value); +void icalparameter_set_x(icalparameter* value, const char* v); -/* RELATED */ -icalparameter* icalparameter_new_related(icalparameter_related v); -icalparameter_related icalparameter_get_related(icalparameter* value); -void icalparameter_set_related(icalparameter* value, icalparameter_related v); +/* SENT-BY */ +icalparameter* icalparameter_new_sentby(const char* v); +const char* icalparameter_get_sentby(const icalparameter* value); +void icalparameter_set_sentby(icalparameter* value, const char* v); -/* CN */ -icalparameter* icalparameter_new_cn(const char* v); -const char* icalparameter_get_cn(icalparameter* value); -void icalparameter_set_cn(icalparameter* value, const char* v); +/* MEMBER */ +icalparameter* icalparameter_new_member(const char* v); +const char* icalparameter_get_member(const icalparameter* value); +void icalparameter_set_member(icalparameter* value, const char* v); + +/* RSVP */ +icalparameter* icalparameter_new_rsvp(icalparameter_rsvp v); +icalparameter_rsvp icalparameter_get_rsvp(const icalparameter* value); +void icalparameter_set_rsvp(icalparameter* value, icalparameter_rsvp v); + +/* CUTYPE */ +icalparameter* icalparameter_new_cutype(icalparameter_cutype v); +icalparameter_cutype icalparameter_get_cutype(const icalparameter* value); +void icalparameter_set_cutype(icalparameter* value, icalparameter_cutype v); /* X-LIC-ERRORTYPE */ icalparameter* icalparameter_new_xlicerrortype(icalparameter_xlicerrortype v); -icalparameter_xlicerrortype icalparameter_get_xlicerrortype(icalparameter* value); +icalparameter_xlicerrortype icalparameter_get_xlicerrortype(const icalparameter* value); void icalparameter_set_xlicerrortype(icalparameter* value, icalparameter_xlicerrortype v); -/* X */ -icalparameter* icalparameter_new_x(const char* v); -const char* icalparameter_get_x(icalparameter* value); -void icalparameter_set_x(icalparameter* value, const char* v); +/* RELATED */ +icalparameter* icalparameter_new_related(icalparameter_related v); +icalparameter_related icalparameter_get_related(const icalparameter* value); +void icalparameter_set_related(icalparameter* value, icalparameter_related v); -/* LANGUAGE */ -icalparameter* icalparameter_new_language(const char* v); -const char* icalparameter_get_language(icalparameter* value); -void icalparameter_set_language(icalparameter* value, const char* v); +/* ENCODING */ +icalparameter* icalparameter_new_encoding(icalparameter_encoding v); +icalparameter_encoding icalparameter_get_encoding(const icalparameter* value); +void icalparameter_set_encoding(icalparameter* value, icalparameter_encoding v); -/* ROLE */ -icalparameter* icalparameter_new_role(icalparameter_role v); -icalparameter_role icalparameter_get_role(icalparameter* value); -void icalparameter_set_role(icalparameter* value, icalparameter_role v); +/* ALTREP */ +icalparameter* icalparameter_new_altrep(const char* v); +const char* icalparameter_get_altrep(const icalparameter* value); +void icalparameter_set_altrep(icalparameter* value, const char* v); -/* X-LIC-COMPARETYPE */ -icalparameter* icalparameter_new_xliccomparetype(icalparameter_xliccomparetype v); -icalparameter_xliccomparetype icalparameter_get_xliccomparetype(icalparameter* value); -void icalparameter_set_xliccomparetype(icalparameter* value, icalparameter_xliccomparetype v); +/* DELEGATED-FROM */ +icalparameter* icalparameter_new_delegatedfrom(const char* v); +const char* icalparameter_get_delegatedfrom(const icalparameter* value); +void icalparameter_set_delegatedfrom(icalparameter* value, const char* v); /* FBTYPE */ icalparameter* icalparameter_new_fbtype(icalparameter_fbtype v); -icalparameter_fbtype icalparameter_get_fbtype(icalparameter* value); +icalparameter_fbtype icalparameter_get_fbtype(const icalparameter* value); void icalparameter_set_fbtype(icalparameter* value, icalparameter_fbtype v); -/* TZID */ -icalparameter* icalparameter_new_tzid(const char* v); -const char* icalparameter_get_tzid(icalparameter* value); -void icalparameter_set_tzid(icalparameter* value, const char* v); +/* ROLE */ +icalparameter* icalparameter_new_role(icalparameter_role v); +icalparameter_role icalparameter_get_role(const icalparameter* value); +void icalparameter_set_role(icalparameter* value, icalparameter_role v); + +/* PARTSTAT */ +icalparameter* icalparameter_new_partstat(icalparameter_partstat v); +icalparameter_partstat icalparameter_get_partstat(const icalparameter* value); +void icalparameter_set_partstat(icalparameter* value, icalparameter_partstat v); #endif /*ICALPARAMETER_H*/ +/* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icalderivedproperty.c b/libical/src/libical/icalderivedproperty.c index b41562b..362bfbe 100644 --- a/libical/src/libical/icalderivedproperty.c +++ b/libical/src/libical/icalderivedproperty.c @@ -1,2014 +1,2514 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalderivedproperty.c CREATOR: eric 15 Feb 2001 $Id$ (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 icalproperty.c ======================================================================*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalproperty.h" #include "icalcomponent.h" #include "pvl.h" #include "icalenums.h" #include "icalerror.h" #include "icalmemory.h" #include "icalparser.h" #include <string.h> /* For icalmemory_strdup, rindex */ #include <assert.h> #include <stdlib.h> #include <errno.h> #include <stdio.h> /* for printf */ #include <stdarg.h> /* for va_list, va_start, etc. */ -#define TMP_BUF_SIZE 1024 - struct icalproperty_impl* icalproperty_new_impl (icalproperty_kind kind); +void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args); /* This map associates the property kinds with the string representation of the property name and the kind of VALUE that the property uses as a default */ struct icalproperty_map { icalproperty_kind kind; const char *name; icalvalue_kind value; }; -extern struct icalproperty_map property_map[]; -extern void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args); -const char* icalproperty_kind_to_string(icalproperty_kind kind) -{ - int i; - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if (property_map[i].kind == kind) { - return property_map[i].name; - } - } - - return 0; - -} - - -icalproperty_kind icalproperty_string_to_kind(const char* string) -{ - int i; - - if (string ==0 ) { - return ICAL_NO_PROPERTY; - } - - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if (strcmp(property_map[i].name, string) == 0) { - return property_map[i].kind; - } - } - - if(strncmp(string,"X-",2)==0){ - return ICAL_X_PROPERTY; - } - - - return ICAL_NO_PROPERTY; -} - - -icalvalue_kind icalproperty_value_kind_to_kind(icalvalue_kind kind) -{ - int i; - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if ( property_map[i].value == kind ) { - return property_map[i].kind; - } - } - - return ICAL_NO_VALUE; -} - - - -icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind) -{ - int i; - - for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { - if ( property_map[i].kind == kind ) { - return property_map[i].value; - } - } - - return ICAL_NO_VALUE; -} - - /* This map associates the property enumerations with the king of property that they are used in and the string representation of the enumeration */ struct icalproperty_enum_map { icalproperty_kind prop; int prop_enum; const char* str; }; -extern struct icalproperty_enum_map enum_map[]; - - -const char* icalproperty_enum_to_string(int e) -{ - icalerror_check_arg_rz(e >= ICALPROPERTY_FIRST_ENUM,"e"); - icalerror_check_arg_rz(e <= ICALPROPERTY_LAST_ENUM,"e"); - - return enum_map[e-ICALPROPERTY_FIRST_ENUM].str; -} - -int icalproperty_string_to_enum(const char* str) -{ - int i; - - icalerror_check_arg_rz(str!=0,"str") - - while(*str == ' '){ - str++; - } - - for (i=ICALPROPERTY_FIRST_ENUM; i != ICALPROPERTY_LAST_ENUM; i++) { - if ( strcmp(enum_map[i-ICALPROPERTY_FIRST_ENUM].str, str) == 0) { - return enum_map[i-ICALPROPERTY_FIRST_ENUM].prop_enum; - } - } - - return 0; -} - -int icalproperty_enum_belongs_to_property(icalproperty_kind kind, int e) -{ - int i; - - - for (i=ICALPROPERTY_FIRST_ENUM; i != ICALPROPERTY_LAST_ENUM; i++) { - if(enum_map[i-ICALPROPERTY_FIRST_ENUM].prop_enum == e && - enum_map[i-ICALPROPERTY_FIRST_ENUM].prop == kind ){ - return 1; - } - } - - return 0; -} - - -const char* icalproperty_method_to_string(icalproperty_method method) -{ - icalerror_check_arg_rz(method >= ICAL_METHOD_X,"method"); - icalerror_check_arg_rz(method <= ICAL_METHOD_NONE,"method"); - - return enum_map[method-ICALPROPERTY_FIRST_ENUM].str; -} - -icalproperty_method icalproperty_string_to_method(const char* str) -{ - int i; - - icalerror_check_arg_rx(str!=0,"str",ICAL_METHOD_NONE) - - while(*str == ' '){ - str++; - } - - for (i=ICAL_METHOD_X-ICALPROPERTY_FIRST_ENUM; - i != ICAL_METHOD_NONE-ICALPROPERTY_FIRST_ENUM; - i++) { - if ( strcmp(enum_map[i].str, str) == 0) { - return (icalproperty_method)enum_map[i].prop_enum; - } - } - - return ICAL_METHOD_NONE; -} - - -const char* icalenum_status_to_string(icalproperty_status status) -{ - icalerror_check_arg_rz(status >= ICAL_STATUS_X,"status"); - icalerror_check_arg_rz(status <= ICAL_STATUS_NONE,"status"); - - return enum_map[status-ICALPROPERTY_FIRST_ENUM].str; -} - -icalproperty_status icalenum_string_to_status(const char* str) -{ - int i; - - icalerror_check_arg_rx(str!=0,"str",ICAL_STATUS_NONE) - - while(*str == ' '){ - str++; - } - - for (i=ICAL_STATUS_X-ICALPROPERTY_FIRST_ENUM; - i != ICAL_STATUS_NONE-ICALPROPERTY_FIRST_ENUM; - i++) { - if ( strcmp(enum_map[i].str, str) == 0) { - return (icalproperty_method)enum_map[i].prop_enum; - } - } - - return ICAL_STATUS_NONE; - -} - - -/* Everything below this line is machine generated. Do not edit. */ -static struct icalproperty_map property_map[] = { +static struct icalproperty_map property_map[77] = { {ICAL_ACTION_PROPERTY,"ACTION",ICAL_ACTION_VALUE}, +{ICAL_ALLOWCONFLICT_PROPERTY,"ALLOW-CONFLICT",ICAL_TEXT_VALUE}, {ICAL_ANY_PROPERTY,"ANY",ICAL_NO_VALUE}, {ICAL_ATTACH_PROPERTY,"ATTACH",ICAL_ATTACH_VALUE}, {ICAL_ATTENDEE_PROPERTY,"ATTENDEE",ICAL_CALADDRESS_VALUE}, +{ICAL_CALID_PROPERTY,"CALID",ICAL_TEXT_VALUE}, +{ICAL_CALMASTER_PROPERTY,"CALMASTER",ICAL_TEXT_VALUE}, {ICAL_CALSCALE_PROPERTY,"CALSCALE",ICAL_TEXT_VALUE}, +{ICAL_CARID_PROPERTY,"CARID",ICAL_TEXT_VALUE}, {ICAL_CATEGORIES_PROPERTY,"CATEGORIES",ICAL_TEXT_VALUE}, -{ICAL_CLASS_PROPERTY,"CLASS",ICAL_TEXT_VALUE}, +{ICAL_CLASS_PROPERTY,"CLASS",ICAL_CLASS_VALUE}, {ICAL_COMMENT_PROPERTY,"COMMENT",ICAL_TEXT_VALUE}, {ICAL_COMPLETED_PROPERTY,"COMPLETED",ICAL_DATETIME_VALUE}, {ICAL_CONTACT_PROPERTY,"CONTACT",ICAL_TEXT_VALUE}, {ICAL_CREATED_PROPERTY,"CREATED",ICAL_DATETIME_VALUE}, +{ICAL_DECREED_PROPERTY,"DECREED",ICAL_TEXT_VALUE}, +{ICAL_DEFAULTCHARSET_PROPERTY,"DEFAULT-CHARSET",ICAL_TEXT_VALUE}, +{ICAL_DEFAULTLOCALE_PROPERTY,"DEFAULT-LOCALE",ICAL_TEXT_VALUE}, +{ICAL_DEFAULTTZID_PROPERTY,"DEFAULT-TZID",ICAL_TEXT_VALUE}, {ICAL_DESCRIPTION_PROPERTY,"DESCRIPTION",ICAL_TEXT_VALUE}, {ICAL_DTEND_PROPERTY,"DTEND",ICAL_DATETIME_VALUE}, {ICAL_DTSTAMP_PROPERTY,"DTSTAMP",ICAL_DATETIME_VALUE}, {ICAL_DTSTART_PROPERTY,"DTSTART",ICAL_DATETIME_VALUE}, {ICAL_DUE_PROPERTY,"DUE",ICAL_DATETIME_VALUE}, {ICAL_DURATION_PROPERTY,"DURATION",ICAL_DURATION_VALUE}, {ICAL_EXDATE_PROPERTY,"EXDATE",ICAL_DATETIME_VALUE}, +{ICAL_EXPAND_PROPERTY,"EXPAND",ICAL_INTEGER_VALUE}, {ICAL_EXRULE_PROPERTY,"EXRULE",ICAL_RECUR_VALUE}, {ICAL_FREEBUSY_PROPERTY,"FREEBUSY",ICAL_PERIOD_VALUE}, {ICAL_GEO_PROPERTY,"GEO",ICAL_GEO_VALUE}, {ICAL_LASTMODIFIED_PROPERTY,"LAST-MODIFIED",ICAL_DATETIME_VALUE}, {ICAL_LOCATION_PROPERTY,"LOCATION",ICAL_TEXT_VALUE}, {ICAL_MAXRESULTS_PROPERTY,"MAXRESULTS",ICAL_INTEGER_VALUE}, {ICAL_MAXRESULTSSIZE_PROPERTY,"MAXRESULTSSIZE",ICAL_INTEGER_VALUE}, {ICAL_METHOD_PROPERTY,"METHOD",ICAL_METHOD_VALUE}, {ICAL_ORGANIZER_PROPERTY,"ORGANIZER",ICAL_CALADDRESS_VALUE}, +{ICAL_OWNER_PROPERTY,"OWNER",ICAL_TEXT_VALUE}, {ICAL_PERCENTCOMPLETE_PROPERTY,"PERCENT-COMPLETE",ICAL_INTEGER_VALUE}, {ICAL_PRIORITY_PROPERTY,"PRIORITY",ICAL_INTEGER_VALUE}, {ICAL_PRODID_PROPERTY,"PRODID",ICAL_TEXT_VALUE}, {ICAL_QUERY_PROPERTY,"QUERY",ICAL_QUERY_VALUE}, {ICAL_QUERYNAME_PROPERTY,"QUERYNAME",ICAL_TEXT_VALUE}, {ICAL_RDATE_PROPERTY,"RDATE",ICAL_DATETIMEPERIOD_VALUE}, {ICAL_RECURRENCEID_PROPERTY,"RECURRENCE-ID",ICAL_DATETIME_VALUE}, {ICAL_RELATEDTO_PROPERTY,"RELATED-TO",ICAL_TEXT_VALUE}, +{ICAL_RELCALID_PROPERTY,"RELCALID",ICAL_TEXT_VALUE}, {ICAL_REPEAT_PROPERTY,"REPEAT",ICAL_INTEGER_VALUE}, {ICAL_REQUESTSTATUS_PROPERTY,"REQUEST-STATUS",ICAL_REQUESTSTATUS_VALUE}, {ICAL_RESOURCES_PROPERTY,"RESOURCES",ICAL_TEXT_VALUE}, {ICAL_RRULE_PROPERTY,"RRULE",ICAL_RECUR_VALUE}, {ICAL_SCOPE_PROPERTY,"SCOPE",ICAL_TEXT_VALUE}, {ICAL_SEQUENCE_PROPERTY,"SEQUENCE",ICAL_INTEGER_VALUE}, {ICAL_STATUS_PROPERTY,"STATUS",ICAL_STATUS_VALUE}, {ICAL_SUMMARY_PROPERTY,"SUMMARY",ICAL_TEXT_VALUE}, {ICAL_TARGET_PROPERTY,"TARGET",ICAL_CALADDRESS_VALUE}, -{ICAL_TRANSP_PROPERTY,"TRANSP",ICAL_TEXT_VALUE}, +{ICAL_TRANSP_PROPERTY,"TRANSP",ICAL_TRANSP_VALUE}, {ICAL_TRIGGER_PROPERTY,"TRIGGER",ICAL_TRIGGER_VALUE}, {ICAL_TZID_PROPERTY,"TZID",ICAL_TEXT_VALUE}, {ICAL_TZNAME_PROPERTY,"TZNAME",ICAL_TEXT_VALUE}, {ICAL_TZOFFSETFROM_PROPERTY,"TZOFFSETFROM",ICAL_UTCOFFSET_VALUE}, {ICAL_TZOFFSETTO_PROPERTY,"TZOFFSETTO",ICAL_UTCOFFSET_VALUE}, {ICAL_TZURL_PROPERTY,"TZURL",ICAL_URI_VALUE}, {ICAL_UID_PROPERTY,"UID",ICAL_TEXT_VALUE}, {ICAL_URL_PROPERTY,"URL",ICAL_URI_VALUE}, {ICAL_VERSION_PROPERTY,"VERSION",ICAL_TEXT_VALUE}, -{ICAL_X_PROPERTY,"X",ICAL_TEXT_VALUE}, +{ICAL_X_PROPERTY,"X",ICAL_X_VALUE}, +{ICAL_XLICCLASS_PROPERTY,"X-LIC-CLASS",ICAL_XLICCLASS_VALUE}, {ICAL_XLICCLUSTERCOUNT_PROPERTY,"X-LIC-CLUSTERCOUNT",ICAL_STRING_VALUE}, {ICAL_XLICERROR_PROPERTY,"X-LIC-ERROR",ICAL_TEXT_VALUE}, {ICAL_XLICMIMECHARSET_PROPERTY,"X-LIC-MIMECHARSET",ICAL_STRING_VALUE}, {ICAL_XLICMIMECID_PROPERTY,"X-LIC-MIMECID",ICAL_STRING_VALUE}, {ICAL_XLICMIMECONTENTTYPE_PROPERTY,"X-LIC-MIMECONTENTTYPE",ICAL_STRING_VALUE}, {ICAL_XLICMIMEENCODING_PROPERTY,"X-LIC-MIMEENCODING",ICAL_STRING_VALUE}, {ICAL_XLICMIMEFILENAME_PROPERTY,"X-LIC-MIMEFILENAME",ICAL_STRING_VALUE}, {ICAL_XLICMIMEOPTINFO_PROPERTY,"X-LIC-MIMEOPTINFO",ICAL_STRING_VALUE}, {ICAL_NO_PROPERTY,"",ICAL_NO_VALUE}}; -static struct icalproperty_enum_map enum_map[] = { +static struct icalproperty_enum_map enum_map[75] = { {ICAL_ACTION_PROPERTY,ICAL_ACTION_X,"" }, /*10000*/ {ICAL_ACTION_PROPERTY,ICAL_ACTION_AUDIO,"AUDIO" }, /*10001*/ {ICAL_ACTION_PROPERTY,ICAL_ACTION_DISPLAY,"DISPLAY" }, /*10002*/ {ICAL_ACTION_PROPERTY,ICAL_ACTION_EMAIL,"EMAIL" }, /*10003*/ {ICAL_ACTION_PROPERTY,ICAL_ACTION_PROCEDURE,"PROCEDURE" }, /*10004*/ {ICAL_ACTION_PROPERTY,ICAL_ACTION_NONE,"" }, /*10005*/ {ICAL_CLASS_PROPERTY,ICAL_CLASS_X,"" }, /*10006*/ {ICAL_CLASS_PROPERTY,ICAL_CLASS_PUBLIC,"PUBLIC" }, /*10007*/ {ICAL_CLASS_PROPERTY,ICAL_CLASS_PRIVATE,"PRIVATE" }, /*10008*/ {ICAL_CLASS_PROPERTY,ICAL_CLASS_CONFIDENTIAL,"CONFIDENTIAL" }, /*10009*/ {ICAL_CLASS_PROPERTY,ICAL_CLASS_NONE,"" }, /*10010*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_X,"" }, /*10011*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_PUBLISH,"PUBLISH" }, /*10012*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_REQUEST,"REQUEST" }, /*10013*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_REPLY,"REPLY" }, /*10014*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_ADD,"ADD" }, /*10015*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_CANCEL,"CANCEL" }, /*10016*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_REFRESH,"REFRESH" }, /*10017*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_COUNTER,"COUNTER" }, /*10018*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_DECLINECOUNTER,"DECLINECOUNTER" }, /*10019*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_CREATE,"CREATE" }, /*10020*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_READ,"READ" }, /*10021*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_RESPONSE,"RESPONSE" }, /*10022*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_MOVE,"MOVE" }, /*10023*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_MODIFY,"MODIFY" }, /*10024*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_GENERATEUID,"GENERATEUID" }, /*10025*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_DELETE,"DELETE" }, /*10026*/ {ICAL_METHOD_PROPERTY,ICAL_METHOD_NONE,"" }, /*10027*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_X,"" }, /*10028*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_TENTATIVE,"TENTATIVE" }, /*10029*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_CONFIRMED,"CONFIRMED" }, /*10030*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_COMPLETED,"COMPLETED" }, /*10031*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_NEEDSACTION,"NEEDS-ACTION" }, /*10032*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_CANCELLED,"CANCELLED" }, /*10033*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_INPROCESS,"IN-PROCESS" }, /*10034*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_DRAFT,"DRAFT" }, /*10035*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_FINAL,"FINAL" }, /*10036*/ {ICAL_STATUS_PROPERTY,ICAL_STATUS_NONE,"" }, /*10037*/ {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_X,"" }, /*10038*/ {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_OPAQUE,"OPAQUE" }, /*10039*/ - {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_TRANSPARENT,"TRANSPARENT" }, /*10040*/ - {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_NONE,"" }, /*10041*/ + {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_OPAQUENOCONFLICT,"OPAQUE-NOCONFLICT" }, /*10040*/ + {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_TRANSPARENT,"TRANSPARENT" }, /*10041*/ + {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_TRANSPARENTNOCONFLICT,"TRANSPARENT-NOCONFLICT" }, /*10042*/ + {ICAL_TRANSP_PROPERTY,ICAL_TRANSP_NONE,"" }, /*10043*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_X,"" }, /*10044*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_PUBLISHNEW,"PUBLISH-NEW" }, /*10045*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_PUBLISHUPDATE,"PUBLISH-UPDATE" }, /*10046*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_PUBLISHFREEBUSY,"PUBLISH-FREEBUSY" }, /*10047*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTNEW,"REQUEST-NEW" }, /*10048*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTUPDATE,"REQUEST-UPDATE" }, /*10049*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTRESCHEDULE,"REQUEST-RESCHEDULE" }, /*10050*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTDELEGATE,"REQUEST-DELEGATE" }, /*10051*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTNEWORGANIZER,"REQUEST-NEW-ORGANIZER" }, /*10052*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTFORWARD,"REQUEST-FORWARD" }, /*10053*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTSTATUS,"REQUEST-STATUS" }, /*10054*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REQUESTFREEBUSY,"REQUEST-FREEBUSY" }, /*10055*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REPLYACCEPT,"REPLY-ACCEPT" }, /*10056*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REPLYDECLINE,"REPLY-DECLINE" }, /*10057*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REPLYDELEGATE,"REPLY-DELEGATE" }, /*10058*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REPLYCRASHERACCEPT,"REPLY-CRASHER-ACCEPT" }, /*10059*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REPLYCRASHERDECLINE,"REPLY-CRASHER-DECLINE" }, /*10060*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_ADDINSTANCE,"ADD-INSTANCE" }, /*10061*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_CANCELEVENT,"CANCEL-EVENT" }, /*10062*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_CANCELINSTANCE,"CANCEL-INSTANCE" }, /*10063*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_CANCELALL,"CANCEL-ALL" }, /*10064*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_REFRESH,"REFRESH" }, /*10065*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_COUNTER,"COUNTER" }, /*10066*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_DECLINECOUNTER,"DECLINECOUNTER" }, /*10067*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_MALFORMED,"MALFORMED" }, /*10068*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_OBSOLETE,"OBSOLETE" }, /*10069*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_MISSEQUENCED,"MISSEQUENCED" }, /*10070*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_UNKNOWN,"UNKNOWN" }, /*10071*/ + {ICAL_XLICCLASS_PROPERTY,ICAL_XLICCLASS_NONE,"" }, /*10072*/ {ICAL_NO_PROPERTY,0,""} }; icalproperty* icalproperty_vanew_action(enum icalproperty_action v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ACTION_PROPERTY); icalproperty_set_action((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* ACTION */ icalproperty* icalproperty_new_action(enum icalproperty_action v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ACTION_PROPERTY); icalproperty_set_action((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_action(icalproperty* prop, enum icalproperty_action v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_action(v)); } -enum icalproperty_action icalproperty_get_action(icalproperty* prop){ +enum icalproperty_action icalproperty_get_action(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_action(icalproperty_get_value(prop)); } -icalproperty* icalproperty_vanew_attach(struct icalattachtype* v, ...){ +icalproperty* icalproperty_vanew_allowconflict(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ALLOWCONFLICT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_allowconflict((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* ALLOW-CONFLICT */ +icalproperty* icalproperty_new_allowconflict(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ALLOWCONFLICT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_allowconflict((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_allowconflict(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_allowconflict(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_attach(icalattach * v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ATTACH_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_attach((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* ATTACH */ -icalproperty* icalproperty_new_attach(struct icalattachtype* v) { +icalproperty* icalproperty_new_attach(icalattach * v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ATTACH_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_attach((icalproperty*)impl,v); return (icalproperty*)impl; } -void icalproperty_set_attach(icalproperty* prop, struct icalattachtype* v){ +void icalproperty_set_attach(icalproperty* prop, icalattach * v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_attach(v)); } -struct icalattachtype* icalproperty_get_attach(icalproperty* prop){ +icalattach * icalproperty_get_attach(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_attach(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_attendee(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ATTENDEE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_attendee((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* ATTENDEE */ icalproperty* icalproperty_new_attendee(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ATTENDEE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_attendee((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_attendee(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_caladdress(v)); } -const char* icalproperty_get_attendee(icalproperty* prop){ +const char* icalproperty_get_attendee(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_caladdress(icalproperty_get_value(prop)); } +icalproperty* icalproperty_vanew_calid(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_calid((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* CALID */ +icalproperty* icalproperty_new_calid(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_calid((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_calid(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_calid(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_calmaster(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALMASTER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_calmaster((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* CALMASTER */ +icalproperty* icalproperty_new_calmaster(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALMASTER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_calmaster((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_calmaster(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_calmaster(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} icalproperty* icalproperty_vanew_calscale(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALSCALE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_calscale((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* CALSCALE */ icalproperty* icalproperty_new_calscale(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CALSCALE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_calscale((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_calscale(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_calscale(icalproperty* prop){ +const char* icalproperty_get_calscale(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_carid(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CARID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_carid((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* CARID */ +icalproperty* icalproperty_new_carid(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CARID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_carid((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_carid(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_carid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_categories(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CATEGORIES_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_categories((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* CATEGORIES */ icalproperty* icalproperty_new_categories(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CATEGORIES_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_categories((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_categories(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_categories(icalproperty* prop){ +const char* icalproperty_get_categories(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } -icalproperty* icalproperty_vanew_class(const char* v, ...){ +icalproperty* icalproperty_vanew_class(enum icalproperty_class v, ...){ va_list args; - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CLASS_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); - + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CLASS_PROPERTY); icalproperty_set_class((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } -/* CLASS */ -icalproperty* icalproperty_new_class(const char* v) { - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CLASS_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); +/* CLASS */ +icalproperty* icalproperty_new_class(enum icalproperty_class v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CLASS_PROPERTY); icalproperty_set_class((icalproperty*)impl,v); return (icalproperty*)impl; } -void icalproperty_set_class(icalproperty* prop, const char* v){ - icalerror_check_arg_rv( (v!=0),"v"); - +void icalproperty_set_class(icalproperty* prop, enum icalproperty_class v){ + icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_text(v)); + icalproperty_set_value(prop,icalvalue_new_class(v)); } -const char* icalproperty_get_class(icalproperty* prop){ +enum icalproperty_class icalproperty_get_class(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); - return icalvalue_get_text(icalproperty_get_value(prop)); + return icalvalue_get_class(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_comment(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_COMMENT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_comment((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* COMMENT */ icalproperty* icalproperty_new_comment(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_COMMENT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_comment((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_comment(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_comment(icalproperty* prop){ +const char* icalproperty_get_comment(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_completed(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_COMPLETED_PROPERTY); icalproperty_set_completed((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* COMPLETED */ icalproperty* icalproperty_new_completed(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_COMPLETED_PROPERTY); icalproperty_set_completed((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_completed(icalproperty* prop, struct icaltimetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_datetime(v)); } -struct icaltimetype icalproperty_get_completed(icalproperty* prop){ +struct icaltimetype icalproperty_get_completed(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_contact(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CONTACT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_contact((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* CONTACT */ icalproperty* icalproperty_new_contact(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CONTACT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_contact((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_contact(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_contact(icalproperty* prop){ +const char* icalproperty_get_contact(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_created(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CREATED_PROPERTY); icalproperty_set_created((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* CREATED */ icalproperty* icalproperty_new_created(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_CREATED_PROPERTY); icalproperty_set_created((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_created(icalproperty* prop, struct icaltimetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_datetime(v)); } -struct icaltimetype icalproperty_get_created(icalproperty* prop){ +struct icaltimetype icalproperty_get_created(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } +icalproperty* icalproperty_vanew_decreed(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DECREED_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_decreed((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* DECREED */ +icalproperty* icalproperty_new_decreed(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DECREED_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_decreed((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_decreed(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_decreed(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_defaultcharset(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTCHARSET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaultcharset((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* DEFAULT-CHARSET */ +icalproperty* icalproperty_new_defaultcharset(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTCHARSET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaultcharset((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_defaultcharset(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_defaultcharset(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_defaultlocale(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTLOCALE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaultlocale((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* DEFAULT-LOCALE */ +icalproperty* icalproperty_new_defaultlocale(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTLOCALE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaultlocale((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_defaultlocale(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_defaultlocale(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_defaulttzid(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTTZID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaulttzid((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* DEFAULT-TZID */ +icalproperty* icalproperty_new_defaulttzid(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DEFAULTTZID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_defaulttzid((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_defaulttzid(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_defaulttzid(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} icalproperty* icalproperty_vanew_description(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DESCRIPTION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_description((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DESCRIPTION */ icalproperty* icalproperty_new_description(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DESCRIPTION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_description((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_description(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_description(icalproperty* prop){ +const char* icalproperty_get_description(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_dtend(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTEND_PROPERTY); icalproperty_set_dtend((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DTEND */ icalproperty* icalproperty_new_dtend(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTEND_PROPERTY); icalproperty_set_dtend((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_dtend(icalproperty* prop, struct icaltimetype v){ + icalvalue *value; icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_datetime(v)); + if (v.is_date) + value = icalvalue_new_date(v); + else + value = icalvalue_new_datetime(v); + icalproperty_set_value(prop,value); } -struct icaltimetype icalproperty_get_dtend(icalproperty* prop){ +struct icaltimetype icalproperty_get_dtend(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_dtstamp(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTSTAMP_PROPERTY); icalproperty_set_dtstamp((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DTSTAMP */ icalproperty* icalproperty_new_dtstamp(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTSTAMP_PROPERTY); icalproperty_set_dtstamp((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_dtstamp(icalproperty* prop, struct icaltimetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_datetime(v)); } -struct icaltimetype icalproperty_get_dtstamp(icalproperty* prop){ +struct icaltimetype icalproperty_get_dtstamp(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_dtstart(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTSTART_PROPERTY); icalproperty_set_dtstart((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DTSTART */ icalproperty* icalproperty_new_dtstart(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DTSTART_PROPERTY); icalproperty_set_dtstart((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_dtstart(icalproperty* prop, struct icaltimetype v){ + icalvalue *value; icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_datetime(v)); + if (v.is_date) + value = icalvalue_new_date(v); + else + value = icalvalue_new_datetime(v); + icalproperty_set_value(prop,value); } -struct icaltimetype icalproperty_get_dtstart(icalproperty* prop){ +struct icaltimetype icalproperty_get_dtstart(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_due(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DUE_PROPERTY); icalproperty_set_due((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DUE */ icalproperty* icalproperty_new_due(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DUE_PROPERTY); icalproperty_set_due((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_due(icalproperty* prop, struct icaltimetype v){ + icalvalue *value; icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_datetime(v)); + if (v.is_date) + value = icalvalue_new_date(v); + else + value = icalvalue_new_datetime(v); + icalproperty_set_value(prop,value); } -struct icaltimetype icalproperty_get_due(icalproperty* prop){ +struct icaltimetype icalproperty_get_due(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_duration(struct icaldurationtype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DURATION_PROPERTY); icalproperty_set_duration((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* DURATION */ icalproperty* icalproperty_new_duration(struct icaldurationtype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_DURATION_PROPERTY); icalproperty_set_duration((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_duration(icalproperty* prop, struct icaldurationtype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_duration(v)); } -struct icaldurationtype icalproperty_get_duration(icalproperty* prop){ +struct icaldurationtype icalproperty_get_duration(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_duration(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_exdate(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXDATE_PROPERTY); icalproperty_set_exdate((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* EXDATE */ icalproperty* icalproperty_new_exdate(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXDATE_PROPERTY); icalproperty_set_exdate((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_exdate(icalproperty* prop, struct icaltimetype v){ + icalvalue *value; icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_datetime(v)); + if (v.is_date) + value = icalvalue_new_date(v); + else + value = icalvalue_new_datetime(v); + icalproperty_set_value(prop,value); } -struct icaltimetype icalproperty_get_exdate(icalproperty* prop){ +struct icaltimetype icalproperty_get_exdate(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } +icalproperty* icalproperty_vanew_expand(int v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXPAND_PROPERTY); + icalproperty_set_expand((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* EXPAND */ +icalproperty* icalproperty_new_expand(int v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXPAND_PROPERTY); + icalproperty_set_expand((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_expand(icalproperty* prop, int v){ + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_integer(v)); +} +int icalproperty_get_expand(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_integer(icalproperty_get_value(prop)); +} icalproperty* icalproperty_vanew_exrule(struct icalrecurrencetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXRULE_PROPERTY); icalproperty_set_exrule((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* EXRULE */ icalproperty* icalproperty_new_exrule(struct icalrecurrencetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_EXRULE_PROPERTY); icalproperty_set_exrule((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_exrule(icalproperty* prop, struct icalrecurrencetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_recur(v)); } -struct icalrecurrencetype icalproperty_get_exrule(icalproperty* prop){ +struct icalrecurrencetype icalproperty_get_exrule(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_recur(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_freebusy(struct icalperiodtype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_FREEBUSY_PROPERTY); icalproperty_set_freebusy((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* FREEBUSY */ icalproperty* icalproperty_new_freebusy(struct icalperiodtype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_FREEBUSY_PROPERTY); icalproperty_set_freebusy((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_freebusy(icalproperty* prop, struct icalperiodtype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_period(v)); } -struct icalperiodtype icalproperty_get_freebusy(icalproperty* prop){ +struct icalperiodtype icalproperty_get_freebusy(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_period(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_geo(struct icalgeotype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_GEO_PROPERTY); icalproperty_set_geo((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* GEO */ icalproperty* icalproperty_new_geo(struct icalgeotype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_GEO_PROPERTY); icalproperty_set_geo((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_geo(icalproperty* prop, struct icalgeotype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_geo(v)); } -struct icalgeotype icalproperty_get_geo(icalproperty* prop){ +struct icalgeotype icalproperty_get_geo(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_geo(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_lastmodified(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_LASTMODIFIED_PROPERTY); icalproperty_set_lastmodified((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* LAST-MODIFIED */ icalproperty* icalproperty_new_lastmodified(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_LASTMODIFIED_PROPERTY); icalproperty_set_lastmodified((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_lastmodified(icalproperty* prop, struct icaltimetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_datetime(v)); } -struct icaltimetype icalproperty_get_lastmodified(icalproperty* prop){ +struct icaltimetype icalproperty_get_lastmodified(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_location(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_LOCATION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_location((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* LOCATION */ icalproperty* icalproperty_new_location(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_LOCATION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_location((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_location(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_location(icalproperty* prop){ +const char* icalproperty_get_location(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_maxresults(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_MAXRESULTS_PROPERTY); icalproperty_set_maxresults((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* MAXRESULTS */ icalproperty* icalproperty_new_maxresults(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_MAXRESULTS_PROPERTY); icalproperty_set_maxresults((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_maxresults(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_maxresults(icalproperty* prop){ +int icalproperty_get_maxresults(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_maxresultssize(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_MAXRESULTSSIZE_PROPERTY); icalproperty_set_maxresultssize((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* MAXRESULTSSIZE */ icalproperty* icalproperty_new_maxresultssize(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_MAXRESULTSSIZE_PROPERTY); icalproperty_set_maxresultssize((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_maxresultssize(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_maxresultssize(icalproperty* prop){ +int icalproperty_get_maxresultssize(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_method(enum icalproperty_method v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_METHOD_PROPERTY); icalproperty_set_method((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* METHOD */ icalproperty* icalproperty_new_method(enum icalproperty_method v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_METHOD_PROPERTY); icalproperty_set_method((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_method(icalproperty* prop, enum icalproperty_method v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_method(v)); } -enum icalproperty_method icalproperty_get_method(icalproperty* prop){ +enum icalproperty_method icalproperty_get_method(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_method(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_organizer(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ORGANIZER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_organizer((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* ORGANIZER */ icalproperty* icalproperty_new_organizer(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_ORGANIZER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_organizer((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_organizer(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_caladdress(v)); } -const char* icalproperty_get_organizer(icalproperty* prop){ +const char* icalproperty_get_organizer(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_caladdress(icalproperty_get_value(prop)); } +icalproperty* icalproperty_vanew_owner(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_OWNER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_owner((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* OWNER */ +icalproperty* icalproperty_new_owner(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_OWNER_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_owner((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_owner(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_owner(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} icalproperty* icalproperty_vanew_percentcomplete(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PERCENTCOMPLETE_PROPERTY); icalproperty_set_percentcomplete((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* PERCENT-COMPLETE */ icalproperty* icalproperty_new_percentcomplete(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PERCENTCOMPLETE_PROPERTY); icalproperty_set_percentcomplete((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_percentcomplete(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_percentcomplete(icalproperty* prop){ +int icalproperty_get_percentcomplete(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_priority(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PRIORITY_PROPERTY); icalproperty_set_priority((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* PRIORITY */ icalproperty* icalproperty_new_priority(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PRIORITY_PROPERTY); icalproperty_set_priority((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_priority(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_priority(icalproperty* prop){ +int icalproperty_get_priority(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_prodid(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PRODID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_prodid((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* PRODID */ icalproperty* icalproperty_new_prodid(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_PRODID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_prodid((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_prodid(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_prodid(icalproperty* prop){ +const char* icalproperty_get_prodid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_query(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_QUERY_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_query((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* QUERY */ icalproperty* icalproperty_new_query(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_QUERY_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_query((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_query(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_query(v)); } -const char* icalproperty_get_query(icalproperty* prop){ +const char* icalproperty_get_query(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_query(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_queryname(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_QUERYNAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_queryname((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* QUERYNAME */ icalproperty* icalproperty_new_queryname(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_QUERYNAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_queryname((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_queryname(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_queryname(icalproperty* prop){ +const char* icalproperty_get_queryname(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_rdate(struct icaldatetimeperiodtype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RDATE_PROPERTY); icalproperty_set_rdate((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* RDATE */ icalproperty* icalproperty_new_rdate(struct icaldatetimeperiodtype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RDATE_PROPERTY); icalproperty_set_rdate((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_rdate(icalproperty* prop, struct icaldatetimeperiodtype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_datetimeperiod(v)); } -struct icaldatetimeperiodtype icalproperty_get_rdate(icalproperty* prop){ +struct icaldatetimeperiodtype icalproperty_get_rdate(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetimeperiod(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_recurrenceid(struct icaltimetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RECURRENCEID_PROPERTY); icalproperty_set_recurrenceid((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* RECURRENCE-ID */ icalproperty* icalproperty_new_recurrenceid(struct icaltimetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RECURRENCEID_PROPERTY); icalproperty_set_recurrenceid((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_recurrenceid(icalproperty* prop, struct icaltimetype v){ + icalvalue *value; icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_datetime(v)); + if (v.is_date) + value = icalvalue_new_date(v); + else + value = icalvalue_new_datetime(v); + icalproperty_set_value(prop,value); } -struct icaltimetype icalproperty_get_recurrenceid(icalproperty* prop){ +struct icaltimetype icalproperty_get_recurrenceid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_datetime(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_relatedto(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RELATEDTO_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_relatedto((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* RELATED-TO */ icalproperty* icalproperty_new_relatedto(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RELATEDTO_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_relatedto((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_relatedto(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_relatedto(icalproperty* prop){ +const char* icalproperty_get_relatedto(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_text(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_relcalid(const char* v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RELCALID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_relcalid((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* RELCALID */ +icalproperty* icalproperty_new_relcalid(const char* v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RELCALID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); + + icalproperty_set_relcalid((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_relcalid(icalproperty* prop, const char* v){ + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_text(v)); +} +const char* icalproperty_get_relcalid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_repeat(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_REPEAT_PROPERTY); icalproperty_set_repeat((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* REPEAT */ icalproperty* icalproperty_new_repeat(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_REPEAT_PROPERTY); icalproperty_set_repeat((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_repeat(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_repeat(icalproperty* prop){ +int icalproperty_get_repeat(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_requeststatus(struct icalreqstattype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_REQUESTSTATUS_PROPERTY); icalproperty_set_requeststatus((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* REQUEST-STATUS */ icalproperty* icalproperty_new_requeststatus(struct icalreqstattype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_REQUESTSTATUS_PROPERTY); icalproperty_set_requeststatus((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_requeststatus(icalproperty* prop, struct icalreqstattype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_requeststatus(v)); } -struct icalreqstattype icalproperty_get_requeststatus(icalproperty* prop){ +struct icalreqstattype icalproperty_get_requeststatus(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_requeststatus(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_resources(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RESOURCES_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_resources((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* RESOURCES */ icalproperty* icalproperty_new_resources(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RESOURCES_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_resources((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_resources(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_resources(icalproperty* prop){ +const char* icalproperty_get_resources(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_rrule(struct icalrecurrencetype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RRULE_PROPERTY); icalproperty_set_rrule((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* RRULE */ icalproperty* icalproperty_new_rrule(struct icalrecurrencetype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_RRULE_PROPERTY); icalproperty_set_rrule((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_rrule(icalproperty* prop, struct icalrecurrencetype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_recur(v)); } -struct icalrecurrencetype icalproperty_get_rrule(icalproperty* prop){ +struct icalrecurrencetype icalproperty_get_rrule(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_recur(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_scope(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SCOPE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_scope((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* SCOPE */ icalproperty* icalproperty_new_scope(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SCOPE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_scope((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_scope(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_scope(icalproperty* prop){ +const char* icalproperty_get_scope(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_sequence(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SEQUENCE_PROPERTY); icalproperty_set_sequence((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* SEQUENCE */ icalproperty* icalproperty_new_sequence(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SEQUENCE_PROPERTY); icalproperty_set_sequence((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_sequence(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_integer(v)); } -int icalproperty_get_sequence(icalproperty* prop){ +int icalproperty_get_sequence(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_integer(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_status(enum icalproperty_status v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_STATUS_PROPERTY); icalproperty_set_status((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* STATUS */ icalproperty* icalproperty_new_status(enum icalproperty_status v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_STATUS_PROPERTY); icalproperty_set_status((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_status(icalproperty* prop, enum icalproperty_status v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_status(v)); } -enum icalproperty_status icalproperty_get_status(icalproperty* prop){ +enum icalproperty_status icalproperty_get_status(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_status(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_summary(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SUMMARY_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_summary((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* SUMMARY */ icalproperty* icalproperty_new_summary(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_SUMMARY_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_summary((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_summary(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_summary(icalproperty* prop){ +const char* icalproperty_get_summary(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_target(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TARGET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_target((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TARGET */ icalproperty* icalproperty_new_target(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TARGET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_target((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_target(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_caladdress(v)); } -const char* icalproperty_get_target(icalproperty* prop){ +const char* icalproperty_get_target(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_caladdress(icalproperty_get_value(prop)); } -icalproperty* icalproperty_vanew_transp(const char* v, ...){ +icalproperty* icalproperty_vanew_transp(enum icalproperty_transp v, ...){ va_list args; - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRANSP_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); - + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRANSP_PROPERTY); icalproperty_set_transp((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } -/* TRANSP */ -icalproperty* icalproperty_new_transp(const char* v) { - struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRANSP_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); +/* TRANSP */ +icalproperty* icalproperty_new_transp(enum icalproperty_transp v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRANSP_PROPERTY); icalproperty_set_transp((icalproperty*)impl,v); return (icalproperty*)impl; } -void icalproperty_set_transp(icalproperty* prop, const char* v){ - icalerror_check_arg_rv( (v!=0),"v"); - +void icalproperty_set_transp(icalproperty* prop, enum icalproperty_transp v){ + icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_text(v)); + icalproperty_set_value(prop,icalvalue_new_transp(v)); } -const char* icalproperty_get_transp(icalproperty* prop){ +enum icalproperty_transp icalproperty_get_transp(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); - return icalvalue_get_text(icalproperty_get_value(prop)); + return icalvalue_get_transp(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_trigger(struct icaltriggertype v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRIGGER_PROPERTY); icalproperty_set_trigger((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TRIGGER */ icalproperty* icalproperty_new_trigger(struct icaltriggertype v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TRIGGER_PROPERTY); icalproperty_set_trigger((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_trigger(icalproperty* prop, struct icaltriggertype v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_trigger(v)); } -struct icaltriggertype icalproperty_get_trigger(icalproperty* prop){ +struct icaltriggertype icalproperty_get_trigger(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_trigger(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_tzid(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzid((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TZID */ icalproperty* icalproperty_new_tzid(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzid((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_tzid(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_tzid(icalproperty* prop){ +const char* icalproperty_get_tzid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_tzname(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZNAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzname((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TZNAME */ icalproperty* icalproperty_new_tzname(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZNAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzname((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_tzname(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_tzname(icalproperty* prop){ +const char* icalproperty_get_tzname(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_tzoffsetfrom(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZOFFSETFROM_PROPERTY); icalproperty_set_tzoffsetfrom((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TZOFFSETFROM */ icalproperty* icalproperty_new_tzoffsetfrom(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZOFFSETFROM_PROPERTY); icalproperty_set_tzoffsetfrom((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_tzoffsetfrom(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_utcoffset(v)); } -int icalproperty_get_tzoffsetfrom(icalproperty* prop){ +int icalproperty_get_tzoffsetfrom(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_utcoffset(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_tzoffsetto(int v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZOFFSETTO_PROPERTY); icalproperty_set_tzoffsetto((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TZOFFSETTO */ icalproperty* icalproperty_new_tzoffsetto(int v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZOFFSETTO_PROPERTY); icalproperty_set_tzoffsetto((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_tzoffsetto(icalproperty* prop, int v){ icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_utcoffset(v)); } -int icalproperty_get_tzoffsetto(icalproperty* prop){ +int icalproperty_get_tzoffsetto(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_utcoffset(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_tzurl(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZURL_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzurl((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* TZURL */ icalproperty* icalproperty_new_tzurl(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_TZURL_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_tzurl((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_tzurl(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_uri(v)); } -const char* icalproperty_get_tzurl(icalproperty* prop){ +const char* icalproperty_get_tzurl(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_uri(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_uid(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_UID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_uid((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* UID */ icalproperty* icalproperty_new_uid(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_UID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_uid((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_uid(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_uid(icalproperty* prop){ +const char* icalproperty_get_uid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_url(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_URL_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_url((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* URL */ icalproperty* icalproperty_new_url(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_URL_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_url((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_url(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_uri(v)); } -const char* icalproperty_get_url(icalproperty* prop){ +const char* icalproperty_get_url(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_uri(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_version(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_VERSION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_version((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* VERSION */ icalproperty* icalproperty_new_version(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_VERSION_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_version((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_version(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_version(icalproperty* prop){ +const char* icalproperty_get_version(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_x(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_X_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_x((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X */ icalproperty* icalproperty_new_x(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_X_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_x((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_x(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); - icalproperty_set_value(prop,icalvalue_new_text(v)); + icalproperty_set_value(prop,icalvalue_new_x(v)); } -const char* icalproperty_get_x(icalproperty* prop){ +const char* icalproperty_get_x(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); - return icalvalue_get_text(icalproperty_get_value(prop)); + return icalvalue_get_x(icalproperty_get_value(prop)); +} +icalproperty* icalproperty_vanew_xlicclass(enum icalproperty_xlicclass v, ...){ + va_list args; + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICCLASS_PROPERTY); + icalproperty_set_xlicclass((icalproperty*)impl,v); + va_start(args,v); + icalproperty_add_parameters(impl, args); + va_end(args); + return (icalproperty*)impl; +} + +/* X-LIC-CLASS */ +icalproperty* icalproperty_new_xlicclass(enum icalproperty_xlicclass v) { + struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICCLASS_PROPERTY); + icalproperty_set_xlicclass((icalproperty*)impl,v); + return (icalproperty*)impl; +} + +void icalproperty_set_xlicclass(icalproperty* prop, enum icalproperty_xlicclass v){ + + icalerror_check_arg_rv( (prop!=0),"prop"); + icalproperty_set_value(prop,icalvalue_new_xlicclass(v)); +} +enum icalproperty_xlicclass icalproperty_get_xlicclass(const icalproperty* prop){ + icalerror_check_arg( (prop!=0),"prop"); + return icalvalue_get_xlicclass(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicclustercount(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICCLUSTERCOUNT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicclustercount((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-CLUSTERCOUNT */ icalproperty* icalproperty_new_xlicclustercount(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICCLUSTERCOUNT_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicclustercount((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicclustercount(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicclustercount(icalproperty* prop){ +const char* icalproperty_get_xlicclustercount(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicerror(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICERROR_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicerror((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-ERROR */ icalproperty* icalproperty_new_xlicerror(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICERROR_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicerror((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicerror(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_text(v)); } -const char* icalproperty_get_xlicerror(icalproperty* prop){ +const char* icalproperty_get_xlicerror(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_text(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimecharset(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECHARSET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecharset((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMECHARSET */ icalproperty* icalproperty_new_xlicmimecharset(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECHARSET_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecharset((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimecharset(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimecharset(icalproperty* prop){ +const char* icalproperty_get_xlicmimecharset(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimecid(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecid((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMECID */ icalproperty* icalproperty_new_xlicmimecid(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECID_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecid((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimecid(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimecid(icalproperty* prop){ +const char* icalproperty_get_xlicmimecid(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimecontenttype(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECONTENTTYPE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecontenttype((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMECONTENTTYPE */ icalproperty* icalproperty_new_xlicmimecontenttype(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMECONTENTTYPE_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimecontenttype((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimecontenttype(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimecontenttype(icalproperty* prop){ +const char* icalproperty_get_xlicmimecontenttype(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimeencoding(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEENCODING_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimeencoding((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMEENCODING */ icalproperty* icalproperty_new_xlicmimeencoding(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEENCODING_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimeencoding((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimeencoding(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimeencoding(icalproperty* prop){ +const char* icalproperty_get_xlicmimeencoding(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimefilename(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEFILENAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimefilename((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMEFILENAME */ icalproperty* icalproperty_new_xlicmimefilename(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEFILENAME_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimefilename((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimefilename(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimefilename(icalproperty* prop){ +const char* icalproperty_get_xlicmimefilename(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } icalproperty* icalproperty_vanew_xlicmimeoptinfo(const char* v, ...){ va_list args; struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEOPTINFO_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimeoptinfo((icalproperty*)impl,v); va_start(args,v); icalproperty_add_parameters(impl, args); va_end(args); return (icalproperty*)impl; } + /* X-LIC-MIMEOPTINFO */ icalproperty* icalproperty_new_xlicmimeoptinfo(const char* v) { struct icalproperty_impl *impl = icalproperty_new_impl(ICAL_XLICMIMEOPTINFO_PROPERTY); icalerror_check_arg_rz( (v!=0),"v"); icalproperty_set_xlicmimeoptinfo((icalproperty*)impl,v); return (icalproperty*)impl; } void icalproperty_set_xlicmimeoptinfo(icalproperty* prop, const char* v){ icalerror_check_arg_rv( (v!=0),"v"); icalerror_check_arg_rv( (prop!=0),"prop"); icalproperty_set_value(prop,icalvalue_new_string(v)); } -const char* icalproperty_get_xlicmimeoptinfo(icalproperty* prop){ +const char* icalproperty_get_xlicmimeoptinfo(const icalproperty* prop){ icalerror_check_arg( (prop!=0),"prop"); return icalvalue_get_string(icalproperty_get_value(prop)); } + +int icalproperty_kind_is_valid(const icalproperty_kind kind) +{ + int i = 0; + do { + if (property_map[i].kind == kind) + return 1; + } while (property_map[i++].kind != ICAL_NO_PROPERTY); + + return 0; +} + +const char* icalproperty_kind_to_string(icalproperty_kind kind) +{ + int i; + + for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { + if (property_map[i].kind == kind) { + return property_map[i].name; + } + } + + return 0; + +} + + +icalproperty_kind icalproperty_string_to_kind(const char* string) +{ + int i; + + if (string ==0 ) { + return ICAL_NO_PROPERTY; + } + + + for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { + if (strcmp(property_map[i].name, string) == 0) { + return property_map[i].kind; + } + } + + if(strncmp(string,"X-",2)==0){ + return ICAL_X_PROPERTY; + } + + + return ICAL_NO_PROPERTY; +} + + +icalproperty_kind icalproperty_value_kind_to_kind(icalvalue_kind kind) +{ + int i; + + for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { + if ( property_map[i].value == kind ) { + return property_map[i].kind; + } + } + + return ICAL_NO_PROPERTY; +} + + + +icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind) +{ + int i; + + for (i=0; property_map[i].kind != ICAL_NO_PROPERTY; i++) { + if ( property_map[i].kind == kind ) { + return property_map[i].value; + } + } + + return ICAL_NO_VALUE; +} + + +const char* icalproperty_enum_to_string(int e) +{ + icalerror_check_arg_rz(e >= ICALPROPERTY_FIRST_ENUM,"e"); + icalerror_check_arg_rz(e <= ICALPROPERTY_LAST_ENUM,"e"); + + return enum_map[e-ICALPROPERTY_FIRST_ENUM].str; +} + +int icalproperty_kind_and_string_to_enum(const int kind, const char* str) +{ + icalproperty_kind pkind; + int i; + + icalerror_check_arg_rz(str!=0,"str") + + if ((pkind = icalproperty_value_kind_to_kind(kind)) == ICAL_NO_VALUE) + return 0; + + while(*str == ' '){ + str++; + } + + for (i=ICALPROPERTY_FIRST_ENUM; i != ICALPROPERTY_LAST_ENUM; i++) { + if (enum_map[i-ICALPROPERTY_FIRST_ENUM].prop == pkind) + break; + } + if (i == ICALPROPERTY_LAST_ENUM) + return 0; + + for (; i != ICALPROPERTY_LAST_ENUM; i++) { + if ( strcmp(enum_map[i-ICALPROPERTY_FIRST_ENUM].str, str) == 0) { + return enum_map[i-ICALPROPERTY_FIRST_ENUM].prop_enum; + } + } + + return 0; +} + +/** @deprecated please use icalproperty_kind_and_string_to_enum instead */ +int icalproperty_string_to_enum(const char* str) +{ + int i; + + icalerror_check_arg_rz(str!=0,"str") + + while(*str == ' '){ + str++; + } + + for (i=ICALPROPERTY_FIRST_ENUM; i != ICALPROPERTY_LAST_ENUM; i++) { + if ( strcmp(enum_map[i-ICALPROPERTY_FIRST_ENUM].str, str) == 0) { + return enum_map[i-ICALPROPERTY_FIRST_ENUM].prop_enum; + } + } + + return 0; +} + +int icalproperty_enum_belongs_to_property(icalproperty_kind kind, int e) +{ + int i; + + + for (i=ICALPROPERTY_FIRST_ENUM; i != ICALPROPERTY_LAST_ENUM; i++) { + if(enum_map[i-ICALPROPERTY_FIRST_ENUM].prop_enum == e && + enum_map[i-ICALPROPERTY_FIRST_ENUM].prop == kind ){ + return 1; + } + } + + return 0; +} + + +const char* icalproperty_method_to_string(icalproperty_method method) +{ + icalerror_check_arg_rz(method >= ICAL_METHOD_X,"method"); + icalerror_check_arg_rz(method <= ICAL_METHOD_NONE,"method"); + + return enum_map[method-ICALPROPERTY_FIRST_ENUM].str; +} + +icalproperty_method icalproperty_string_to_method(const char* str) +{ + int i; + + icalerror_check_arg_rx(str!=0,"str",ICAL_METHOD_NONE) + + while(*str == ' '){ + str++; + } + + for (i=ICAL_METHOD_X-ICALPROPERTY_FIRST_ENUM; + i != ICAL_METHOD_NONE-ICALPROPERTY_FIRST_ENUM; + i++) { + if ( strcmp(enum_map[i].str, str) == 0) { + return (icalproperty_method)enum_map[i].prop_enum; + } + } + + return ICAL_METHOD_NONE; +} + + +const char* icalenum_status_to_string(icalproperty_status status) +{ + icalerror_check_arg_rz(status >= ICAL_STATUS_X,"status"); + icalerror_check_arg_rz(status <= ICAL_STATUS_NONE,"status"); + + return enum_map[status-ICALPROPERTY_FIRST_ENUM].str; +} + +icalproperty_status icalenum_string_to_status(const char* str) +{ + int i; + + icalerror_check_arg_rx(str!=0,"str",ICAL_STATUS_NONE) + + while(*str == ' '){ + str++; + } + + for (i=ICAL_STATUS_X-ICALPROPERTY_FIRST_ENUM; + i != ICAL_STATUS_NONE-ICALPROPERTY_FIRST_ENUM; + i++) { + if ( strcmp(enum_map[i].str, str) == 0) { + return (icalproperty_status)enum_map[i].prop_enum; + } + } + + return ICAL_STATUS_NONE; + +} diff --git a/libical/src/libical/icalderivedproperty.h b/libical/src/libical/icalderivedproperty.h index 07e01b0..ae19c81 100644 --- a/libical/src/libical/icalderivedproperty.h +++ b/libical/src/libical/icalderivedproperty.h @@ -1,403 +1,473 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalderivedproperties.{c,h} CREATOR: eric 09 May 1999 $Id$ (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef ICALDERIVEDPROPERTY_H #define ICALDERIVEDPROPERTY_H #include <time.h> #include "icalparameter.h" #include "icalderivedvalue.h" #include "icalrecur.h" -typedef void icalproperty; +typedef struct icalproperty_impl icalproperty; - -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalproperty_kind { ICAL_ANY_PROPERTY = 0, ICAL_ACTION_PROPERTY, + ICAL_ALLOWCONFLICT_PROPERTY, ICAL_ATTACH_PROPERTY, ICAL_ATTENDEE_PROPERTY, + ICAL_CALID_PROPERTY, + ICAL_CALMASTER_PROPERTY, ICAL_CALSCALE_PROPERTY, + ICAL_CARID_PROPERTY, ICAL_CATEGORIES_PROPERTY, ICAL_CLASS_PROPERTY, ICAL_COMMENT_PROPERTY, ICAL_COMPLETED_PROPERTY, ICAL_CONTACT_PROPERTY, ICAL_CREATED_PROPERTY, + ICAL_DECREED_PROPERTY, + ICAL_DEFAULTCHARSET_PROPERTY, + ICAL_DEFAULTLOCALE_PROPERTY, + ICAL_DEFAULTTZID_PROPERTY, ICAL_DESCRIPTION_PROPERTY, ICAL_DTEND_PROPERTY, ICAL_DTSTAMP_PROPERTY, ICAL_DTSTART_PROPERTY, ICAL_DUE_PROPERTY, ICAL_DURATION_PROPERTY, ICAL_EXDATE_PROPERTY, + ICAL_EXPAND_PROPERTY, ICAL_EXRULE_PROPERTY, ICAL_FREEBUSY_PROPERTY, ICAL_GEO_PROPERTY, ICAL_LASTMODIFIED_PROPERTY, ICAL_LOCATION_PROPERTY, ICAL_MAXRESULTS_PROPERTY, ICAL_MAXRESULTSSIZE_PROPERTY, ICAL_METHOD_PROPERTY, ICAL_ORGANIZER_PROPERTY, + ICAL_OWNER_PROPERTY, ICAL_PERCENTCOMPLETE_PROPERTY, ICAL_PRIORITY_PROPERTY, ICAL_PRODID_PROPERTY, ICAL_QUERY_PROPERTY, ICAL_QUERYNAME_PROPERTY, ICAL_RDATE_PROPERTY, ICAL_RECURRENCEID_PROPERTY, ICAL_RELATEDTO_PROPERTY, + ICAL_RELCALID_PROPERTY, ICAL_REPEAT_PROPERTY, ICAL_REQUESTSTATUS_PROPERTY, ICAL_RESOURCES_PROPERTY, ICAL_RRULE_PROPERTY, ICAL_SCOPE_PROPERTY, ICAL_SEQUENCE_PROPERTY, ICAL_STATUS_PROPERTY, ICAL_SUMMARY_PROPERTY, ICAL_TARGET_PROPERTY, ICAL_TRANSP_PROPERTY, ICAL_TRIGGER_PROPERTY, ICAL_TZID_PROPERTY, ICAL_TZNAME_PROPERTY, ICAL_TZOFFSETFROM_PROPERTY, ICAL_TZOFFSETTO_PROPERTY, ICAL_TZURL_PROPERTY, ICAL_UID_PROPERTY, ICAL_URL_PROPERTY, ICAL_VERSION_PROPERTY, ICAL_X_PROPERTY, + ICAL_XLICCLASS_PROPERTY, ICAL_XLICCLUSTERCOUNT_PROPERTY, ICAL_XLICERROR_PROPERTY, ICAL_XLICMIMECHARSET_PROPERTY, ICAL_XLICMIMECID_PROPERTY, ICAL_XLICMIMECONTENTTYPE_PROPERTY, ICAL_XLICMIMEENCODING_PROPERTY, ICAL_XLICMIMEFILENAME_PROPERTY, ICAL_XLICMIMEOPTINFO_PROPERTY, ICAL_NO_PROPERTY } icalproperty_kind; -icalproperty* icalproperty_vanew_action(enum icalproperty_action v, ...); /* ACTION */ icalproperty* icalproperty_new_action(enum icalproperty_action v); void icalproperty_set_action(icalproperty* prop, enum icalproperty_action v); -enum icalproperty_action icalproperty_get_action(icalproperty* prop);icalproperty* icalproperty_vanew_attach(struct icalattachtype* v, ...); +enum icalproperty_action icalproperty_get_action(const icalproperty* prop);icalproperty* icalproperty_vanew_action(enum icalproperty_action v, ...); + +/* ALLOW-CONFLICT */ +icalproperty* icalproperty_new_allowconflict(const char* v); +void icalproperty_set_allowconflict(icalproperty* prop, const char* v); +const char* icalproperty_get_allowconflict(const icalproperty* prop);icalproperty* icalproperty_vanew_allowconflict(const char* v, ...); /* ATTACH */ -icalproperty* icalproperty_new_attach(struct icalattachtype* v); -void icalproperty_set_attach(icalproperty* prop, struct icalattachtype* v); -struct icalattachtype* icalproperty_get_attach(icalproperty* prop);icalproperty* icalproperty_vanew_attendee(const char* v, ...); +icalproperty* icalproperty_new_attach(icalattach * v); +void icalproperty_set_attach(icalproperty* prop, icalattach * v); +icalattach * icalproperty_get_attach(const icalproperty* prop);icalproperty* icalproperty_vanew_attach(icalattach * v, ...); /* ATTENDEE */ icalproperty* icalproperty_new_attendee(const char* v); void icalproperty_set_attendee(icalproperty* prop, const char* v); -const char* icalproperty_get_attendee(icalproperty* prop);icalproperty* icalproperty_vanew_calscale(const char* v, ...); +const char* icalproperty_get_attendee(const icalproperty* prop);icalproperty* icalproperty_vanew_attendee(const char* v, ...); + +/* CALID */ +icalproperty* icalproperty_new_calid(const char* v); +void icalproperty_set_calid(icalproperty* prop, const char* v); +const char* icalproperty_get_calid(const icalproperty* prop);icalproperty* icalproperty_vanew_calid(const char* v, ...); + +/* CALMASTER */ +icalproperty* icalproperty_new_calmaster(const char* v); +void icalproperty_set_calmaster(icalproperty* prop, const char* v); +const char* icalproperty_get_calmaster(const icalproperty* prop);icalproperty* icalproperty_vanew_calmaster(const char* v, ...); /* CALSCALE */ icalproperty* icalproperty_new_calscale(const char* v); void icalproperty_set_calscale(icalproperty* prop, const char* v); -const char* icalproperty_get_calscale(icalproperty* prop);icalproperty* icalproperty_vanew_categories(const char* v, ...); +const char* icalproperty_get_calscale(const icalproperty* prop);icalproperty* icalproperty_vanew_calscale(const char* v, ...); + +/* CARID */ +icalproperty* icalproperty_new_carid(const char* v); +void icalproperty_set_carid(icalproperty* prop, const char* v); +const char* icalproperty_get_carid(const icalproperty* prop);icalproperty* icalproperty_vanew_carid(const char* v, ...); /* CATEGORIES */ icalproperty* icalproperty_new_categories(const char* v); void icalproperty_set_categories(icalproperty* prop, const char* v); -const char* icalproperty_get_categories(icalproperty* prop);icalproperty* icalproperty_vanew_class(const char* v, ...); +const char* icalproperty_get_categories(const icalproperty* prop);icalproperty* icalproperty_vanew_categories(const char* v, ...); /* CLASS */ -icalproperty* icalproperty_new_class(const char* v); -void icalproperty_set_class(icalproperty* prop, const char* v); -const char* icalproperty_get_class(icalproperty* prop);icalproperty* icalproperty_vanew_comment(const char* v, ...); +icalproperty* icalproperty_new_class(enum icalproperty_class v); +void icalproperty_set_class(icalproperty* prop, enum icalproperty_class v); +enum icalproperty_class icalproperty_get_class(const icalproperty* prop);icalproperty* icalproperty_vanew_class(enum icalproperty_class v, ...); /* COMMENT */ icalproperty* icalproperty_new_comment(const char* v); void icalproperty_set_comment(icalproperty* prop, const char* v); -const char* icalproperty_get_comment(icalproperty* prop);icalproperty* icalproperty_vanew_completed(struct icaltimetype v, ...); +const char* icalproperty_get_comment(const icalproperty* prop);icalproperty* icalproperty_vanew_comment(const char* v, ...); /* COMPLETED */ icalproperty* icalproperty_new_completed(struct icaltimetype v); void icalproperty_set_completed(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_completed(icalproperty* prop);icalproperty* icalproperty_vanew_contact(const char* v, ...); +struct icaltimetype icalproperty_get_completed(const icalproperty* prop);icalproperty* icalproperty_vanew_completed(struct icaltimetype v, ...); /* CONTACT */ icalproperty* icalproperty_new_contact(const char* v); void icalproperty_set_contact(icalproperty* prop, const char* v); -const char* icalproperty_get_contact(icalproperty* prop);icalproperty* icalproperty_vanew_created(struct icaltimetype v, ...); +const char* icalproperty_get_contact(const icalproperty* prop);icalproperty* icalproperty_vanew_contact(const char* v, ...); /* CREATED */ icalproperty* icalproperty_new_created(struct icaltimetype v); void icalproperty_set_created(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_created(icalproperty* prop);icalproperty* icalproperty_vanew_description(const char* v, ...); +struct icaltimetype icalproperty_get_created(const icalproperty* prop);icalproperty* icalproperty_vanew_created(struct icaltimetype v, ...); + +/* DECREED */ +icalproperty* icalproperty_new_decreed(const char* v); +void icalproperty_set_decreed(icalproperty* prop, const char* v); +const char* icalproperty_get_decreed(const icalproperty* prop);icalproperty* icalproperty_vanew_decreed(const char* v, ...); + +/* DEFAULT-CHARSET */ +icalproperty* icalproperty_new_defaultcharset(const char* v); +void icalproperty_set_defaultcharset(icalproperty* prop, const char* v); +const char* icalproperty_get_defaultcharset(const icalproperty* prop);icalproperty* icalproperty_vanew_defaultcharset(const char* v, ...); + +/* DEFAULT-LOCALE */ +icalproperty* icalproperty_new_defaultlocale(const char* v); +void icalproperty_set_defaultlocale(icalproperty* prop, const char* v); +const char* icalproperty_get_defaultlocale(const icalproperty* prop);icalproperty* icalproperty_vanew_defaultlocale(const char* v, ...); + +/* DEFAULT-TZID */ +icalproperty* icalproperty_new_defaulttzid(const char* v); +void icalproperty_set_defaulttzid(icalproperty* prop, const char* v); +const char* icalproperty_get_defaulttzid(const icalproperty* prop);icalproperty* icalproperty_vanew_defaulttzid(const char* v, ...); /* DESCRIPTION */ icalproperty* icalproperty_new_description(const char* v); void icalproperty_set_description(icalproperty* prop, const char* v); -const char* icalproperty_get_description(icalproperty* prop);icalproperty* icalproperty_vanew_dtend(struct icaltimetype v, ...); +const char* icalproperty_get_description(const icalproperty* prop);icalproperty* icalproperty_vanew_description(const char* v, ...); /* DTEND */ icalproperty* icalproperty_new_dtend(struct icaltimetype v); void icalproperty_set_dtend(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtend(icalproperty* prop);icalproperty* icalproperty_vanew_dtstamp(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtend(const icalproperty* prop);icalproperty* icalproperty_vanew_dtend(struct icaltimetype v, ...); /* DTSTAMP */ icalproperty* icalproperty_new_dtstamp(struct icaltimetype v); void icalproperty_set_dtstamp(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtstamp(icalproperty* prop);icalproperty* icalproperty_vanew_dtstart(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtstamp(const icalproperty* prop);icalproperty* icalproperty_vanew_dtstamp(struct icaltimetype v, ...); /* DTSTART */ icalproperty* icalproperty_new_dtstart(struct icaltimetype v); void icalproperty_set_dtstart(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_dtstart(icalproperty* prop);icalproperty* icalproperty_vanew_due(struct icaltimetype v, ...); +struct icaltimetype icalproperty_get_dtstart(const icalproperty* prop);icalproperty* icalproperty_vanew_dtstart(struct icaltimetype v, ...); /* DUE */ icalproperty* icalproperty_new_due(struct icaltimetype v); void icalproperty_set_due(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_due(icalproperty* prop);icalproperty* icalproperty_vanew_duration(struct icaldurationtype v, ...); +struct icaltimetype icalproperty_get_due(const icalproperty* prop);icalproperty* icalproperty_vanew_due(struct icaltimetype v, ...); /* DURATION */ icalproperty* icalproperty_new_duration(struct icaldurationtype v); void icalproperty_set_duration(icalproperty* prop, struct icaldurationtype v); -struct icaldurationtype icalproperty_get_duration(icalproperty* prop);icalproperty* icalproperty_vanew_exdate(struct icaltimetype v, ...); +struct icaldurationtype icalproperty_get_duration(const icalproperty* prop);icalproperty* icalproperty_vanew_duration(struct icaldurationtype v, ...); /* EXDATE */ icalproperty* icalproperty_new_exdate(struct icaltimetype v); void icalproperty_set_exdate(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_exdate(icalproperty* prop);icalproperty* icalproperty_vanew_exrule(struct icalrecurrencetype v, ...); +struct icaltimetype icalproperty_get_exdate(const icalproperty* prop);icalproperty* icalproperty_vanew_exdate(struct icaltimetype v, ...); + +/* EXPAND */ +icalproperty* icalproperty_new_expand(int v); +void icalproperty_set_expand(icalproperty* prop, int v); +int icalproperty_get_expand(const icalproperty* prop);icalproperty* icalproperty_vanew_expand(int v, ...); /* EXRULE */ icalproperty* icalproperty_new_exrule(struct icalrecurrencetype v); void icalproperty_set_exrule(icalproperty* prop, struct icalrecurrencetype v); -struct icalrecurrencetype icalproperty_get_exrule(icalproperty* prop);icalproperty* icalproperty_vanew_freebusy(struct icalperiodtype v, ...); +struct icalrecurrencetype icalproperty_get_exrule(const icalproperty* prop);icalproperty* icalproperty_vanew_exrule(struct icalrecurrencetype v, ...); /* FREEBUSY */ icalproperty* icalproperty_new_freebusy(struct icalperiodtype v); void icalproperty_set_freebusy(icalproperty* prop, struct icalperiodtype v); -struct icalperiodtype icalproperty_get_freebusy(icalproperty* prop);icalproperty* icalproperty_vanew_geo(struct icalgeotype v, ...); +struct icalperiodtype icalproperty_get_freebusy(const icalproperty* prop);icalproperty* icalproperty_vanew_freebusy(struct icalperiodtype v, ...); /* GEO */ icalproperty* icalproperty_new_geo(struct icalgeotype v); void icalproperty_set_geo(icalproperty* prop, struct icalgeotype v); -struct icalgeotype icalproperty_get_geo(icalproperty* prop);icalproperty* icalproperty_vanew_lastmodified(struct icaltimetype v, ...); +struct icalgeotype icalproperty_get_geo(const icalproperty* prop);icalproperty* icalproperty_vanew_geo(struct icalgeotype v, ...); /* LAST-MODIFIED */ icalproperty* icalproperty_new_lastmodified(struct icaltimetype v); void icalproperty_set_lastmodified(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_lastmodified(icalproperty* prop);icalproperty* icalproperty_vanew_location(const char* v, ...); +struct icaltimetype icalproperty_get_lastmodified(const icalproperty* prop);icalproperty* icalproperty_vanew_lastmodified(struct icaltimetype v, ...); /* LOCATION */ icalproperty* icalproperty_new_location(const char* v); void icalproperty_set_location(icalproperty* prop, const char* v); -const char* icalproperty_get_location(icalproperty* prop);icalproperty* icalproperty_vanew_maxresults(int v, ...); +const char* icalproperty_get_location(const icalproperty* prop);icalproperty* icalproperty_vanew_location(const char* v, ...); /* MAXRESULTS */ icalproperty* icalproperty_new_maxresults(int v); void icalproperty_set_maxresults(icalproperty* prop, int v); -int icalproperty_get_maxresults(icalproperty* prop);icalproperty* icalproperty_vanew_maxresultssize(int v, ...); +int icalproperty_get_maxresults(const icalproperty* prop);icalproperty* icalproperty_vanew_maxresults(int v, ...); /* MAXRESULTSSIZE */ icalproperty* icalproperty_new_maxresultssize(int v); void icalproperty_set_maxresultssize(icalproperty* prop, int v); -int icalproperty_get_maxresultssize(icalproperty* prop);icalproperty* icalproperty_vanew_method(enum icalproperty_method v, ...); +int icalproperty_get_maxresultssize(const icalproperty* prop);icalproperty* icalproperty_vanew_maxresultssize(int v, ...); /* METHOD */ icalproperty* icalproperty_new_method(enum icalproperty_method v); void icalproperty_set_method(icalproperty* prop, enum icalproperty_method v); -enum icalproperty_method icalproperty_get_method(icalproperty* prop);icalproperty* icalproperty_vanew_organizer(const char* v, ...); +enum icalproperty_method icalproperty_get_method(const icalproperty* prop);icalproperty* icalproperty_vanew_method(enum icalproperty_method v, ...); /* ORGANIZER */ icalproperty* icalproperty_new_organizer(const char* v); void icalproperty_set_organizer(icalproperty* prop, const char* v); -const char* icalproperty_get_organizer(icalproperty* prop);icalproperty* icalproperty_vanew_percentcomplete(int v, ...); +const char* icalproperty_get_organizer(const icalproperty* prop);icalproperty* icalproperty_vanew_organizer(const char* v, ...); + +/* OWNER */ +icalproperty* icalproperty_new_owner(const char* v); +void icalproperty_set_owner(icalproperty* prop, const char* v); +const char* icalproperty_get_owner(const icalproperty* prop);icalproperty* icalproperty_vanew_owner(const char* v, ...); /* PERCENT-COMPLETE */ icalproperty* icalproperty_new_percentcomplete(int v); void icalproperty_set_percentcomplete(icalproperty* prop, int v); -int icalproperty_get_percentcomplete(icalproperty* prop);icalproperty* icalproperty_vanew_priority(int v, ...); +int icalproperty_get_percentcomplete(const icalproperty* prop);icalproperty* icalproperty_vanew_percentcomplete(int v, ...); /* PRIORITY */ icalproperty* icalproperty_new_priority(int v); void icalproperty_set_priority(icalproperty* prop, int v); -int icalproperty_get_priority(icalproperty* prop);icalproperty* icalproperty_vanew_prodid(const char* v, ...); +int icalproperty_get_priority(const icalproperty* prop);icalproperty* icalproperty_vanew_priority(int v, ...); /* PRODID */ icalproperty* icalproperty_new_prodid(const char* v); void icalproperty_set_prodid(icalproperty* prop, const char* v); -const char* icalproperty_get_prodid(icalproperty* prop);icalproperty* icalproperty_vanew_query(const char* v, ...); +const char* icalproperty_get_prodid(const icalproperty* prop);icalproperty* icalproperty_vanew_prodid(const char* v, ...); /* QUERY */ icalproperty* icalproperty_new_query(const char* v); void icalproperty_set_query(icalproperty* prop, const char* v); -const char* icalproperty_get_query(icalproperty* prop);icalproperty* icalproperty_vanew_queryname(const char* v, ...); +const char* icalproperty_get_query(const icalproperty* prop);icalproperty* icalproperty_vanew_query(const char* v, ...); /* QUERYNAME */ icalproperty* icalproperty_new_queryname(const char* v); void icalproperty_set_queryname(icalproperty* prop, const char* v); -const char* icalproperty_get_queryname(icalproperty* prop);icalproperty* icalproperty_vanew_rdate(struct icaldatetimeperiodtype v, ...); +const char* icalproperty_get_queryname(const icalproperty* prop);icalproperty* icalproperty_vanew_queryname(const char* v, ...); /* RDATE */ icalproperty* icalproperty_new_rdate(struct icaldatetimeperiodtype v); void icalproperty_set_rdate(icalproperty* prop, struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalproperty_get_rdate(icalproperty* prop);icalproperty* icalproperty_vanew_recurrenceid(struct icaltimetype v, ...); +struct icaldatetimeperiodtype icalproperty_get_rdate(const icalproperty* prop);icalproperty* icalproperty_vanew_rdate(struct icaldatetimeperiodtype v, ...); /* RECURRENCE-ID */ icalproperty* icalproperty_new_recurrenceid(struct icaltimetype v); void icalproperty_set_recurrenceid(icalproperty* prop, struct icaltimetype v); -struct icaltimetype icalproperty_get_recurrenceid(icalproperty* prop);icalproperty* icalproperty_vanew_relatedto(const char* v, ...); +struct icaltimetype icalproperty_get_recurrenceid(const icalproperty* prop);icalproperty* icalproperty_vanew_recurrenceid(struct icaltimetype v, ...); /* RELATED-TO */ icalproperty* icalproperty_new_relatedto(const char* v); void icalproperty_set_relatedto(icalproperty* prop, const char* v); -const char* icalproperty_get_relatedto(icalproperty* prop);icalproperty* icalproperty_vanew_repeat(int v, ...); +const char* icalproperty_get_relatedto(const icalproperty* prop);icalproperty* icalproperty_vanew_relatedto(const char* v, ...); + +/* RELCALID */ +icalproperty* icalproperty_new_relcalid(const char* v); +void icalproperty_set_relcalid(icalproperty* prop, const char* v); +const char* icalproperty_get_relcalid(const icalproperty* prop);icalproperty* icalproperty_vanew_relcalid(const char* v, ...); /* REPEAT */ icalproperty* icalproperty_new_repeat(int v); void icalproperty_set_repeat(icalproperty* prop, int v); -int icalproperty_get_repeat(icalproperty* prop);icalproperty* icalproperty_vanew_requeststatus(struct icalreqstattype v, ...); +int icalproperty_get_repeat(const icalproperty* prop);icalproperty* icalproperty_vanew_repeat(int v, ...); /* REQUEST-STATUS */ icalproperty* icalproperty_new_requeststatus(struct icalreqstattype v); void icalproperty_set_requeststatus(icalproperty* prop, struct icalreqstattype v); -struct icalreqstattype icalproperty_get_requeststatus(icalproperty* prop);icalproperty* icalproperty_vanew_resources(const char* v, ...); +struct icalreqstattype icalproperty_get_requeststatus(const icalproperty* prop);icalproperty* icalproperty_vanew_requeststatus(struct icalreqstattype v, ...); /* RESOURCES */ icalproperty* icalproperty_new_resources(const char* v); void icalproperty_set_resources(icalproperty* prop, const char* v); -const char* icalproperty_get_resources(icalproperty* prop);icalproperty* icalproperty_vanew_rrule(struct icalrecurrencetype v, ...); +const char* icalproperty_get_resources(const icalproperty* prop);icalproperty* icalproperty_vanew_resources(const char* v, ...); /* RRULE */ icalproperty* icalproperty_new_rrule(struct icalrecurrencetype v); void icalproperty_set_rrule(icalproperty* prop, struct icalrecurrencetype v); -struct icalrecurrencetype icalproperty_get_rrule(icalproperty* prop);icalproperty* icalproperty_vanew_scope(const char* v, ...); +struct icalrecurrencetype icalproperty_get_rrule(const icalproperty* prop);icalproperty* icalproperty_vanew_rrule(struct icalrecurrencetype v, ...); /* SCOPE */ icalproperty* icalproperty_new_scope(const char* v); void icalproperty_set_scope(icalproperty* prop, const char* v); -const char* icalproperty_get_scope(icalproperty* prop);icalproperty* icalproperty_vanew_sequence(int v, ...); +const char* icalproperty_get_scope(const icalproperty* prop);icalproperty* icalproperty_vanew_scope(const char* v, ...); /* SEQUENCE */ icalproperty* icalproperty_new_sequence(int v); void icalproperty_set_sequence(icalproperty* prop, int v); -int icalproperty_get_sequence(icalproperty* prop);icalproperty* icalproperty_vanew_status(enum icalproperty_status v, ...); +int icalproperty_get_sequence(const icalproperty* prop);icalproperty* icalproperty_vanew_sequence(int v, ...); /* STATUS */ icalproperty* icalproperty_new_status(enum icalproperty_status v); void icalproperty_set_status(icalproperty* prop, enum icalproperty_status v); -enum icalproperty_status icalproperty_get_status(icalproperty* prop);icalproperty* icalproperty_vanew_summary(const char* v, ...); +enum icalproperty_status icalproperty_get_status(const icalproperty* prop);icalproperty* icalproperty_vanew_status(enum icalproperty_status v, ...); /* SUMMARY */ icalproperty* icalproperty_new_summary(const char* v); void icalproperty_set_summary(icalproperty* prop, const char* v); -const char* icalproperty_get_summary(icalproperty* prop);icalproperty* icalproperty_vanew_target(const char* v, ...); +const char* icalproperty_get_summary(const icalproperty* prop);icalproperty* icalproperty_vanew_summary(const char* v, ...); /* TARGET */ icalproperty* icalproperty_new_target(const char* v); void icalproperty_set_target(icalproperty* prop, const char* v); -const char* icalproperty_get_target(icalproperty* prop);icalproperty* icalproperty_vanew_transp(const char* v, ...); +const char* icalproperty_get_target(const icalproperty* prop);icalproperty* icalproperty_vanew_target(const char* v, ...); /* TRANSP */ -icalproperty* icalproperty_new_transp(const char* v); -void icalproperty_set_transp(icalproperty* prop, const char* v); -const char* icalproperty_get_transp(icalproperty* prop);icalproperty* icalproperty_vanew_trigger(struct icaltriggertype v, ...); +icalproperty* icalproperty_new_transp(enum icalproperty_transp v); +void icalproperty_set_transp(icalproperty* prop, enum icalproperty_transp v); +enum icalproperty_transp icalproperty_get_transp(const icalproperty* prop);icalproperty* icalproperty_vanew_transp(enum icalproperty_transp v, ...); /* TRIGGER */ icalproperty* icalproperty_new_trigger(struct icaltriggertype v); void icalproperty_set_trigger(icalproperty* prop, struct icaltriggertype v); -struct icaltriggertype icalproperty_get_trigger(icalproperty* prop);icalproperty* icalproperty_vanew_tzid(const char* v, ...); +struct icaltriggertype icalproperty_get_trigger(const icalproperty* prop);icalproperty* icalproperty_vanew_trigger(struct icaltriggertype v, ...); /* TZID */ icalproperty* icalproperty_new_tzid(const char* v); void icalproperty_set_tzid(icalproperty* prop, const char* v); -const char* icalproperty_get_tzid(icalproperty* prop);icalproperty* icalproperty_vanew_tzname(const char* v, ...); +const char* icalproperty_get_tzid(const icalproperty* prop);icalproperty* icalproperty_vanew_tzid(const char* v, ...); /* TZNAME */ icalproperty* icalproperty_new_tzname(const char* v); void icalproperty_set_tzname(icalproperty* prop, const char* v); -const char* icalproperty_get_tzname(icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetfrom(int v, ...); +const char* icalproperty_get_tzname(const icalproperty* prop);icalproperty* icalproperty_vanew_tzname(const char* v, ...); /* TZOFFSETFROM */ icalproperty* icalproperty_new_tzoffsetfrom(int v); void icalproperty_set_tzoffsetfrom(icalproperty* prop, int v); -int icalproperty_get_tzoffsetfrom(icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetto(int v, ...); +int icalproperty_get_tzoffsetfrom(const icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetfrom(int v, ...); /* TZOFFSETTO */ icalproperty* icalproperty_new_tzoffsetto(int v); void icalproperty_set_tzoffsetto(icalproperty* prop, int v); -int icalproperty_get_tzoffsetto(icalproperty* prop);icalproperty* icalproperty_vanew_tzurl(const char* v, ...); +int icalproperty_get_tzoffsetto(const icalproperty* prop);icalproperty* icalproperty_vanew_tzoffsetto(int v, ...); /* TZURL */ icalproperty* icalproperty_new_tzurl(const char* v); void icalproperty_set_tzurl(icalproperty* prop, const char* v); -const char* icalproperty_get_tzurl(icalproperty* prop);icalproperty* icalproperty_vanew_uid(const char* v, ...); +const char* icalproperty_get_tzurl(const icalproperty* prop);icalproperty* icalproperty_vanew_tzurl(const char* v, ...); /* UID */ icalproperty* icalproperty_new_uid(const char* v); void icalproperty_set_uid(icalproperty* prop, const char* v); -const char* icalproperty_get_uid(icalproperty* prop);icalproperty* icalproperty_vanew_url(const char* v, ...); +const char* icalproperty_get_uid(const icalproperty* prop);icalproperty* icalproperty_vanew_uid(const char* v, ...); /* URL */ icalproperty* icalproperty_new_url(const char* v); void icalproperty_set_url(icalproperty* prop, const char* v); -const char* icalproperty_get_url(icalproperty* prop);icalproperty* icalproperty_vanew_version(const char* v, ...); +const char* icalproperty_get_url(const icalproperty* prop);icalproperty* icalproperty_vanew_url(const char* v, ...); /* VERSION */ icalproperty* icalproperty_new_version(const char* v); void icalproperty_set_version(icalproperty* prop, const char* v); -const char* icalproperty_get_version(icalproperty* prop);icalproperty* icalproperty_vanew_x(const char* v, ...); +const char* icalproperty_get_version(const icalproperty* prop);icalproperty* icalproperty_vanew_version(const char* v, ...); /* X */ icalproperty* icalproperty_new_x(const char* v); void icalproperty_set_x(icalproperty* prop, const char* v); -const char* icalproperty_get_x(icalproperty* prop);icalproperty* icalproperty_vanew_xlicclustercount(const char* v, ...); +const char* icalproperty_get_x(const icalproperty* prop);icalproperty* icalproperty_vanew_x(const char* v, ...); + +/* X-LIC-CLASS */ +icalproperty* icalproperty_new_xlicclass(enum icalproperty_xlicclass v); +void icalproperty_set_xlicclass(icalproperty* prop, enum icalproperty_xlicclass v); +enum icalproperty_xlicclass icalproperty_get_xlicclass(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicclass(enum icalproperty_xlicclass v, ...); /* X-LIC-CLUSTERCOUNT */ icalproperty* icalproperty_new_xlicclustercount(const char* v); void icalproperty_set_xlicclustercount(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicclustercount(icalproperty* prop);icalproperty* icalproperty_vanew_xlicerror(const char* v, ...); +const char* icalproperty_get_xlicclustercount(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicclustercount(const char* v, ...); /* X-LIC-ERROR */ icalproperty* icalproperty_new_xlicerror(const char* v); void icalproperty_set_xlicerror(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicerror(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecharset(const char* v, ...); +const char* icalproperty_get_xlicerror(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicerror(const char* v, ...); /* X-LIC-MIMECHARSET */ icalproperty* icalproperty_new_xlicmimecharset(const char* v); void icalproperty_set_xlicmimecharset(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecharset(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecid(const char* v, ...); +const char* icalproperty_get_xlicmimecharset(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecharset(const char* v, ...); /* X-LIC-MIMECID */ icalproperty* icalproperty_new_xlicmimecid(const char* v); void icalproperty_set_xlicmimecid(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecid(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecontenttype(const char* v, ...); +const char* icalproperty_get_xlicmimecid(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecid(const char* v, ...); /* X-LIC-MIMECONTENTTYPE */ icalproperty* icalproperty_new_xlicmimecontenttype(const char* v); void icalproperty_set_xlicmimecontenttype(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimecontenttype(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeencoding(const char* v, ...); +const char* icalproperty_get_xlicmimecontenttype(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimecontenttype(const char* v, ...); /* X-LIC-MIMEENCODING */ icalproperty* icalproperty_new_xlicmimeencoding(const char* v); void icalproperty_set_xlicmimeencoding(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimeencoding(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimefilename(const char* v, ...); +const char* icalproperty_get_xlicmimeencoding(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeencoding(const char* v, ...); /* X-LIC-MIMEFILENAME */ icalproperty* icalproperty_new_xlicmimefilename(const char* v); void icalproperty_set_xlicmimefilename(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimefilename(icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeoptinfo(const char* v, ...); +const char* icalproperty_get_xlicmimefilename(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimefilename(const char* v, ...); /* X-LIC-MIMEOPTINFO */ icalproperty* icalproperty_new_xlicmimeoptinfo(const char* v); void icalproperty_set_xlicmimeoptinfo(icalproperty* prop, const char* v); -const char* icalproperty_get_xlicmimeoptinfo(icalproperty* prop); +const char* icalproperty_get_xlicmimeoptinfo(const icalproperty* prop);icalproperty* icalproperty_vanew_xlicmimeoptinfo(const char* v, ...); + #endif /*ICALPROPERTY_H*/ diff --git a/libical/src/libical/icalderivedvalue.c b/libical/src/libical/icalderivedvalue.c index db762ea..8dbbe9e 100644 --- a/libical/src/libical/icalderivedvalue.c +++ b/libical/src/libical/icalderivedvalue.c @@ -1,981 +1,1007 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalvalue.c CREATOR: eric 02 May 1999 $Id$ (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 icalvalue.c Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalerror.h" #include "icalmemory.h" #include "icalparser.h" #include "icalenums.h" #include "icalvalueimpl.h" #include <stdlib.h> /* for malloc */ #include <stdio.h> /* for sprintf */ #include <string.h> /* For memset, others */ #include <stddef.h> /* For offsetof() macro */ #include <errno.h> #include <time.h> /* for mktime */ #include <stdlib.h> /* for atoi and atof */ #include <limits.h> /* for SHRT_MAX */ - - -#define TMP_BUF_SIZE 1024 - struct icalvalue_impl* icalvalue_new_impl(icalvalue_kind kind); /* This map associates each of the value types with its string representation */ struct icalvalue_kind_map { icalvalue_kind kind; char name[20]; }; -extern struct icalvalue_kind_map value_map[]; - -const char* icalvalue_kind_to_string(icalvalue_kind kind) -{ - int i; - - for (i=0; value_map[i].kind != ICAL_NO_VALUE; i++) { - if (value_map[i].kind == kind) { - return value_map[i].name; - } - } - - return 0; -} - -icalvalue_kind icalvalue_string_to_kind(const char* str) -{ - int i; - - for (i=0; value_map[i].kind != ICAL_NO_VALUE; i++) { - if (strcmp(value_map[i].name,str) == 0) { - return value_map[i].kind; - } - } - - return value_map[i].kind; +static struct icalvalue_kind_map value_map[28]={ + {ICAL_QUERY_VALUE,"QUERY"}, + {ICAL_DATE_VALUE,"DATE"}, + {ICAL_ATTACH_VALUE,"ATTACH"}, + {ICAL_GEO_VALUE,"GEO"}, + {ICAL_STATUS_VALUE,"STATUS"}, + {ICAL_TRANSP_VALUE,"TRANSP"}, + {ICAL_STRING_VALUE,"STRING"}, + {ICAL_TEXT_VALUE,"TEXT"}, + {ICAL_REQUESTSTATUS_VALUE,"REQUEST-STATUS"}, + {ICAL_BINARY_VALUE,"BINARY"}, + {ICAL_PERIOD_VALUE,"PERIOD"}, + {ICAL_FLOAT_VALUE,"FLOAT"}, + {ICAL_DATETIMEPERIOD_VALUE,"DATE-TIME-PERIOD"}, + {ICAL_INTEGER_VALUE,"INTEGER"}, + {ICAL_CLASS_VALUE,"CLASS"}, + {ICAL_URI_VALUE,"URI"}, + {ICAL_DURATION_VALUE,"DURATION"}, + {ICAL_BOOLEAN_VALUE,"BOOLEAN"}, + {ICAL_X_VALUE,"X"}, + {ICAL_CALADDRESS_VALUE,"CAL-ADDRESS"}, + {ICAL_TRIGGER_VALUE,"TRIGGER"}, + {ICAL_XLICCLASS_VALUE,"X-LIC-CLASS"}, + {ICAL_RECUR_VALUE,"RECUR"}, + {ICAL_ACTION_VALUE,"ACTION"}, + {ICAL_DATETIME_VALUE,"DATE-TIME"}, + {ICAL_UTCOFFSET_VALUE,"UTC-OFFSET"}, + {ICAL_METHOD_VALUE,"METHOD"}, + {ICAL_NO_VALUE,""} +}; -} -icalvalue* icalvalue_new_x (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_X_VALUE); +icalvalue* icalvalue_new_query (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_QUERY_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_x((icalvalue*)impl,v); + icalvalue_set_query((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_x(icalvalue* value, const char* v) { +void icalvalue_set_query(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); + icalerror_check_value_type(value, ICAL_QUERY_VALUE); impl = (struct icalvalue_impl*)value; - if(impl->x_value!=0) {free((void*)impl->x_value);} + if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} - impl->x_value = icalmemory_strdup(v); - if (impl->x_value == 0){ + impl->data.v_string = icalmemory_strdup(v); + + if (impl->data.v_string == 0){ errno = ENOMEM; } - } -const char* icalvalue_get_x(icalvalue* value) { + + icalvalue_reset_kind(impl); +} +const char* icalvalue_get_query(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_X_VALUE); - return ((struct icalvalue_impl*)value)->x_value; + icalerror_check_value_type(value, ICAL_QUERY_VALUE); + return ((struct icalvalue_impl*)value)->data.v_string; } -/* Attachment is a special case, so it is not auto generated. */ -icalvalue* -icalvalue_new_attach (struct icalattachtype *v) -{ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_ATTACH_VALUE); - - icalvalue_set_attach((icalvalue*)impl,v); + +icalvalue* icalvalue_new_date (struct icaltimetype v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DATE_VALUE); + + icalvalue_set_date((icalvalue*)impl,v); return (icalvalue*)impl; } - -void -icalvalue_set_attach(icalvalue* value, struct icalattachtype *v) -{ +void icalvalue_set_date(icalvalue* value, struct icaltimetype v) { struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_ATTACH_VALUE); - + + icalerror_check_value_type(value, ICAL_DATE_VALUE); impl = (struct icalvalue_impl*)value; - if (impl->data.v_attach != 0){ - icalattachtype_free(impl->data.v_attach); - } - impl->data.v_attach = v; - icalattachtype_add_reference(v); + impl->data.v_time = v; + + icalvalue_reset_kind(impl); } +struct icaltimetype icalvalue_get_date(const icalvalue* value) { -struct icalattachtype* -icalvalue_get_attach(icalvalue* value) -{ icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_ATTACH_VALUE); - - return ((struct icalvalue_impl*)value)->data.v_attach; + icalerror_check_value_type(value, ICAL_DATE_VALUE); + return ((struct icalvalue_impl*)value)->data.v_time; } -/* Recur is a special case, so it is not auto generated. */ -icalvalue* -icalvalue_new_recur (struct icalrecurrencetype v) -{ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_RECUR_VALUE); - - icalvalue_set_recur((icalvalue*)impl,v); +icalvalue* icalvalue_new_geo (struct icalgeotype v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_GEO_VALUE); + + icalvalue_set_geo((icalvalue*)impl,v); return (icalvalue*)impl; } - -void -icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v) -{ +void icalvalue_set_geo(icalvalue* value, struct icalgeotype v) { struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_RECUR_VALUE); - + + icalerror_check_value_type(value, ICAL_GEO_VALUE); impl = (struct icalvalue_impl*)value; - if (impl->data.v_recur != 0){ - free(impl->data.v_recur); - impl->data.v_recur = 0; - } - impl->data.v_recur = malloc(sizeof(struct icalrecurrencetype)); + impl->data.v_geo = v; - if (impl->data.v_recur == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return; - } else { - memcpy(impl->data.v_recur, &v, sizeof(struct icalrecurrencetype)); - } - + icalvalue_reset_kind(impl); } +struct icalgeotype icalvalue_get_geo(const icalvalue* value) { -struct icalrecurrencetype -icalvalue_get_recur(icalvalue* value) -{ icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_RECUR_VALUE); - - return *(((struct icalvalue_impl*)value)->data.v_recur); + icalerror_check_value_type(value, ICAL_GEO_VALUE); + return ((struct icalvalue_impl*)value)->data.v_geo; } - -icalvalue* -icalvalue_new_trigger (struct icaltriggertype v) -{ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TRIGGER_VALUE); - - icalvalue_set_trigger((icalvalue*)impl,v); - +icalvalue* icalvalue_new_status (enum icalproperty_status v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STATUS_VALUE); + + icalvalue_set_status((icalvalue*)impl,v); return (icalvalue*)impl; } - -void -icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v) -{ +void icalvalue_set_status(icalvalue* value, enum icalproperty_status v) { struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); + icalerror_check_value_type(value, ICAL_STATUS_VALUE); impl = (struct icalvalue_impl*)value; - if(!icaltime_is_null_time(v.time)){ - icalvalue_set_datetime((icalvalue*)impl,v.time); - impl->kind = ICAL_DATETIME_VALUE; - } else { - icalvalue_set_duration((icalvalue*)impl,v.duration); - impl->kind = ICAL_DURATION_VALUE; - } -} + impl->data.v_enum = v; -struct icaltriggertype -icalvalue_get_trigger(icalvalue* value) -{ - struct icalvalue_impl *impl = (struct icalvalue_impl*)value; - struct icaltriggertype tr; + icalvalue_reset_kind(impl); +} +enum icalproperty_status icalvalue_get_status(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_arg( (value!=0),"value"); - - if(impl->kind == ICAL_DATETIME_VALUE){ - tr.duration = icaldurationtype_from_int(0); - tr.time = impl->data.v_time; - } else if(impl->kind == ICAL_DURATION_VALUE){ - tr.time = icaltime_null_time(); - tr.duration = impl->data.v_duration; - } else { - tr.duration = icaldurationtype_from_int(0); - tr.time = icaltime_null_time(); - icalerror_set_errno(ICAL_BADARG_ERROR); - } - - return tr; + icalerror_check_value_type(value, ICAL_STATUS_VALUE); + return ((struct icalvalue_impl*)value)->data.v_enum; } -/* DATE-TIME-PERIOD is a special case, and is not auto generated */ - -icalvalue* -icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v) -{ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DATETIMEPERIOD_VALUE); - icalvalue_set_datetimeperiod((icalvalue*)impl,v); +icalvalue* icalvalue_new_transp (enum icalproperty_transp v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TRANSP_VALUE); + + icalvalue_set_transp((icalvalue*)impl,v); return (icalvalue*)impl; } - -void -icalvalue_set_datetimeperiod(icalvalue* value, struct icaldatetimeperiodtype v) -{ - struct icalvalue_impl* impl = (struct icalvalue_impl*)value; - +void icalvalue_set_transp(icalvalue* value, enum icalproperty_transp v) { + struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_DATETIMEPERIOD_VALUE); + icalerror_check_value_type(value, ICAL_TRANSP_VALUE); + impl = (struct icalvalue_impl*)value; - if(!icaltime_is_null_time(v.time)){ - if(!icaltime_is_valid_time(v.time)){ - icalerror_set_errno(ICAL_BADARG_ERROR); - return; - } - impl->kind = ICAL_DATETIME_VALUE; - icalvalue_set_datetime(impl,v.time); - } else if (!icalperiodtype_is_null_period(v.period)) { - if(!icalperiodtype_is_valid_period(v.period)){ - icalerror_set_errno(ICAL_BADARG_ERROR); - return; - } - impl->kind = ICAL_PERIOD_VALUE; - icalvalue_set_period(impl,v.period); - } else { - icalerror_set_errno(ICAL_BADARG_ERROR); - } -} -struct icaldatetimeperiodtype -icalvalue_get_datetimeperiod(icalvalue* value) -{ - struct icaldatetimeperiodtype dtp; - - struct icalvalue_impl* impl = (struct icalvalue_impl*)value; - icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_DATETIMEPERIOD_VALUE); - - if(impl->kind == ICAL_DATETIME_VALUE){ - dtp.period = icalperiodtype_null_period(); - dtp.time = impl->data.v_time; - } else if(impl->kind == ICAL_PERIOD_VALUE) { - dtp.period = impl->data.v_period; - dtp.time = icaltime_null_time(); - } else { - dtp.period = icalperiodtype_null_period(); - dtp.time = icaltime_null_time(); - icalerror_set_errno(ICAL_BADARG_ERROR); - } + impl->data.v_enum = v; - return dtp; + icalvalue_reset_kind(impl); } +enum icalproperty_transp icalvalue_get_transp(const icalvalue* value) { + icalerror_check_arg( (value!=0),"value"); + icalerror_check_value_type(value, ICAL_TRANSP_VALUE); + return ((struct icalvalue_impl*)value)->data.v_enum; +} - - - - - -/* The remaining interfaces are 'new', 'set' and 'get' for each of the value - types */ - - -/* Everything below this line is machine generated. Do not edit. */ -static struct icalvalue_kind_map value_map[]={ - {ICAL_QUERY_VALUE,"QUERY"}, - {ICAL_TRIGGER_VALUE,"TRIGGER"}, - {ICAL_STATUS_VALUE,"STATUS"}, - {ICAL_TRANSP_VALUE,"TRANSP"}, - {ICAL_CLASS_VALUE,"CLASS"}, - {ICAL_DATE_VALUE,"DATE"}, - {ICAL_STRING_VALUE,"STRING"}, - {ICAL_INTEGER_VALUE,"INTEGER"}, - {ICAL_PERIOD_VALUE,"PERIOD"}, - {ICAL_TEXT_VALUE,"TEXT"}, - {ICAL_DURATION_VALUE,"DURATION"}, - {ICAL_BOOLEAN_VALUE,"BOOLEAN"}, - {ICAL_URI_VALUE,"URI"}, - {ICAL_DATETIMEPERIOD_VALUE,"DATE-TIME-PERIOD"}, - {ICAL_GEO_VALUE,"GEO"}, - {ICAL_DATETIME_VALUE,"DATE-TIME"}, - {ICAL_UTCOFFSET_VALUE,"UTC-OFFSET"}, - {ICAL_ATTACH_VALUE,"ATTACH"}, - {ICAL_ACTION_VALUE,"ACTION"}, - {ICAL_CALADDRESS_VALUE,"CAL-ADDRESS"}, - {ICAL_X_VALUE,"X"}, - {ICAL_FLOAT_VALUE,"FLOAT"}, - {ICAL_REQUESTSTATUS_VALUE,"REQUEST-STATUS"}, - {ICAL_METHOD_VALUE,"METHOD"}, - {ICAL_BINARY_VALUE,"BINARY"}, - {ICAL_RECUR_VALUE,"RECUR"}, - {ICAL_NO_VALUE,""} -}; - - -icalvalue* icalvalue_new_query (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_QUERY_VALUE); +icalvalue* icalvalue_new_string (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STRING_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_query((icalvalue*)impl,v); + icalvalue_set_string((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_query(icalvalue* value, const char* v) { +void icalvalue_set_string(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_QUERY_VALUE); + icalerror_check_value_type(value, ICAL_STRING_VALUE); impl = (struct icalvalue_impl*)value; if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} impl->data.v_string = icalmemory_strdup(v); if (impl->data.v_string == 0){ errno = ENOMEM; } icalvalue_reset_kind(impl); } -const char* icalvalue_get_query(icalvalue* value) { +const char* icalvalue_get_string(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_QUERY_VALUE); + icalerror_check_value_type(value, ICAL_STRING_VALUE); return ((struct icalvalue_impl*)value)->data.v_string; } -icalvalue* icalvalue_new_status (enum icalproperty_status v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STATUS_VALUE); - - icalvalue_set_status((icalvalue*)impl,v); +icalvalue* icalvalue_new_text (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); + icalerror_check_arg_rz( (v!=0),"v"); + + icalvalue_set_text((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_status(icalvalue* value, enum icalproperty_status v) { +void icalvalue_set_text(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - - icalerror_check_value_type(value, ICAL_STATUS_VALUE); + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_value_type(value, ICAL_TEXT_VALUE); impl = (struct icalvalue_impl*)value; + if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} - impl->data.v_enum = v; + impl->data.v_string = icalmemory_strdup(v); + + if (impl->data.v_string == 0){ + errno = ENOMEM; + } + icalvalue_reset_kind(impl); } -enum icalproperty_status icalvalue_get_status(icalvalue* value) { +const char* icalvalue_get_text(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_STATUS_VALUE); - return ((struct icalvalue_impl*)value)->data.v_enum; + icalerror_check_value_type(value, ICAL_TEXT_VALUE); + return ((struct icalvalue_impl*)value)->data.v_string; } -icalvalue* icalvalue_new_transp (enum icalproperty_transp v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TRANSP_VALUE); +icalvalue* icalvalue_new_requeststatus (struct icalreqstattype v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_REQUESTSTATUS_VALUE); - icalvalue_set_transp((icalvalue*)impl,v); + icalvalue_set_requeststatus((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_transp(icalvalue* value, enum icalproperty_transp v) { +void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_TRANSP_VALUE); + icalerror_check_value_type(value, ICAL_REQUESTSTATUS_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_enum = v; + impl->data.v_requeststatus = v; icalvalue_reset_kind(impl); } -enum icalproperty_transp icalvalue_get_transp(icalvalue* value) { +struct icalreqstattype icalvalue_get_requeststatus(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_TRANSP_VALUE); - return ((struct icalvalue_impl*)value)->data.v_enum; + icalerror_check_value_type(value, ICAL_REQUESTSTATUS_VALUE); + return ((struct icalvalue_impl*)value)->data.v_requeststatus; } -icalvalue* icalvalue_new_class (enum icalproperty_class v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_CLASS_VALUE); - - icalvalue_set_class((icalvalue*)impl,v); +icalvalue* icalvalue_new_binary (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_BINARY_VALUE); + icalerror_check_arg_rz( (v!=0),"v"); + + icalvalue_set_binary((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_class(icalvalue* value, enum icalproperty_class v) { +void icalvalue_set_binary(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - - icalerror_check_value_type(value, ICAL_CLASS_VALUE); + icalerror_check_arg_rv( (v!=0),"v"); + + icalerror_check_value_type(value, ICAL_BINARY_VALUE); impl = (struct icalvalue_impl*)value; + if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} - impl->data.v_enum = v; + impl->data.v_string = icalmemory_strdup(v); + + if (impl->data.v_string == 0){ + errno = ENOMEM; + } + icalvalue_reset_kind(impl); } -enum icalproperty_class icalvalue_get_class(icalvalue* value) { +const char* icalvalue_get_binary(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_CLASS_VALUE); - return ((struct icalvalue_impl*)value)->data.v_enum; + icalerror_check_value_type(value, ICAL_BINARY_VALUE); + return ((struct icalvalue_impl*)value)->data.v_string; } -icalvalue* icalvalue_new_date (struct icaltimetype v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DATE_VALUE); +icalvalue* icalvalue_new_period (struct icalperiodtype v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_PERIOD_VALUE); - icalvalue_set_date((icalvalue*)impl,v); + icalvalue_set_period((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_date(icalvalue* value, struct icaltimetype v) { +void icalvalue_set_period(icalvalue* value, struct icalperiodtype v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_DATE_VALUE); + icalerror_check_value_type(value, ICAL_PERIOD_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_time = v; + impl->data.v_period = v; icalvalue_reset_kind(impl); } -struct icaltimetype icalvalue_get_date(icalvalue* value) { +struct icalperiodtype icalvalue_get_period(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_DATE_VALUE); - return ((struct icalvalue_impl*)value)->data.v_time; + icalerror_check_value_type(value, ICAL_PERIOD_VALUE); + return ((struct icalvalue_impl*)value)->data.v_period; } -icalvalue* icalvalue_new_string (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_STRING_VALUE); - icalerror_check_arg_rz( (v!=0),"v"); - - icalvalue_set_string((icalvalue*)impl,v); +icalvalue* icalvalue_new_float (float v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_FLOAT_VALUE); + + icalvalue_set_float((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_string(icalvalue* value, const char* v) { +void icalvalue_set_float(icalvalue* value, float v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_arg_rv( (v!=0),"v"); - - icalerror_check_value_type(value, ICAL_STRING_VALUE); + + icalerror_check_value_type(value, ICAL_FLOAT_VALUE); impl = (struct icalvalue_impl*)value; - if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} - impl->data.v_string = icalmemory_strdup(v); - - if (impl->data.v_string == 0){ - errno = ENOMEM; - } - + impl->data.v_float = v; icalvalue_reset_kind(impl); } -const char* icalvalue_get_string(icalvalue* value) { +float icalvalue_get_float(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_STRING_VALUE); - return ((struct icalvalue_impl*)value)->data.v_string; + icalerror_check_value_type(value, ICAL_FLOAT_VALUE); + return ((struct icalvalue_impl*)value)->data.v_float; } icalvalue* icalvalue_new_integer (int v){ struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_INTEGER_VALUE); icalvalue_set_integer((icalvalue*)impl,v); return (icalvalue*)impl; } void icalvalue_set_integer(icalvalue* value, int v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_value_type(value, ICAL_INTEGER_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_int = v; icalvalue_reset_kind(impl); } -int icalvalue_get_integer(icalvalue* value) { +int icalvalue_get_integer(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); icalerror_check_value_type(value, ICAL_INTEGER_VALUE); return ((struct icalvalue_impl*)value)->data.v_int; } -icalvalue* icalvalue_new_period (struct icalperiodtype v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_PERIOD_VALUE); +icalvalue* icalvalue_new_class (enum icalproperty_class v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_CLASS_VALUE); - icalvalue_set_period((icalvalue*)impl,v); + icalvalue_set_class((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_period(icalvalue* value, struct icalperiodtype v) { +void icalvalue_set_class(icalvalue* value, enum icalproperty_class v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_PERIOD_VALUE); + icalerror_check_value_type(value, ICAL_CLASS_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_period = v; + impl->data.v_enum = v; icalvalue_reset_kind(impl); } -struct icalperiodtype icalvalue_get_period(icalvalue* value) { +enum icalproperty_class icalvalue_get_class(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_PERIOD_VALUE); - return ((struct icalvalue_impl*)value)->data.v_period; + icalerror_check_value_type(value, ICAL_CLASS_VALUE); + return ((struct icalvalue_impl*)value)->data.v_enum; } -icalvalue* icalvalue_new_text (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TEXT_VALUE); +icalvalue* icalvalue_new_uri (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_URI_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_text((icalvalue*)impl,v); + icalvalue_set_uri((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_text(icalvalue* value, const char* v) { +void icalvalue_set_uri(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_TEXT_VALUE); + icalerror_check_value_type(value, ICAL_URI_VALUE); impl = (struct icalvalue_impl*)value; if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} impl->data.v_string = icalmemory_strdup(v); if (impl->data.v_string == 0){ errno = ENOMEM; } icalvalue_reset_kind(impl); } -const char* icalvalue_get_text(icalvalue* value) { +const char* icalvalue_get_uri(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_TEXT_VALUE); + icalerror_check_value_type(value, ICAL_URI_VALUE); return ((struct icalvalue_impl*)value)->data.v_string; } icalvalue* icalvalue_new_duration (struct icaldurationtype v){ struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DURATION_VALUE); icalvalue_set_duration((icalvalue*)impl,v); return (icalvalue*)impl; } void icalvalue_set_duration(icalvalue* value, struct icaldurationtype v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_value_type(value, ICAL_DURATION_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_duration = v; icalvalue_reset_kind(impl); } -struct icaldurationtype icalvalue_get_duration(icalvalue* value) { +struct icaldurationtype icalvalue_get_duration(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); icalerror_check_value_type(value, ICAL_DURATION_VALUE); return ((struct icalvalue_impl*)value)->data.v_duration; } icalvalue* icalvalue_new_boolean (int v){ struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_BOOLEAN_VALUE); icalvalue_set_boolean((icalvalue*)impl,v); return (icalvalue*)impl; } void icalvalue_set_boolean(icalvalue* value, int v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_value_type(value, ICAL_BOOLEAN_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_int = v; icalvalue_reset_kind(impl); } -int icalvalue_get_boolean(icalvalue* value) { +int icalvalue_get_boolean(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); icalerror_check_value_type(value, ICAL_BOOLEAN_VALUE); return ((struct icalvalue_impl*)value)->data.v_int; } -icalvalue* icalvalue_new_uri (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_URI_VALUE); +icalvalue* icalvalue_new_caladdress (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_CALADDRESS_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_uri((icalvalue*)impl,v); + icalvalue_set_caladdress((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_uri(icalvalue* value, const char* v) { +void icalvalue_set_caladdress(icalvalue* value, const char* v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_URI_VALUE); + icalerror_check_value_type(value, ICAL_CALADDRESS_VALUE); impl = (struct icalvalue_impl*)value; if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} impl->data.v_string = icalmemory_strdup(v); if (impl->data.v_string == 0){ errno = ENOMEM; } icalvalue_reset_kind(impl); } -const char* icalvalue_get_uri(icalvalue* value) { +const char* icalvalue_get_caladdress(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_URI_VALUE); + icalerror_check_value_type(value, ICAL_CALADDRESS_VALUE); return ((struct icalvalue_impl*)value)->data.v_string; } -icalvalue* icalvalue_new_geo (struct icalgeotype v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_GEO_VALUE); +icalvalue* icalvalue_new_xlicclass (enum icalproperty_xlicclass v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_XLICCLASS_VALUE); - icalvalue_set_geo((icalvalue*)impl,v); + icalvalue_set_xlicclass((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_geo(icalvalue* value, struct icalgeotype v) { +void icalvalue_set_xlicclass(icalvalue* value, enum icalproperty_xlicclass v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_GEO_VALUE); + icalerror_check_value_type(value, ICAL_XLICCLASS_VALUE); impl = (struct icalvalue_impl*)value; - impl->data.v_geo = v; + impl->data.v_enum = v; icalvalue_reset_kind(impl); } -struct icalgeotype icalvalue_get_geo(icalvalue* value) { +enum icalproperty_xlicclass icalvalue_get_xlicclass(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_GEO_VALUE); - return ((struct icalvalue_impl*)value)->data.v_geo; + icalerror_check_value_type(value, ICAL_XLICCLASS_VALUE); + return ((struct icalvalue_impl*)value)->data.v_enum; +} + + + +icalvalue* icalvalue_new_action (enum icalproperty_action v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_ACTION_VALUE); + + icalvalue_set_action((icalvalue*)impl,v); + return (icalvalue*)impl; +} +void icalvalue_set_action(icalvalue* value, enum icalproperty_action v) { + struct icalvalue_impl* impl; + icalerror_check_arg_rv( (value!=0),"value"); + + icalerror_check_value_type(value, ICAL_ACTION_VALUE); + impl = (struct icalvalue_impl*)value; + + + impl->data.v_enum = v; + + icalvalue_reset_kind(impl); +} +enum icalproperty_action icalvalue_get_action(const icalvalue* value) { + + icalerror_check_arg( (value!=0),"value"); + icalerror_check_value_type(value, ICAL_ACTION_VALUE); + return ((struct icalvalue_impl*)value)->data.v_enum; } icalvalue* icalvalue_new_datetime (struct icaltimetype v){ struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DATETIME_VALUE); icalvalue_set_datetime((icalvalue*)impl,v); return (icalvalue*)impl; } void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_value_type(value, ICAL_DATETIME_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_time = v; icalvalue_reset_kind(impl); } -struct icaltimetype icalvalue_get_datetime(icalvalue* value) { +struct icaltimetype icalvalue_get_datetime(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); icalerror_check_value_type(value, ICAL_DATETIME_VALUE); return ((struct icalvalue_impl*)value)->data.v_time; } icalvalue* icalvalue_new_utcoffset (int v){ struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_UTCOFFSET_VALUE); icalvalue_set_utcoffset((icalvalue*)impl,v); return (icalvalue*)impl; } void icalvalue_set_utcoffset(icalvalue* value, int v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); icalerror_check_value_type(value, ICAL_UTCOFFSET_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_int = v; icalvalue_reset_kind(impl); } -int icalvalue_get_utcoffset(icalvalue* value) { +int icalvalue_get_utcoffset(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); icalerror_check_value_type(value, ICAL_UTCOFFSET_VALUE); return ((struct icalvalue_impl*)value)->data.v_int; } -icalvalue* icalvalue_new_action (enum icalproperty_action v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_ACTION_VALUE); +icalvalue* icalvalue_new_method (enum icalproperty_method v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_METHOD_VALUE); - icalvalue_set_action((icalvalue*)impl,v); + icalvalue_set_method((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_action(icalvalue* value, enum icalproperty_action v) { +void icalvalue_set_method(icalvalue* value, enum icalproperty_method v) { struct icalvalue_impl* impl; icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_ACTION_VALUE); + icalerror_check_value_type(value, ICAL_METHOD_VALUE); impl = (struct icalvalue_impl*)value; impl->data.v_enum = v; icalvalue_reset_kind(impl); } -enum icalproperty_action icalvalue_get_action(icalvalue* value) { +enum icalproperty_method icalvalue_get_method(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_ACTION_VALUE); + icalerror_check_value_type(value, ICAL_METHOD_VALUE); return ((struct icalvalue_impl*)value)->data.v_enum; } +int icalvalue_kind_is_valid(const icalvalue_kind kind) +{ + int i = 0; + do { + if (value_map[i].kind == kind) + return 1; + } while (value_map[i++].kind != ICAL_NO_VALUE); -icalvalue* icalvalue_new_caladdress (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_CALADDRESS_VALUE); + return 0; +} + +const char* icalvalue_kind_to_string(const icalvalue_kind kind) +{ + int i; + + for (i=0; value_map[i].kind != ICAL_NO_VALUE; i++) { + if (value_map[i].kind == kind) { + return value_map[i].name; + } + } + + return 0; +} + +icalvalue_kind icalvalue_string_to_kind(const char* str) +{ + int i; + + for (i=0; value_map[i].kind != ICAL_NO_VALUE; i++) { + if (strcmp(value_map[i].name,str) == 0) { + return value_map[i].kind; + } + } + + return value_map[i].kind; + +} + +icalvalue* icalvalue_new_x (const char* v){ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_X_VALUE); icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_caladdress((icalvalue*)impl,v); + icalvalue_set_x((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_caladdress(icalvalue* value, const char* v) { - struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); +void icalvalue_set_x(icalvalue* impl, const char* v) { + icalerror_check_arg_rv( (impl!=0),"value"); icalerror_check_arg_rv( (v!=0),"v"); - icalerror_check_value_type(value, ICAL_CALADDRESS_VALUE); - impl = (struct icalvalue_impl*)value; - if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} - + if(impl->x_value!=0) {free((void*)impl->x_value);} - impl->data.v_string = icalmemory_strdup(v); + impl->x_value = icalmemory_strdup(v); - if (impl->data.v_string == 0){ + if (impl->x_value == 0){ errno = ENOMEM; } - - icalvalue_reset_kind(impl); -} -const char* icalvalue_get_caladdress(icalvalue* value) { + } +const char* icalvalue_get_x(const icalvalue* value) { icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_CALADDRESS_VALUE); - return ((struct icalvalue_impl*)value)->data.v_string; + icalerror_check_value_type(value, ICAL_X_VALUE); + return value->x_value; } +/* Recur is a special case, so it is not auto generated. */ +icalvalue* +icalvalue_new_recur (struct icalrecurrencetype v) +{ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_RECUR_VALUE); + + icalvalue_set_recur((icalvalue*)impl,v); - -icalvalue* icalvalue_new_float (float v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_FLOAT_VALUE); - - icalvalue_set_float((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_float(icalvalue* value, float v) { - struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); - - icalerror_check_value_type(value, ICAL_FLOAT_VALUE); - impl = (struct icalvalue_impl*)value; +void +icalvalue_set_recur(icalvalue* impl, struct icalrecurrencetype v) +{ + icalerror_check_arg_rv( (impl!=0),"value"); + icalerror_check_value_type(value, ICAL_RECUR_VALUE); - impl->data.v_float = v; + if (impl->data.v_recur != 0){ + free(impl->data.v_recur); + impl->data.v_recur = 0; + } - icalvalue_reset_kind(impl); + impl->data.v_recur = malloc(sizeof(struct icalrecurrencetype)); + + if (impl->data.v_recur == 0){ + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } else { + memcpy(impl->data.v_recur, &v, sizeof(struct icalrecurrencetype)); + } + } -float icalvalue_get_float(icalvalue* value) { +struct icalrecurrencetype +icalvalue_get_recur(const icalvalue* value) +{ icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_FLOAT_VALUE); - return ((struct icalvalue_impl*)value)->data.v_float; + icalerror_check_value_type(value, ICAL_RECUR_VALUE); + + return *(value->data.v_recur); } -icalvalue* icalvalue_new_requeststatus (struct icalreqstattype v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_REQUESTSTATUS_VALUE); - - icalvalue_set_requeststatus((icalvalue*)impl,v); + +icalvalue* +icalvalue_new_trigger (struct icaltriggertype v) +{ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_TRIGGER_VALUE); + + icalvalue_set_trigger((icalvalue*)impl,v); + return (icalvalue*)impl; } -void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v) { - struct icalvalue_impl* impl; + +void +icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v) +{ icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_REQUESTSTATUS_VALUE); - impl = (struct icalvalue_impl*)value; + if(!icaltime_is_null_time(v.time)){ + icalvalue_set_datetime(value,v.time); + value->kind = ICAL_DATETIME_VALUE; + } else { + icalvalue_set_duration(value,v.duration); + value->kind = ICAL_DURATION_VALUE; + } +} +struct icaltriggertype +icalvalue_get_trigger(const icalvalue* impl) +{ + struct icaltriggertype tr; - impl->data.v_requeststatus = v; + icalerror_check_arg( (impl!=0),"value"); + icalerror_check_arg( (impl!=0),"value"); - icalvalue_reset_kind(impl); -} -struct icalreqstattype icalvalue_get_requeststatus(icalvalue* value) { + if(impl->kind == ICAL_DATETIME_VALUE){ + tr.duration = icaldurationtype_from_int(0); + tr.time = impl->data.v_time; + } else if(impl->kind == ICAL_DURATION_VALUE){ + tr.time = icaltime_null_time(); + tr.duration = impl->data.v_duration; + } else { + tr.duration = icaldurationtype_from_int(0); + tr.time = icaltime_null_time(); + icalerror_set_errno(ICAL_BADARG_ERROR); + } - icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_REQUESTSTATUS_VALUE); - return ((struct icalvalue_impl*)value)->data.v_requeststatus; + return tr; } +/* DATE-TIME-PERIOD is a special case, and is not auto generated */ +icalvalue* +icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v) +{ + struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_DATETIMEPERIOD_VALUE); + + icalvalue_set_datetimeperiod(impl,v); -icalvalue* icalvalue_new_method (enum icalproperty_method v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_METHOD_VALUE); - - icalvalue_set_method((icalvalue*)impl,v); return (icalvalue*)impl; } -void icalvalue_set_method(icalvalue* value, enum icalproperty_method v) { - struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); - - icalerror_check_value_type(value, ICAL_METHOD_VALUE); - impl = (struct icalvalue_impl*)value; - - impl->data.v_enum = v; +void +icalvalue_set_datetimeperiod(icalvalue* impl, struct icaldatetimeperiodtype v) +{ + icalerror_check_arg_rv( (impl!=0),"value"); + + icalerror_check_value_type(value, ICAL_DATETIMEPERIOD_VALUE); - icalvalue_reset_kind(impl); + if(!icaltime_is_null_time(v.time)){ + if(!icaltime_is_valid_time(v.time)){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return; + } + impl->kind = ICAL_DATETIME_VALUE; + icalvalue_set_datetime(impl,v.time); + } else if (!icalperiodtype_is_null_period(v.period)) { + if(!icalperiodtype_is_valid_period(v.period)){ + icalerror_set_errno(ICAL_BADARG_ERROR); + return; + } + impl->kind = ICAL_PERIOD_VALUE; + icalvalue_set_period(impl,v.period); + } else { + icalerror_set_errno(ICAL_BADARG_ERROR); + } } -enum icalproperty_method icalvalue_get_method(icalvalue* value) { - icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_METHOD_VALUE); - return ((struct icalvalue_impl*)value)->data.v_enum; -} +struct icaldatetimeperiodtype +icalvalue_get_datetimeperiod(const icalvalue* impl) +{ + struct icaldatetimeperiodtype dtp; + + icalerror_check_arg( (impl!=0),"value"); + icalerror_check_value_type(value, ICAL_DATETIMEPERIOD_VALUE); + + if(impl->kind == ICAL_DATETIME_VALUE){ + dtp.period = icalperiodtype_null_period(); + dtp.time = impl->data.v_time; + } else if(impl->kind == ICAL_PERIOD_VALUE) { + dtp.period = impl->data.v_period; + dtp.time = icaltime_null_time(); + } else { + dtp.period = icalperiodtype_null_period(); + dtp.time = icaltime_null_time(); + icalerror_set_errno(ICAL_BADARG_ERROR); + } + return dtp; +} -icalvalue* icalvalue_new_binary (const char* v){ - struct icalvalue_impl* impl = icalvalue_new_impl(ICAL_BINARY_VALUE); - icalerror_check_arg_rz( (v!=0),"v"); - icalvalue_set_binary((icalvalue*)impl,v); - return (icalvalue*)impl; -} -void icalvalue_set_binary(icalvalue* value, const char* v) { - struct icalvalue_impl* impl; - icalerror_check_arg_rv( (value!=0),"value"); - icalerror_check_arg_rv( (v!=0),"v"); +icalvalue * +icalvalue_new_attach (icalattach *attach) +{ + struct icalvalue_impl *impl; - icalerror_check_value_type(value, ICAL_BINARY_VALUE); - impl = (struct icalvalue_impl*)value; - if(impl->data.v_string!=0) {free((void*)impl->data.v_string);} + icalerror_check_arg_rz ((attach != NULL), "attach"); + impl = icalvalue_new_impl (ICAL_ATTACH_VALUE); + if (!impl) { + errno = ENOMEM; + return NULL; + } - impl->data.v_string = icalmemory_strdup(v); + icalvalue_set_attach ((icalvalue *) impl, attach); + return (icalvalue *) impl; +} - if (impl->data.v_string == 0){ - errno = ENOMEM; - } +void +icalvalue_set_attach (icalvalue *value, icalattach *attach) +{ + struct icalvalue_impl *impl; + + icalerror_check_arg_rv ((value != NULL), "value"); + icalerror_check_value_type (value, ICAL_ATTACH_VALUE); + icalerror_check_arg_rv ((attach != NULL), "attach"); + + impl = (struct icalvalue_impl *) value; + icalattach_ref (attach); - icalvalue_reset_kind(impl); + if (impl->data.v_attach) + icalattach_unref (impl->data.v_attach); + + impl->data.v_attach = attach; } -const char* icalvalue_get_binary(icalvalue* value) { - icalerror_check_arg( (value!=0),"value"); - icalerror_check_value_type(value, ICAL_BINARY_VALUE); - return ((struct icalvalue_impl*)value)->data.v_string; +icalattach * +icalvalue_get_attach (const icalvalue *value) +{ + icalerror_check_arg_rz ((value != NULL), "value"); + icalerror_check_value_type (value, ICAL_ATTACH_VALUE); + + return value->data.v_attach; } + + + + + + + +/* The remaining interfaces are 'new', 'set' and 'get' for each of the value + types */ + + +/* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icalderivedvalue.h b/libical/src/libical/icalderivedvalue.h index 8324f04..7043ae7 100644 --- a/libical/src/libical/icalderivedvalue.h +++ b/libical/src/libical/icalderivedvalue.h @@ -1,283 +1,324 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalvalue.h CREATOR: eric 20 March 1999 $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 icalvalue.h ======================================================================*/ #ifndef ICALDERIVEDVALUE_H #define ICALDERIVEDVALUE_H #include "icaltypes.h" #include "icalrecur.h" #include "icaltime.h" #include "icalduration.h" #include "icalperiod.h" +#include "icalattach.h" -typedef void icalvalue; +typedef struct icalvalue_impl icalvalue; void icalvalue_set_x(icalvalue* value, const char* v); icalvalue* icalvalue_new_x(const char* v); -const char* icalvalue_get_x(icalvalue* value); - -icalvalue* icalvalue_new_attach (struct icalattachtype* v); -void icalvalue_set_attach(icalvalue* value, struct icalattachtype* v); -struct icalattachtype* icalvalue_get_attach(icalvalue* value); +const char* icalvalue_get_x(const icalvalue* value); icalvalue* icalvalue_new_recur (struct icalrecurrencetype v); void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); -struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); +struct icalrecurrencetype icalvalue_get_recur(const icalvalue* value); icalvalue* icalvalue_new_trigger (struct icaltriggertype v); void icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v); -struct icaltriggertype icalvalue_get_trigger(icalvalue* value); +struct icaltriggertype icalvalue_get_trigger(const icalvalue* value); icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); void icalvalue_set_datetimeperiod(icalvalue* value, struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(icalvalue* value); +struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(const icalvalue* value); + +icalvalue *icalvalue_new_attach (icalattach *attach); +void icalvalue_set_attach (icalvalue *value, icalattach *attach); +icalattach *icalvalue_get_attach (const icalvalue *value); void icalvalue_reset_kind(icalvalue* value); -/* Everything below this line is machine generated. Do not edit. */ typedef enum icalvalue_kind { ICAL_ANY_VALUE=5000, ICAL_QUERY_VALUE=5001, - ICAL_TRIGGER_VALUE=5002, - ICAL_STATUS_VALUE=5003, - ICAL_TRANSP_VALUE=5004, - ICAL_CLASS_VALUE=5005, - ICAL_DATE_VALUE=5006, + ICAL_DATE_VALUE=5002, + ICAL_ATTACH_VALUE=5003, + ICAL_GEO_VALUE=5004, + ICAL_STATUS_VALUE=5005, + ICAL_TRANSP_VALUE=5006, ICAL_STRING_VALUE=5007, - ICAL_INTEGER_VALUE=5008, - ICAL_PERIOD_VALUE=5009, - ICAL_TEXT_VALUE=5010, - ICAL_DURATION_VALUE=5011, - ICAL_BOOLEAN_VALUE=5012, - ICAL_URI_VALUE=5013, - ICAL_DATETIMEPERIOD_VALUE=5014, - ICAL_GEO_VALUE=5015, - ICAL_DATETIME_VALUE=5016, - ICAL_UTCOFFSET_VALUE=5017, - ICAL_ATTACH_VALUE=5018, - ICAL_ACTION_VALUE=5019, + ICAL_TEXT_VALUE=5008, + ICAL_REQUESTSTATUS_VALUE=5009, + ICAL_BINARY_VALUE=5010, + ICAL_PERIOD_VALUE=5011, + ICAL_FLOAT_VALUE=5012, + ICAL_DATETIMEPERIOD_VALUE=5013, + ICAL_INTEGER_VALUE=5014, + ICAL_CLASS_VALUE=5015, + ICAL_URI_VALUE=5016, + ICAL_DURATION_VALUE=5017, + ICAL_BOOLEAN_VALUE=5018, + ICAL_X_VALUE=5019, ICAL_CALADDRESS_VALUE=5020, - ICAL_X_VALUE=5021, - ICAL_FLOAT_VALUE=5022, - ICAL_REQUESTSTATUS_VALUE=5023, - ICAL_METHOD_VALUE=5024, - ICAL_BINARY_VALUE=5025, - ICAL_RECUR_VALUE=5026, - ICAL_NO_VALUE=5027 + ICAL_TRIGGER_VALUE=5021, + ICAL_XLICCLASS_VALUE=5022, + ICAL_RECUR_VALUE=5023, + ICAL_ACTION_VALUE=5024, + ICAL_DATETIME_VALUE=5025, + ICAL_UTCOFFSET_VALUE=5026, + ICAL_METHOD_VALUE=5027, + ICAL_NO_VALUE=5028 } icalvalue_kind ; #define ICALPROPERTY_FIRST_ENUM 10000 typedef enum icalproperty_action { ICAL_ACTION_X = 10000, ICAL_ACTION_AUDIO = 10001, ICAL_ACTION_DISPLAY = 10002, ICAL_ACTION_EMAIL = 10003, ICAL_ACTION_PROCEDURE = 10004, ICAL_ACTION_NONE = 10005 } icalproperty_action; typedef enum icalproperty_class { ICAL_CLASS_X = 10006, ICAL_CLASS_PUBLIC = 10007, ICAL_CLASS_PRIVATE = 10008, ICAL_CLASS_CONFIDENTIAL = 10009, ICAL_CLASS_NONE = 10010 } icalproperty_class; typedef enum icalproperty_method { ICAL_METHOD_X = 10011, ICAL_METHOD_PUBLISH = 10012, ICAL_METHOD_REQUEST = 10013, ICAL_METHOD_REPLY = 10014, ICAL_METHOD_ADD = 10015, ICAL_METHOD_CANCEL = 10016, ICAL_METHOD_REFRESH = 10017, ICAL_METHOD_COUNTER = 10018, ICAL_METHOD_DECLINECOUNTER = 10019, ICAL_METHOD_CREATE = 10020, ICAL_METHOD_READ = 10021, ICAL_METHOD_RESPONSE = 10022, ICAL_METHOD_MOVE = 10023, ICAL_METHOD_MODIFY = 10024, ICAL_METHOD_GENERATEUID = 10025, ICAL_METHOD_DELETE = 10026, ICAL_METHOD_NONE = 10027 } icalproperty_method; typedef enum icalproperty_status { ICAL_STATUS_X = 10028, ICAL_STATUS_TENTATIVE = 10029, ICAL_STATUS_CONFIRMED = 10030, ICAL_STATUS_COMPLETED = 10031, ICAL_STATUS_NEEDSACTION = 10032, ICAL_STATUS_CANCELLED = 10033, ICAL_STATUS_INPROCESS = 10034, ICAL_STATUS_DRAFT = 10035, ICAL_STATUS_FINAL = 10036, ICAL_STATUS_NONE = 10037 } icalproperty_status; typedef enum icalproperty_transp { ICAL_TRANSP_X = 10038, ICAL_TRANSP_OPAQUE = 10039, - ICAL_TRANSP_TRANSPARENT = 10040, - ICAL_TRANSP_NONE = 10041 + ICAL_TRANSP_OPAQUENOCONFLICT = 10040, + ICAL_TRANSP_TRANSPARENT = 10041, + ICAL_TRANSP_TRANSPARENTNOCONFLICT = 10042, + ICAL_TRANSP_NONE = 10043 } icalproperty_transp; -#define ICALPROPERTY_LAST_ENUM 10042 +typedef enum icalproperty_xlicclass { + ICAL_XLICCLASS_X = 10044, + ICAL_XLICCLASS_PUBLISHNEW = 10045, + ICAL_XLICCLASS_PUBLISHUPDATE = 10046, + ICAL_XLICCLASS_PUBLISHFREEBUSY = 10047, + ICAL_XLICCLASS_REQUESTNEW = 10048, + ICAL_XLICCLASS_REQUESTUPDATE = 10049, + ICAL_XLICCLASS_REQUESTRESCHEDULE = 10050, + ICAL_XLICCLASS_REQUESTDELEGATE = 10051, + ICAL_XLICCLASS_REQUESTNEWORGANIZER = 10052, + ICAL_XLICCLASS_REQUESTFORWARD = 10053, + ICAL_XLICCLASS_REQUESTSTATUS = 10054, + ICAL_XLICCLASS_REQUESTFREEBUSY = 10055, + ICAL_XLICCLASS_REPLYACCEPT = 10056, + ICAL_XLICCLASS_REPLYDECLINE = 10057, + ICAL_XLICCLASS_REPLYDELEGATE = 10058, + ICAL_XLICCLASS_REPLYCRASHERACCEPT = 10059, + ICAL_XLICCLASS_REPLYCRASHERDECLINE = 10060, + ICAL_XLICCLASS_ADDINSTANCE = 10061, + ICAL_XLICCLASS_CANCELEVENT = 10062, + ICAL_XLICCLASS_CANCELINSTANCE = 10063, + ICAL_XLICCLASS_CANCELALL = 10064, + ICAL_XLICCLASS_REFRESH = 10065, + ICAL_XLICCLASS_COUNTER = 10066, + ICAL_XLICCLASS_DECLINECOUNTER = 10067, + ICAL_XLICCLASS_MALFORMED = 10068, + ICAL_XLICCLASS_OBSOLETE = 10069, + ICAL_XLICCLASS_MISSEQUENCED = 10070, + ICAL_XLICCLASS_UNKNOWN = 10071, + ICAL_XLICCLASS_NONE = 10072 +} icalproperty_xlicclass; + +#define ICALPROPERTY_LAST_ENUM 10073 /* QUERY */ icalvalue* icalvalue_new_query(const char* v); -const char* icalvalue_get_query(icalvalue* value); +const char* icalvalue_get_query(const icalvalue* value); void icalvalue_set_query(icalvalue* value, const char* v); + /* DATE */ +icalvalue* icalvalue_new_date(struct icaltimetype v); +struct icaltimetype icalvalue_get_date(const icalvalue* value); +void icalvalue_set_date(icalvalue* value, struct icaltimetype v); + + + /* GEO */ +icalvalue* icalvalue_new_geo(struct icalgeotype v); +struct icalgeotype icalvalue_get_geo(const icalvalue* value); +void icalvalue_set_geo(icalvalue* value, struct icalgeotype v); + + /* STATUS */ icalvalue* icalvalue_new_status(enum icalproperty_status v); -enum icalproperty_status icalvalue_get_status(icalvalue* value); +enum icalproperty_status icalvalue_get_status(const icalvalue* value); void icalvalue_set_status(icalvalue* value, enum icalproperty_status v); /* TRANSP */ icalvalue* icalvalue_new_transp(enum icalproperty_transp v); -enum icalproperty_transp icalvalue_get_transp(icalvalue* value); +enum icalproperty_transp icalvalue_get_transp(const icalvalue* value); void icalvalue_set_transp(icalvalue* value, enum icalproperty_transp v); - /* CLASS */ -icalvalue* icalvalue_new_class(enum icalproperty_class v); -enum icalproperty_class icalvalue_get_class(icalvalue* value); -void icalvalue_set_class(icalvalue* value, enum icalproperty_class v); + /* STRING */ +icalvalue* icalvalue_new_string(const char* v); +const char* icalvalue_get_string(const icalvalue* value); +void icalvalue_set_string(icalvalue* value, const char* v); - /* DATE */ -icalvalue* icalvalue_new_date(struct icaltimetype v); -struct icaltimetype icalvalue_get_date(icalvalue* value); -void icalvalue_set_date(icalvalue* value, struct icaltimetype v); + /* TEXT */ +icalvalue* icalvalue_new_text(const char* v); +const char* icalvalue_get_text(const icalvalue* value); +void icalvalue_set_text(icalvalue* value, const char* v); - /* STRING */ -icalvalue* icalvalue_new_string(const char* v); -const char* icalvalue_get_string(icalvalue* value); -void icalvalue_set_string(icalvalue* value, const char* v); + /* REQUEST-STATUS */ +icalvalue* icalvalue_new_requeststatus(struct icalreqstattype v); +struct icalreqstattype icalvalue_get_requeststatus(const icalvalue* value); +void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v); - /* INTEGER */ -icalvalue* icalvalue_new_integer(int v); -int icalvalue_get_integer(icalvalue* value); -void icalvalue_set_integer(icalvalue* value, int v); + /* BINARY */ +icalvalue* icalvalue_new_binary(const char* v); +const char* icalvalue_get_binary(const icalvalue* value); +void icalvalue_set_binary(icalvalue* value, const char* v); /* PERIOD */ icalvalue* icalvalue_new_period(struct icalperiodtype v); -struct icalperiodtype icalvalue_get_period(icalvalue* value); +struct icalperiodtype icalvalue_get_period(const icalvalue* value); void icalvalue_set_period(icalvalue* value, struct icalperiodtype v); - /* TEXT */ -icalvalue* icalvalue_new_text(const char* v); -const char* icalvalue_get_text(icalvalue* value); -void icalvalue_set_text(icalvalue* value, const char* v); + /* FLOAT */ +icalvalue* icalvalue_new_float(float v); +float icalvalue_get_float(const icalvalue* value); +void icalvalue_set_float(icalvalue* value, float v); - /* DURATION */ -icalvalue* icalvalue_new_duration(struct icaldurationtype v); -struct icaldurationtype icalvalue_get_duration(icalvalue* value); -void icalvalue_set_duration(icalvalue* value, struct icaldurationtype v); + /* INTEGER */ +icalvalue* icalvalue_new_integer(int v); +int icalvalue_get_integer(const icalvalue* value); +void icalvalue_set_integer(icalvalue* value, int v); - /* BOOLEAN */ -icalvalue* icalvalue_new_boolean(int v); -int icalvalue_get_boolean(icalvalue* value); -void icalvalue_set_boolean(icalvalue* value, int v); + /* CLASS */ +icalvalue* icalvalue_new_class(enum icalproperty_class v); +enum icalproperty_class icalvalue_get_class(const icalvalue* value); +void icalvalue_set_class(icalvalue* value, enum icalproperty_class v); /* URI */ icalvalue* icalvalue_new_uri(const char* v); -const char* icalvalue_get_uri(icalvalue* value); +const char* icalvalue_get_uri(const icalvalue* value); void icalvalue_set_uri(icalvalue* value, const char* v); - /* GEO */ -icalvalue* icalvalue_new_geo(struct icalgeotype v); -struct icalgeotype icalvalue_get_geo(icalvalue* value); -void icalvalue_set_geo(icalvalue* value, struct icalgeotype v); + /* DURATION */ +icalvalue* icalvalue_new_duration(struct icaldurationtype v); +struct icaldurationtype icalvalue_get_duration(const icalvalue* value); +void icalvalue_set_duration(icalvalue* value, struct icaldurationtype v); - /* DATE-TIME */ -icalvalue* icalvalue_new_datetime(struct icaltimetype v); -struct icaltimetype icalvalue_get_datetime(icalvalue* value); -void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); + /* BOOLEAN */ +icalvalue* icalvalue_new_boolean(int v); +int icalvalue_get_boolean(const icalvalue* value); +void icalvalue_set_boolean(icalvalue* value, int v); - /* UTC-OFFSET */ -icalvalue* icalvalue_new_utcoffset(int v); -int icalvalue_get_utcoffset(icalvalue* value); -void icalvalue_set_utcoffset(icalvalue* value, int v); + /* CAL-ADDRESS */ +icalvalue* icalvalue_new_caladdress(const char* v); +const char* icalvalue_get_caladdress(const icalvalue* value); +void icalvalue_set_caladdress(icalvalue* value, const char* v); + + + /* X-LIC-CLASS */ +icalvalue* icalvalue_new_xlicclass(enum icalproperty_xlicclass v); +enum icalproperty_xlicclass icalvalue_get_xlicclass(const icalvalue* value); +void icalvalue_set_xlicclass(icalvalue* value, enum icalproperty_xlicclass v); /* ACTION */ icalvalue* icalvalue_new_action(enum icalproperty_action v); -enum icalproperty_action icalvalue_get_action(icalvalue* value); +enum icalproperty_action icalvalue_get_action(const icalvalue* value); void icalvalue_set_action(icalvalue* value, enum icalproperty_action v); - /* CAL-ADDRESS */ -icalvalue* icalvalue_new_caladdress(const char* v); -const char* icalvalue_get_caladdress(icalvalue* value); -void icalvalue_set_caladdress(icalvalue* value, const char* v); - - - /* FLOAT */ -icalvalue* icalvalue_new_float(float v); -float icalvalue_get_float(icalvalue* value); -void icalvalue_set_float(icalvalue* value, float v); + /* DATE-TIME */ +icalvalue* icalvalue_new_datetime(struct icaltimetype v); +struct icaltimetype icalvalue_get_datetime(const icalvalue* value); +void icalvalue_set_datetime(icalvalue* value, struct icaltimetype v); - /* REQUEST-STATUS */ -icalvalue* icalvalue_new_requeststatus(struct icalreqstattype v); -struct icalreqstattype icalvalue_get_requeststatus(icalvalue* value); -void icalvalue_set_requeststatus(icalvalue* value, struct icalreqstattype v); + /* UTC-OFFSET */ +icalvalue* icalvalue_new_utcoffset(int v); +int icalvalue_get_utcoffset(const icalvalue* value); +void icalvalue_set_utcoffset(icalvalue* value, int v); /* METHOD */ icalvalue* icalvalue_new_method(enum icalproperty_method v); -enum icalproperty_method icalvalue_get_method(icalvalue* value); +enum icalproperty_method icalvalue_get_method(const icalvalue* value); void icalvalue_set_method(icalvalue* value, enum icalproperty_method v); - - /* BINARY */ -icalvalue* icalvalue_new_binary(const char* v); -const char* icalvalue_get_binary(icalvalue* value); -void icalvalue_set_binary(icalvalue* value, const char* v); - #endif /*ICALVALUE_H*/ 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)); } diff --git a/libical/src/libical/icalduration.h b/libical/src/libical/icalduration.h index dd6e311..0e64cad 100644 --- a/libical/src/libical/icalduration.h +++ b/libical/src/libical/icalduration.h @@ -1,60 +1,62 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalduration.h CREATOR: eric 26 Jan 2001 $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 ======================================================================*/ #ifndef ICALDURATION_H #define ICALDURATION_H #include "icaltime.h" struct icaldurationtype { int is_neg; unsigned int days; unsigned int weeks; unsigned int hours; unsigned int minutes; unsigned int seconds; }; struct icaldurationtype icaldurationtype_from_int(int t); struct icaldurationtype icaldurationtype_from_string(const char*); int icaldurationtype_as_int(struct icaldurationtype duration); char* icaldurationtype_as_ical_string(struct icaldurationtype d); -struct icaldurationtype icaldurationtype_null_duration(); +struct icaldurationtype icaldurationtype_null_duration(void); +struct icaldurationtype icaldurationtype_bad_duration(void); int icaldurationtype_is_null_duration(struct icaldurationtype d); +int icaldurationtype_is_bad_duration(struct icaldurationtype d); struct icaltimetype icaltime_add(struct icaltimetype t, struct icaldurationtype d); struct icaldurationtype icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2); #endif /* !ICALDURATION_H */ diff --git a/libical/src/libical/icalenums.c b/libical/src/libical/icalenums.c index 6751933..66c5ccd 100644 --- a/libical/src/libical/icalenums.c +++ b/libical/src/libical/icalenums.c @@ -1,135 +1,166 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalenum.c CREATOR: eric 29 April 1999 $Id$ (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 icalenum.c ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "icalenums.h" #include <stdio.h> /* For fprintf */ #include <stdio.h> /* For stderr */ #include <string.h> /* For strncmp */ #include <assert.h> +#include "icalmemory.h" - - -struct { +/*** @brief Allowed request status values + */ +static struct { enum icalrequeststatus kind; int major; int minor; const char* str; } request_status_map[] = { {ICAL_2_0_SUCCESS_STATUS, 2,0,"Success."}, {ICAL_2_1_FALLBACK_STATUS, 2,1,"Success but fallback taken on one or more property values."}, {ICAL_2_2_IGPROP_STATUS, 2,2,"Success, invalid property ignored."}, {ICAL_2_3_IGPARAM_STATUS, 2,3,"Success, invalid property parameter ignored."}, {ICAL_2_4_IGXPROP_STATUS, 2,4,"Success, unknown non-standard property ignored."}, {ICAL_2_5_IGXPARAM_STATUS, 2,5,"Success, unknown non standard property value ignored."}, {ICAL_2_6_IGCOMP_STATUS, 2,6,"Success, invalid calendar component ignored."}, {ICAL_2_7_FORWARD_STATUS, 2,7,"Success, request forwarded to Calendar User."}, {ICAL_2_8_ONEEVENT_STATUS, 2,8,"Success, repeating event ignored. Scheduled as a single component."}, {ICAL_2_9_TRUNC_STATUS, 2,9,"Success, truncated end date time to date boundary."}, {ICAL_2_10_ONETODO_STATUS, 2,10,"Success, repeating VTODO ignored. Scheduled as a single VTODO."}, {ICAL_2_11_TRUNCRRULE_STATUS, 2,11,"Success, unbounded RRULE clipped at some finite number of instances "}, {ICAL_3_0_INVPROPNAME_STATUS, 3,0,"Invalid property name."}, {ICAL_3_1_INVPROPVAL_STATUS, 3,1,"Invalid property value."}, {ICAL_3_2_INVPARAM_STATUS, 3,2,"Invalid property parameter."}, {ICAL_3_3_INVPARAMVAL_STATUS, 3,3,"Invalid property parameter value."}, {ICAL_3_4_INVCOMP_STATUS, 3,4,"Invalid calendar component."}, {ICAL_3_5_INVTIME_STATUS, 3,5,"Invalid date or time."}, {ICAL_3_6_INVRULE_STATUS, 3,6,"Invalid rule."}, {ICAL_3_7_INVCU_STATUS, 3,7,"Invalid Calendar User."}, {ICAL_3_8_NOAUTH_STATUS, 3,8,"No authority."}, {ICAL_3_9_BADVERSION_STATUS, 3,9,"Unsupported version."}, {ICAL_3_10_TOOBIG_STATUS, 3,10,"Request entity too large."}, {ICAL_3_11_MISSREQCOMP_STATUS, 3,11,"Required component or property missing."}, {ICAL_3_12_UNKCOMP_STATUS, 3,12,"Unknown component or property found."}, {ICAL_3_13_BADCOMP_STATUS, 3,13,"Unsupported component or property found"}, {ICAL_3_14_NOCAP_STATUS, 3,14,"Unsupported capability."}, + {ICAL_3_15_INVCOMMAND, 3,15,"Invalid command."}, {ICAL_4_0_BUSY_STATUS, 4,0,"Event conflict. Date/time is busy."}, + {ICAL_4_1_STORE_ACCESS_DENIED, 4,1,"Store Access Denied."}, + {ICAL_4_2_STORE_FAILED, 4,2,"Store Failed."}, + {ICAL_4_3_STORE_NOT_FOUND, 4,3,"Store not found."}, {ICAL_5_0_MAYBE_STATUS, 5,0,"Request MAY supported."}, {ICAL_5_1_UNAVAIL_STATUS, 5,1,"Service unavailable."}, {ICAL_5_2_NOSERVICE_STATUS, 5,2,"Invalid calendar service."}, {ICAL_5_3_NOSCHED_STATUS, 5,3,"No scheduling support for user."}, + {ICAL_6_1_CONTAINER_NOT_FOUND, 6,1,"Container not found."}, + {ICAL_9_0_UNRECOGNIZED_COMMAND, 9,0,"An unrecognized command was received."}, {ICAL_UNKNOWN_STATUS, 0,0,"Error: Unknown request status"} }; +/*** @brief Return the descriptive text for a request status + */ const char* icalenum_reqstat_desc(icalrequeststatus stat) { - int i; for (i=0; request_status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { if ( request_status_map[i].kind == stat) { return request_status_map[i].str; } } return 0; } +/*** @brief Return the code for a request status + */ +char* icalenum_reqstat_code(icalrequeststatus stat) +{ + int i, major, minor; + char tmpbuf[36]; + + for (i=0; request_status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { + if ( request_status_map[i].kind == stat) { + major = request_status_map[i].major; + minor = request_status_map[i].minor; + sprintf(tmpbuf, "%i.%i", major, minor); + return icalmemory_tmp_copy(tmpbuf); + } + } + return NULL; +} +/*** @brief Return the major number for a request status + */ short icalenum_reqstat_major(icalrequeststatus stat) { int i; for (i=0; request_status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { if ( request_status_map[i].kind == stat) { return request_status_map[i].major; } } return -1; } +/*** @brief Return the minor number for a request status + */ short icalenum_reqstat_minor(icalrequeststatus stat) { int i; for (i=0; request_status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { if ( request_status_map[i].kind == stat) { return request_status_map[i].minor; } } return -1; } +/*** @brief Return a request status for major/minor status numbers + */ icalrequeststatus icalenum_num_to_reqstat(short major, short minor) { int i; for (i=0; request_status_map[i].kind != ICAL_UNKNOWN_STATUS; i++) { if ( request_status_map[i].major == major && request_status_map[i].minor == minor) { return request_status_map[i].kind; } } return 0; } diff --git a/libical/src/libical/icalenums.h b/libical/src/libical/icalenums.h index 21031dd..b00907f 100644 --- a/libical/src/libical/icalenums.h +++ b/libical/src/libical/icalenums.h @@ -1,157 +1,165 @@ /* -*- Mode: C -*-*/ /*====================================================================== FILE: icalenums.h (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 icalenums.h Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifndef ICALENUMS_H #define ICALENUMS_H /*********************************************************************** * Component enumerations **********************************************************************/ typedef enum icalcomponent_kind { ICAL_NO_COMPONENT, ICAL_ANY_COMPONENT, /* Used to select all components*/ ICAL_XROOT_COMPONENT, ICAL_XATTACH_COMPONENT, /* MIME attached data, returned by parser. */ ICAL_VEVENT_COMPONENT, ICAL_VTODO_COMPONENT, ICAL_VJOURNAL_COMPONENT, ICAL_VCALENDAR_COMPONENT, + ICAL_VAGENDA_COMPONENT, ICAL_VFREEBUSY_COMPONENT, ICAL_VALARM_COMPONENT, ICAL_XAUDIOALARM_COMPONENT, ICAL_XDISPLAYALARM_COMPONENT, ICAL_XEMAILALARM_COMPONENT, ICAL_XPROCEDUREALARM_COMPONENT, ICAL_VTIMEZONE_COMPONENT, ICAL_XSTANDARD_COMPONENT, ICAL_XDAYLIGHT_COMPONENT, ICAL_X_COMPONENT, ICAL_VSCHEDULE_COMPONENT, ICAL_VQUERY_COMPONENT, ICAL_VCAR_COMPONENT, ICAL_VCOMMAND_COMPONENT, ICAL_XLICINVALID_COMPONENT, ICAL_XLICMIMEPART_COMPONENT /* a non-stardard component that mirrors structure of MIME data */ } icalcomponent_kind; /*********************************************************************** * Request Status codes **********************************************************************/ typedef enum icalrequeststatus { ICAL_UNKNOWN_STATUS, ICAL_2_0_SUCCESS_STATUS, ICAL_2_1_FALLBACK_STATUS, ICAL_2_2_IGPROP_STATUS, ICAL_2_3_IGPARAM_STATUS, ICAL_2_4_IGXPROP_STATUS, ICAL_2_5_IGXPARAM_STATUS, ICAL_2_6_IGCOMP_STATUS, ICAL_2_7_FORWARD_STATUS, ICAL_2_8_ONEEVENT_STATUS, ICAL_2_9_TRUNC_STATUS, ICAL_2_10_ONETODO_STATUS, ICAL_2_11_TRUNCRRULE_STATUS, ICAL_3_0_INVPROPNAME_STATUS, ICAL_3_1_INVPROPVAL_STATUS, ICAL_3_2_INVPARAM_STATUS, ICAL_3_3_INVPARAMVAL_STATUS, ICAL_3_4_INVCOMP_STATUS, ICAL_3_5_INVTIME_STATUS, ICAL_3_6_INVRULE_STATUS, ICAL_3_7_INVCU_STATUS, ICAL_3_8_NOAUTH_STATUS, ICAL_3_9_BADVERSION_STATUS, ICAL_3_10_TOOBIG_STATUS, ICAL_3_11_MISSREQCOMP_STATUS, ICAL_3_12_UNKCOMP_STATUS, ICAL_3_13_BADCOMP_STATUS, ICAL_3_14_NOCAP_STATUS, + ICAL_3_15_INVCOMMAND, ICAL_4_0_BUSY_STATUS, + ICAL_4_1_STORE_ACCESS_DENIED, + ICAL_4_2_STORE_FAILED, + ICAL_4_3_STORE_NOT_FOUND, ICAL_5_0_MAYBE_STATUS, ICAL_5_1_UNAVAIL_STATUS, ICAL_5_2_NOSERVICE_STATUS, - ICAL_5_3_NOSCHED_STATUS + ICAL_5_3_NOSCHED_STATUS, + ICAL_6_1_CONTAINER_NOT_FOUND, + ICAL_9_0_UNRECOGNIZED_COMMAND } icalrequeststatus; const char* icalenum_reqstat_desc(icalrequeststatus stat); short icalenum_reqstat_major(icalrequeststatus stat); short icalenum_reqstat_minor(icalrequeststatus stat); icalrequeststatus icalenum_num_to_reqstat(short major, short minor); +char* icalenum_reqstat_code(icalrequeststatus stat); /*********************************************************************** * Conversion functions **********************************************************************/ /* Thse routines used to be in icalenums.c, but were moved into the icalproperty, icalparameter, icalvalue, or icalcomponent modules. */ /* const char* icalproperty_kind_to_string(icalproperty_kind kind);*/ #define icalenum_property_kind_to_string(x) icalproperty_kind_to_string(x) /*icalproperty_kind icalproperty_string_to_kind(const char* string)*/ #define icalenum_string_to_property_kind(x) icalproperty_string_to_kind(x) /*icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind);*/ #define icalenum_property_kind_to_value_kind(x) icalproperty_kind_to_value_kind(x) /*const char* icalenum_method_to_string(icalproperty_method);*/ #define icalenum_method_to_string(x) icalproperty_method_to_string(x) /*icalproperty_method icalenum_string_to_method(const char* string);*/ #define icalenum_string_to_method(x) icalproperty_string_to_method(x) /*const char* icalenum_status_to_string(icalproperty_status);*/ #define icalenum_status_to_string(x) icalproperty_status_to_string(x) /*icalproperty_status icalenum_string_to_status(const char* string);*/ #define icalenum_string_to_status(x) icalproperty_string_to_status(x) /*icalvalue_kind icalenum_string_to_value_kind(const char* str);*/ #define icalenum_string_to_value_kind(x) icalvalue_string_to_kind(x) /*const char* icalenum_value_kind_to_string(icalvalue_kind kind);*/ #define icalenum_value_kind_to_string(x) icalvalue_kind_to_string(x) /*const char* icalenum_component_kind_to_string(icalcomponent_kind kind);*/ #define icalenum_component_kind_to_string(x) icalcomponent_kind_to_string(x) /*icalcomponent_kind icalenum_string_to_component_kind(const char* string);*/ #define icalenum_string_to_component_kind(x) icalcomponent_string_to_kind(x) #endif /* !ICALENUMS_H */ diff --git a/libical/src/libical/icalerror.c b/libical/src/libical/icalerror.c index d44d37a..61043b2 100644 --- a/libical/src/libical/icalerror.c +++ b/libical/src/libical/icalerror.c @@ -1,209 +1,251 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalerror.c CREATOR: eric 16 May 1999 $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 icalerror.c ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#include <stdlib.h> /* for malloc() */ +#include <string.h> /* for strcmp */ #include "icalerror.h" -#include <string.h> +#ifdef HAVE_PTHREAD +#include <pthread.h> -icalerrorenum icalerrno; +static pthread_key_t icalerrno_key; +static pthread_once_t icalerrno_key_once = PTHREAD_ONCE_INIT; + +static void icalerrno_destroy(void* buf) { + free(buf); + pthread_setspecific(icalerrno_key, NULL); +} + +static void icalerrno_key_alloc(void) { + pthread_key_create(&icalerrno_key, icalerrno_destroy); +} + +icalerrorenum *icalerrno_return(void) { + icalerrorenum *_errno; + + pthread_once(&icalerrno_key_once, icalerrno_key_alloc); + + _errno = (icalerrorenum*) pthread_getspecific(icalerrno_key); + + if (!_errno) { + _errno = malloc(sizeof(icalerrorenum)); + *_errno = ICAL_NO_ERROR; + pthread_setspecific(icalerrno_key, _errno); + } + return _errno; +} + +#else + +static icalerrorenum icalerrno_storage = ICAL_NO_ERROR; + +icalerrorenum *icalerrno_return(void) { + return &icalerrno_storage; +} + +#endif + + +static int foo; -int foo; void icalerror_stop_here(void) { foo++; /* Keep optimizers from removing routine */ } void icalerror_crash_here(void) { int *p=0; *p = 1; assert( *p); } #ifdef ICAL_SETERROR_ISFUNC void icalerror_set_errno(icalerrorenum x) { icalerrno = x; if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL || (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT && icalerror_errors_are_fatal == 1 )){ icalerror_warn(icalerror_strerror(x)); assert(0); } } #endif void icalerror_clear_errno() { icalerrno = ICAL_NO_ERROR; } #ifdef ICAL_ERRORS_ARE_FATAL int icalerror_errors_are_fatal = 1; #else int icalerror_errors_are_fatal = 0; #endif struct icalerror_state { icalerrorenum error; icalerrorstate state; }; -struct icalerror_state error_state_map[] = +static struct icalerror_state error_state_map[] = { { ICAL_BADARG_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_NEWFAILED_ERROR,ICAL_ERROR_DEFAULT}, + { ICAL_ALLOCATION_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_PARSE_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_INTERNAL_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_FILE_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_USAGE_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_UNIMPLEMENTED_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_UNKNOWN_ERROR,ICAL_ERROR_DEFAULT}, { ICAL_NO_ERROR,ICAL_ERROR_DEFAULT} }; struct icalerror_string_map { const char* str; icalerrorenum error; char name[160]; }; static struct icalerror_string_map string_map[] = { {"BADARG",ICAL_BADARG_ERROR,"BADARG: Bad argument to function"}, { "NEWFAILED",ICAL_NEWFAILED_ERROR,"NEWFAILED: Failed to create a new object via a *_new() routine"}, + { "ALLOCATION",ICAL_ALLOCATION_ERROR,"ALLOCATION: Failed to allocate new memory"}, {"MALFORMEDDATA",ICAL_MALFORMEDDATA_ERROR,"MALFORMEDDATA: An input string was not correctly formed or a component has missing or extra properties"}, { "PARSE",ICAL_PARSE_ERROR,"PARSE: Failed to parse a part of an iCal component"}, {"INTERNAL",ICAL_INTERNAL_ERROR,"INTERNAL: Random internal error. This indicates an error in the library code, not an error in use"}, { "FILE",ICAL_FILE_ERROR,"FILE: An operation on a file failed. Check errno for more detail."}, { "USAGE",ICAL_USAGE_ERROR,"USAGE: Failed to propertyl sequence calls to a set of interfaces"}, { "UNIMPLEMENTED",ICAL_UNIMPLEMENTED_ERROR,"UNIMPLEMENTED: This feature has not been implemented"}, { "NO",ICAL_NO_ERROR,"NO: No error"}, {"UNKNOWN",ICAL_UNKNOWN_ERROR,"UNKNOWN: Unknown error type -- icalerror_strerror() was probably given bad input"} }; icalerrorenum icalerror_error_from_string(const char* str){ icalerrorenum e; int i = 0; for( i = 0; string_map[i].error != ICAL_NO_ERROR; i++){ if (strcmp(string_map[i].str,str) == 0){ e = string_map[i].error; } } return e; } icalerrorstate icalerror_supress(const char* error){ icalerrorenum e = icalerror_error_from_string(error); icalerrorstate es; if (e == ICAL_NO_ERROR){ return ICAL_ERROR_UNKNOWN; } es = icalerror_get_error_state(e); icalerror_set_error_state(e,ICAL_ERROR_NONFATAL); return es; } char* icalerror_perror() { return icalerror_strerror(icalerrno); } void icalerror_restore(const char* error, icalerrorstate es){ icalerrorenum e = icalerror_error_from_string(error); if (e != ICAL_NO_ERROR){ icalerror_set_error_state(e,es); } } void icalerror_set_error_state( icalerrorenum error, icalerrorstate state) { int i; - for(i = ICAL_BADARG_ERROR; error_state_map[i].error!= ICAL_NO_ERROR;i++){ + for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){ if(error_state_map[i].error == error){ error_state_map[i].state = state; } } } icalerrorstate icalerror_get_error_state( icalerrorenum error) { int i; - for(i = ICAL_BADARG_ERROR; error_state_map[i].error!= ICAL_NO_ERROR;i++){ + for(i = 0; error_state_map[i].error!= ICAL_NO_ERROR;i++){ if(error_state_map[i].error == error){ return error_state_map[i].state; } } return ICAL_ERROR_UNKNOWN; } char* icalerror_strerror(icalerrorenum e) { int i; for (i=0; string_map[i].error != ICAL_UNKNOWN_ERROR; i++) { if (string_map[i].error == e) { return string_map[i].name; } } return string_map[i].name; /* Return string for ICAL_UNKNOWN_ERROR*/ } diff --git a/libical/src/libical/icalerror.h b/libical/src/libical/icalerror.h index 52f5ba9..826c8e8 100644 --- a/libical/src/libical/icalerror.h +++ b/libical/src/libical/icalerror.h @@ -1,156 +1,161 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalerror.h CREATOR: eric 09 May 1999 $Id$ (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 icalerror.h ======================================================================*/ #ifndef ICALERROR_H #define ICALERROR_H #include <assert.h> #include <stdio.h> /* For icalerror_warn() */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #define ICAL_SETERROR_ISFUNC -/* This routine is called before any error is triggered. It is called +/** This routine is called before any error is triggered. It is called by icalerror_set_errno, so it does not appear in all of the macros below */ void icalerror_stop_here(void); void icalerror_crash_here(void); typedef enum icalerrorenum { - + ICAL_NO_ERROR, /* icalerrno may not be initialized - put it first so and pray that the compiler initialize things to zero */ ICAL_BADARG_ERROR, ICAL_NEWFAILED_ERROR, ICAL_ALLOCATION_ERROR, ICAL_MALFORMEDDATA_ERROR, ICAL_PARSE_ERROR, ICAL_INTERNAL_ERROR, /* Like assert --internal consist. prob */ ICAL_FILE_ERROR, ICAL_USAGE_ERROR, ICAL_UNIMPLEMENTED_ERROR, - ICAL_UNKNOWN_ERROR, /* Used for problems in input to icalerror_strerror()*/ - ICAL_NO_ERROR + ICAL_UNKNOWN_ERROR /* Used for problems in input to icalerror_strerror()*/ } icalerrorenum; -/* The libical error enumeration, like errno*/ -extern icalerrorenum icalerrno; +icalerrorenum * icalerrno_return(void); +#define icalerrno (*(icalerrno_return())) -/* If true, libicl aborts after a call to icalerror_set_error*/ +/** If true, libicl aborts after a call to icalerror_set_error + * + * @warning NOT THREAD SAFE -- recommended that you do not change + * this in a multithreaded program. + */ extern int icalerror_errors_are_fatal; /* Warning messages */ #ifdef __GNUC__ca #define icalerror_warn(message) {fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);} #else /* __GNU_C__ */ #define icalerror_warn(message) {fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);} #endif /* __GNU_C__ */ void icalerror_clear_errno(void); +void _icalerror_set_errno(icalerrorenum); /* Make an individual error fatal or non-fatal. */ typedef enum icalerrorstate { ICAL_ERROR_FATAL, /* Not fata */ ICAL_ERROR_NONFATAL, /* Fatal */ ICAL_ERROR_DEFAULT, /* Use the value of icalerror_errors_are_fatal*/ ICAL_ERROR_UNKNOWN /* Asked state for an unknown error type */ } icalerrorstate ; char* icalerror_strerror(icalerrorenum e); char* icalerror_perror(); void icalerror_set_error_state( icalerrorenum error, icalerrorstate); icalerrorstate icalerror_get_error_state( icalerrorenum error); #ifndef ICAL_SETERROR_ISFUNC #define icalerror_set_errno(x) \ icalerrno = x; \ + fprintf(stderr,"Ical error # %d\n", x); \ if(icalerror_get_error_state(x)==ICAL_ERROR_FATAL || \ (icalerror_get_error_state(x)==ICAL_ERROR_DEFAULT && \ icalerror_errors_are_fatal == 1 )){ \ icalerror_warn(icalerror_strerror(x)); \ assert(0); \ -} +} #else -void icalerror_set_errno(icalerrorenum); +void icalerror_set_errno(icalerrorenum x); #endif #ifdef ICAL_ERRORS_ARE_FATAL #undef NDEBUG #endif #define icalerror_check_value_type(value,type); #define icalerror_check_property_type(value,type); #define icalerror_check_parameter_type(value,type); #define icalerror_check_component_type(value,type); /* Assert with a message */ #ifdef ICAL_ERRORS_ARE_FATAL #ifdef __GNUC__ #define icalerror_assert(test,message) if(!(test)){fprintf(stderr,"%s(), %s:%d: %s\n",__FUNCTION__,__FILE__,__LINE__,message);icalerror_stop_here(); abort();} #else /*__GNUC__*/ #define icalerror_assert(test,message) if(!(test)){fprintf(stderr,"%s:%d: %s\n",__FILE__,__LINE__,message);icalerror_stop_here(); abort();} #endif /*__GNUC__*/ #else /* ICAL_ERRORS_ARE_FATAL */ #define icalerror_assert(test,message) #endif /* ICAL_ERRORS_ARE_FATAL */ /* Check & abort if check fails */ #define icalerror_check_arg(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); } /* Check & return void if check fails*/ #define icalerror_check_arg_rv(test,arg) if(!(test)) {icalerror_set_errno(ICAL_BADARG_ERROR); return; } /* Check & return 0 if check fails*/ #define icalerror_check_arg_rz(test,arg) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0;} /* Check & return an error if check fails*/ #define icalerror_check_arg_re(test,arg,error) if(!(test)) { icalerror_stop_here(); assert(0); return error;} /* Check & return something*/ #define icalerror_check_arg_rx(test,arg,x) if(!(test)) { icalerror_set_errno(ICAL_BADARG_ERROR); return x;} /* String interfaces to set an error to NONFATAL and restore it to its original value */ icalerrorstate icalerror_supress(const char* error); void icalerror_restore(const char* error, icalerrorstate es); #endif /* !ICALERROR_H */ diff --git a/libical/src/libical/icallangbind.c b/libical/src/libical/icallangbind.c index c079034..1a3ad48 100644 --- a/libical/src/libical/icallangbind.c +++ b/libical/src/libical/icallangbind.c @@ -1,275 +1,312 @@ /* -*- Mode: C -*- ====================================================================== FILE: icallangbind.c CREATOR: eric 15 dec 2000 DESCRIPTION: $Id$ $Locker$ (C) COPYRIGHT 1999 Eric Busboom http://www.softwarestudio.org This package is free software and is provided "as is" without express or implied warranty. It may be used, redistributed and/or modified under the same terms as perl itself. ( Either the Artistic License or the GPL. ) ======================================================================*/ #include "icalcomponent.h" #include "icalproperty.h" #include "icalerror.h" #include "icalmemory.h" +#include "icalvalue.h" #include <stdlib.h> #include <string.h> -#include <stdio.h> -int snprintf(char *str, size_t n, char const *fmt, ...); +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif int* icallangbind_new_array(int size){ int* p = (int*)malloc(size*sizeof(int)); return p; /* Caller handles failures */ } void icallangbind_free_array(int* array){ free(array); } int icallangbind_access_array(int* array, int index) { return array[index]; } +/** Iterators to fetch parameters given property */ +icalparameter* icallangbind_get_first_parameter(icalproperty *prop) -/* LIke icalcomponent_get_first_component, buut takes a string for the +{ + icalparameter_kind kind = ICAL_ANY_PARAMETER; + + return icalproperty_get_first_parameter(prop,kind); +} + +icalparameter* icallangbind_get_next_parameter(icalproperty *prop) +{ + icalparameter_kind kind = ICAL_ANY_PARAMETER; + + return icalproperty_get_next_parameter(prop,kind); +} + + +/** Like icalcomponent_get_first_component(), but takes a string for the kind and can iterate over X properties as if each X name was a seperate kind */ + icalproperty* icallangbind_get_first_property(icalcomponent *c, const char* prop) { icalproperty_kind kind = icalproperty_string_to_kind(prop); icalproperty *p; if (kind == ICAL_NO_PROPERTY){ return 0; } if(kind == ICAL_X_PROPERTY){ for(p = icalcomponent_get_first_property(c,kind); p !=0; p = icalcomponent_get_next_property(c,kind)){ if(strcmp(icalproperty_get_x_name(p),prop) == 0){ return p; } } } else { p=icalcomponent_get_first_property(c,kind); return p; } return 0; } icalproperty* icallangbind_get_next_property(icalcomponent *c, const char* prop) { icalproperty_kind kind = icalenum_string_to_property_kind(prop); icalproperty *p; if (kind == ICAL_NO_PROPERTY){ return 0; } if(kind == ICAL_X_PROPERTY){ for(p = icalcomponent_get_next_property(c,kind); p !=0; p = icalcomponent_get_next_property(c,kind)){ if(strcmp(icalproperty_get_x_name(p),prop) == 0){ return p; } } } else { p=icalcomponent_get_next_property(c,kind); return p; } return 0; } icalcomponent* icallangbind_get_first_component(icalcomponent *c, const char* comp) { icalcomponent_kind kind = icalenum_string_to_component_kind(comp); if (kind == ICAL_NO_COMPONENT){ return 0; } return icalcomponent_get_first_component(c,kind); } icalcomponent* icallangbind_get_next_component(icalcomponent *c, const char* comp) { icalcomponent_kind kind = icalenum_string_to_component_kind(comp); if (kind == ICAL_NO_COMPONENT){ return 0; } return icalcomponent_get_next_component(c,kind); } #define APPENDS(x) icalmemory_append_string(&buf, &buf_ptr, &buf_size, x); #define APPENDC(x) icalmemory_append_char(&buf, &buf_ptr, &buf_size, x); + const char* icallangbind_property_eval_string(icalproperty* prop, char* sep) { char tmp[25]; size_t buf_size = 1024; char* buf = icalmemory_new_buffer(buf_size); char* buf_ptr = buf; icalparameter *param; icalvalue* value; if( prop == 0){ return 0; } APPENDS("{ "); value = icalproperty_get_value(prop); APPENDS(" 'name' "); APPENDS(sep); APPENDC('\''); - APPENDS(icalenum_property_kind_to_string(icalproperty_isa(prop))); + APPENDS(icalproperty_kind_to_string(icalproperty_isa(prop))); APPENDC('\''); if(value){ APPENDS(", 'value_type' "); APPENDS(sep); APPENDC('\''); - APPENDS(icalenum_value_kind_to_string(icalvalue_isa(value))); + APPENDS(icalvalue_kind_to_string(icalvalue_isa(value))); APPENDC('\''); } APPENDS(", 'pid' "); APPENDS(sep); APPENDC('\''); snprintf(tmp,25,"%p",prop); APPENDS(tmp); APPENDC('\''); if(value){ switch (icalvalue_isa(value)){ case ICAL_ATTACH_VALUE: case ICAL_BINARY_VALUE: case ICAL_NO_VALUE: { icalerror_set_errno(ICAL_INTERNAL_ERROR); break; } default: { const char* str = icalvalue_as_ical_string(value); char* copy = (char*) malloc(strlen(str)+1); const char *i; char *j; if(copy ==0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); break; } /* Remove any newlines */ for(j=copy, i = str; *i != 0; j++,i++){ if(*i=='\n'){ i++; } *j = *i; } *j = 0; APPENDS(", 'value'"); APPENDS(sep); APPENDC('\''); APPENDS(copy); APPENDC('\''); free(copy); break; } } } /* Add Parameters */ for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); param != 0; param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)){ const char* str = icalparameter_as_ical_string(param); char *copy = icalmemory_tmp_copy(str); char *v; if(copy == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); continue; } v = strchr(copy,'='); if(v == 0){ continue; } *v = 0; v++; APPENDS(", "); APPENDC('\''); APPENDS(copy); APPENDC('\''); APPENDS(sep); APPENDC('\''); APPENDS(v); APPENDC('\''); } APPENDC('}'); icalmemory_add_tmp_buffer(buf); return buf; } #include "fcntl.h" int icallangbind_string_to_open_flag(const char* str) { if (strcmp(str,"r") == 0) {return O_RDONLY;} else if (strcmp(str,"r+") == 0) {return O_RDWR;} else if (strcmp(str,"w") == 0) {return O_WRONLY;} + else if (strcmp(str,"w+") == 0) {return O_RDWR|O_CREAT;} else if (strcmp(str,"a") == 0) {return O_WRONLY|O_APPEND;} else return -1; } + +const char* icallangbind_quote_as_ical(const char* str) +{ + size_t buf_size = 2 * strlen(str); + + /* assume every char could be quoted */ + char* buf = icalmemory_new_buffer(buf_size); + int result; + + result = icalvalue_encode_ical_string(str, buf, buf_size); + + icalmemory_add_tmp_buffer(buf); + + return buf; +} diff --git a/libical/src/libical/icallangbind.h b/libical/src/libical/icallangbind.h index 2ed5003..fed3626 100644 --- a/libical/src/libical/icallangbind.h +++ b/libical/src/libical/icallangbind.h @@ -1,49 +1,54 @@ /* -*- Mode: C -*- ====================================================================== FILE: icallangbind.h CREATOR: eric 25 jan 2001 DESCRIPTION: $Id$ $Locker$ (C) COPYRIGHT 1999 Eric Busboom http://www.softwarestudio.org This package is free software and is provided "as is" without express or implied warranty. It may be used, redistributed and/or modified under the same terms as perl itself. ( Either the Artistic License or the GPL. ) ======================================================================*/ #ifndef __ICALLANGBIND_H__ #define __ICALLANGBIND_H__ int* icallangbind_new_array(int size); void icallangbind_free_array(int* array); int icallangbind_access_array(int* array, int index); icalproperty* icallangbind_get_property(icalcomponent *c, int n, const char* prop); const char* icallangbind_get_property_val(icalproperty* p); const char* icallangbind_get_parameter(icalproperty *p, const char* parameter); icalcomponent* icallangbind_get_component(icalcomponent *c, const char* comp); icalproperty* icallangbind_get_first_property(icalcomponent *c, const char* prop); icalproperty* icallangbind_get_next_property(icalcomponent *c, const char* prop); icalcomponent* icallangbind_get_first_component(icalcomponent *c, const char* comp); icalcomponent* icallangbind_get_next_component(icalcomponent *c, const char* comp); +icalparameter* icallangbind_get_first_parameter(icalproperty *prop); + +icalparameter* icallangbind_get_next_parameter(icalproperty *prop); const char* icallangbind_property_eval_string(icalproperty* prop, char* sep); int icallangbind_string_to_open_flag(const char* str); + +const char* icallangbind_quote_as_ical(const char* str); #endif /*__ICALLANGBIND_H__*/ diff --git a/libical/src/libical/icalmemory.c b/libical/src/libical/icalmemory.c index 297ead8..058ef37 100644 --- a/libical/src/libical/icalmemory.c +++ b/libical/src/libical/icalmemory.c @@ -1,287 +1,367 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalmemory.c CREATOR: eric 30 June 1999 $Id$ $Locker$ The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. 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 icalmemory.h ======================================================================*/ -/* libical often passes strings back to the caller. To make these +/** + * @file icalmemory.c + * @brief Common memory management routines. + * + * libical often passes strings back to the caller. To make these * interfaces simple, I did not want the caller to have to pass in a * memory buffer, but having libical pass out newly allocated memory * makes it difficult to de-allocate the memory. * * The ring buffer in this scheme makes it possible for libical to pass * out references to memory which the caller does not own, and be able * to de-allocate the memory later. The ring allows libical to have * several buffers active simultaneously, which is handy when creating - * string representations of components. */ + * string representations of components. + */ #define ICALMEMORY_C #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef DMALLOC #include "dmalloc.h" #endif #include "icalmemory.h" #include "icalerror.h" #include <stdio.h> /* for printf (debugging) */ #include <stdlib.h> /* for malloc, realloc */ #include <string.h> /* for memset(), strdup */ -#define BUFFER_RING_SIZE 25 +#ifdef WIN32 +#include <windows.h> +#endif + +#define BUFFER_RING_SIZE 2500 #define MIN_BUFFER_SIZE 200 + +/* HACK. Not threadsafe */ + +typedef struct { + int pos; + void *ring[BUFFER_RING_SIZE]; +} buffer_ring; + void icalmemory_free_tmp_buffer (void* buf); +void icalmemory_free_ring_byval(buffer_ring *br); +static buffer_ring* global_buffer_ring = 0; -/* HACK. Not threadsafe */ -void* buffer_ring[BUFFER_RING_SIZE]; -int buffer_pos = -1; -int initialized = 0; +#ifdef HAVE_PTHREAD +#include <pthread.h> -/* Add an existing buffer to the buffer ring */ -void icalmemory_add_tmp_buffer(void* buf) -{ - /* I don't think I need this -- I think static arrays are - initialized to 0 as a standard part of C, but I am not sure. */ - if (initialized == 0){ +static pthread_key_t ring_key; +static pthread_once_t ring_key_once = PTHREAD_ONCE_INIT; + +static void ring_destroy(void * buf) { + if (buf) icalmemory_free_ring_byval((buffer_ring *) buf); + pthread_setspecific(ring_key, NULL); +} + +static void ring_key_alloc(void) { + pthread_key_create(&ring_key, ring_destroy); +} +#endif + + +static buffer_ring * buffer_ring_new(void) { + buffer_ring *br; int i; + + br = (buffer_ring *)malloc(sizeof(buffer_ring)); + for(i=0; i<BUFFER_RING_SIZE; i++){ - buffer_ring[i] = 0; + br->ring[i] = 0; } - initialized = 1; + br->pos = 0; + return(br); +} + + +#ifdef HAVE_PTHREAD +static buffer_ring* get_buffer_ring_pthread(void) { + buffer_ring *br; + + pthread_once(&ring_key_once, ring_key_alloc); + + br = pthread_getspecific(ring_key); + + if (!br) { + br = buffer_ring_new(); + pthread_setspecific(ring_key, br); } + return(br); +} +#endif + +/* get buffer ring via a single global for a non-threaded program */ +static buffer_ring* get_buffer_ring_global(void) { + if (global_buffer_ring == 0) { + global_buffer_ring = buffer_ring_new(); + } + return(global_buffer_ring); +} + +static buffer_ring *get_buffer_ring(void) { +#ifdef HAVE_PTHREAD + return(get_buffer_ring_pthread()); +#else + return get_buffer_ring_global(); +#endif +} + + +/** Add an existing buffer to the buffer ring */ +void icalmemory_add_tmp_buffer(void* buf) +{ + buffer_ring *br = get_buffer_ring(); + /* Wrap around the ring */ - if(++buffer_pos == BUFFER_RING_SIZE){ - buffer_pos = 0; + if(++(br->pos) == BUFFER_RING_SIZE){ + br->pos = 0; } /* Free buffers as their slots are overwritten */ - if ( buffer_ring[buffer_pos] != 0){ - free( buffer_ring[buffer_pos]); - buffer_ring[buffer_pos] = 0; + if ( br->ring[br->pos] != 0){ + free( br->ring[br->pos]); } /* Assign the buffer to a slot */ - buffer_ring[buffer_pos] = buf; + br->ring[br->pos] = buf; } -/* Create a new temporary buffer on the ring. Libical owns these and - wil deallocate them. */ + +/** + * Create a new temporary buffer on the ring. Libical owns these and + * will deallocate them. + */ + void* icalmemory_tmp_buffer (size_t size) { char *buf; if (size < MIN_BUFFER_SIZE){ size = MIN_BUFFER_SIZE; } buf = (void*)malloc(size); if( buf == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(buf,0,size); icalmemory_add_tmp_buffer(buf); return buf; } -void icalmemory_free_ring() -{ - +/** get rid of this buffer ring */ +void icalmemory_free_ring_byval(buffer_ring *br) { int i; for(i=0; i<BUFFER_RING_SIZE; i++){ - if ( buffer_ring[i] != 0){ - free( buffer_ring[i]); + if ( br->ring[i] != 0){ + free( br->ring[i]); } - buffer_ring[i] = 0; - } + } + free(br); +} - initialized = 1; +void icalmemory_free_ring() +{ + buffer_ring *br; + br = get_buffer_ring(); + icalmemory_free_ring_byval(br); } -/* Like strdup, but the buffer is on the ring. */ +/** Like strdup, but the buffer is on the ring. */ char* icalmemory_tmp_copy(const char* str) { char* b = icalmemory_tmp_buffer(strlen(str)+1); strcpy(b,str); return b; } char* icalmemory_strdup(const char *s) { return strdup(s); } void icalmemory_free_tmp_buffer (void* buf) { if(buf == 0) { return; } free(buf); } -/* These buffer routines create memory the old fashioned way -- so the - caller will have to delocate the new memory */ +/* + * These buffer routines create memory the old fashioned way -- so the + * caller will have to deallocate the new memory + */ void* icalmemory_new_buffer(size_t size) { void *b = malloc(size); if( b == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(b,0,size); return b; } void* icalmemory_resize_buffer(void* buf, size_t size) { void *b = realloc(buf, size); if( b == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } return b; } void icalmemory_free_buffer(void* buf) { free(buf); } void icalmemory_append_string(char** buf, char** pos, size_t* buf_size, const char* string) { char *new_buf; char *new_pos; size_t data_length, final_length, string_length; #ifndef ICAL_NO_INTERNAL_DEBUG icalerror_check_arg_rv( (buf!=0),"buf"); icalerror_check_arg_rv( (*buf!=0),"*buf"); icalerror_check_arg_rv( (pos!=0),"pos"); icalerror_check_arg_rv( (*pos!=0),"*pos"); icalerror_check_arg_rv( (buf_size!=0),"buf_size"); icalerror_check_arg_rv( (*buf_size!=0),"*buf_size"); icalerror_check_arg_rv( (string!=0),"string"); #endif string_length = strlen(string); data_length = (size_t)*pos - (size_t)*buf; final_length = data_length + string_length; if ( final_length >= (size_t) *buf_size) { *buf_size = (*buf_size) * 2 + final_length; new_buf = realloc(*buf,*buf_size); new_pos = (void*)((size_t)new_buf + data_length); *pos = new_pos; *buf = new_buf; } strcpy(*pos, string); *pos += string_length; } void icalmemory_append_char(char** buf, char** pos, size_t* buf_size, char ch) { char *new_buf; char *new_pos; size_t data_length, final_length; #ifndef ICAL_NO_INTERNAL_DEBUG icalerror_check_arg_rv( (buf!=0),"buf"); icalerror_check_arg_rv( (*buf!=0),"*buf"); icalerror_check_arg_rv( (pos!=0),"pos"); icalerror_check_arg_rv( (*pos!=0),"*pos"); icalerror_check_arg_rv( (buf_size!=0),"buf_size"); icalerror_check_arg_rv( (*buf_size!=0),"*buf_size"); #endif data_length = (size_t)*pos - (size_t)*buf; final_length = data_length + 2; if ( final_length > (size_t) *buf_size ) { *buf_size = (*buf_size) * 2 + final_length +1; new_buf = realloc(*buf,*buf_size); new_pos = (void*)((size_t)new_buf + data_length); *pos = new_pos; *buf = new_buf; } **pos = ch; *pos += 1; **pos = 0; } diff --git a/libical/src/libical/icalmemory.h b/libical/src/libical/icalmemory.h index f833c6c..7c42566 100644 --- a/libical/src/libical/icalmemory.h +++ b/libical/src/libical/icalmemory.h @@ -1,85 +1,84 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalmemory.h CREATOR: eric 30 June 1999 $Id$ $Locker$ 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 Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef ICALMEMORY_H #define ICALMEMORY_H +#ifndef WIN32 #include <sys/types.h> /* for size_t */ - -// Eugen C. <eug@thekompany.com> -#ifdef _WIN32 +#else #include <stddef.h> #endif -// Eugen C. <eug@thekompany.com> /* Tmp buffers are managed by ical. References can be returned to the caller, although the caller will not own the memory. */ void* icalmemory_tmp_buffer(size_t size); char* icalmemory_tmp_copy(const char* str); -/* Add an externally allocated buffer to the ring. */ +/** Add an externally allocated buffer to the ring. */ void icalmemory_add_tmp_buffer(void*); -/* Free all memory used in the ring */ +/** Free all memory used in the ring */ void icalmemory_free_ring(void); /* Non-tmp buffers must be freed. These are mostly wrappers around * malloc, etc, but are used so the caller can change the memory * allocators in a future version of the library */ void* icalmemory_new_buffer(size_t size); void* icalmemory_resize_buffer(void* buf, size_t size); void icalmemory_free_buffer(void* buf); -/* icalmemory_append_string will copy the string 'string' to the +/** + icalmemory_append_string will copy the string 'string' to the buffer 'buf' starting at position 'pos', reallocing 'buf' if it is too small. 'buf_size' is the size of 'buf' and will be changed if 'buf' is reallocated. 'pos' will point to the last byte of the new string in 'buf', usually a '\0' */ /* THESE ROUTINES CAN NOT BE USED ON TMP BUFFERS. Only use them on normally allocated memory, or on buffers created from icalmemory_new_buffer, never with buffers created by icalmemory_tmp_buffer. If icalmemory_append_string has to resize a buffer on the ring, the ring will loose track of it an you will have memory problems. */ void icalmemory_append_string(char** buf, char** pos, size_t* buf_size, const char* string); -/* icalmemory_append_char is similar, but is appends a character instead of a string */ +/** icalmemory_append_char is similar, but is appends a character instead of a string */ void icalmemory_append_char(char** buf, char** pos, size_t* buf_size, char ch); -/* A wrapper around strdup. Partly to trap calls to strdup, partly - because in -ansi, gcc on Red Hat claims that strudup is undeclared */ +/** A wrapper around strdup. Partly to trap calls to strdup, partly + because in -ansi, gcc on Red Hat claims that strdup is undeclared */ char* icalmemory_strdup(const char *s); #endif /* !ICALMEMORY_H */ diff --git a/libical/src/libical/icalmime.c b/libical/src/libical/icalmime.c index 7021746..12443c3 100644 --- a/libical/src/libical/icalmime.c +++ b/libical/src/libical/icalmime.c @@ -1,388 +1,390 @@ /* -*- Mode: C -*-*/ /*====================================================================== FILE: icalmime.c CREATOR: eric 26 July 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 ======================================================================*/ #include "icalmime.h" #include "icalerror.h" #include "icalmemory.h" #include "sspm.h" #include "stdlib.h" #include <string.h> /* For strdup */ #include <stdio.h> /* for snprintf*/ -int snprintf(char *str, size_t n, char const *fmt, ...); - #ifdef DMALLOC #include "dmalloc.h" #endif +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif /* These *_part routines are called by the MIME parser via the local_action_map */ struct text_part { char* buf; char* buf_pos; size_t buf_size; }; void* icalmime_text_new_part() { #define BUF_SIZE 2048 struct text_part* impl; if ( ( impl = (struct text_part*) malloc(sizeof(struct text_part))) == 0) { return 0; } impl->buf = icalmemory_new_buffer(BUF_SIZE); impl->buf_pos = impl->buf; impl->buf_size = BUF_SIZE; return impl; } void icalmime_text_add_line(void *part, struct sspm_header *header, char* line, size_t size) { struct text_part* impl = (struct text_part*) part; icalmemory_append_string(&(impl->buf),&(impl->buf_pos), &(impl->buf_size),line); } void* icalmime_textcalendar_end_part(void* part) { struct text_part* impl = (struct text_part*) part; icalcomponent *c = icalparser_parse_string(impl->buf); icalmemory_free_buffer(impl->buf); free(impl); return c; } void* icalmime_text_end_part(void* part) { struct text_part* impl = ( struct text_part*) part; icalmemory_add_tmp_buffer(impl->buf); free(impl); return impl->buf; } void icalmime_text_free_part(void *part) { part = part; } /* Ignore Attachments for now */ void* icalmime_attachment_new_part() { return 0; } void icalmime_attachment_add_line(void *part, struct sspm_header *header, char* line, size_t size) { part = part; header = header; line = line; size = size; } void* icalmime_attachment_end_part(void* part) { return 0; } void icalmime_attachment_free_part(void *part) { } struct sspm_action_map icalmime_local_action_map[] = { {SSPM_TEXT_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_textcalendar_end_part,icalmime_text_free_part}, {SSPM_TEXT_MAJOR_TYPE,SSPM_ANY_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part}, {SSPM_TEXT_MAJOR_TYPE,SSPM_PLAIN_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part}, {SSPM_APPLICATION_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_IMAGE_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_AUDIO_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_IMAGE_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_UNKNOWN_MAJOR_TYPE,SSPM_UNKNOWN_MINOR_TYPE,0,0,0,0} }; #define NUM_PARTS 100 /* HACK. Hard Limit */ struct sspm_part* icalmime_make_part(icalcomponent* comp) { comp = comp; return 0; } char* icalmime_as_mime_string(char* icalcomponent); icalcomponent* icalmime_parse(char* (*get_string)(char *s, size_t size, void *d), void *data) { struct sspm_part *parts; int i, last_level=0; icalcomponent *root=0, *parent=0, *comp=0, *last = 0; if ( (parts = (struct sspm_part *) malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(parts,0,sizeof(parts)); sspm_parse_mime(parts, NUM_PARTS, /* Max parts */ icalmime_local_action_map, /* Actions */ get_string, data, /* data for get_string*/ 0 /* First header */); for(i = 0; i <NUM_PARTS && parts[i].header.major != SSPM_NO_MAJOR_TYPE ; i++){ #define TMPSZ 1024 char mimetype[TMPSZ]; char* major = sspm_major_type_string(parts[i].header.major); char* minor = sspm_minor_type_string(parts[i].header.minor); if(parts[i].header.minor == SSPM_UNKNOWN_MINOR_TYPE ){ assert(parts[i].header.minor_text !=0); minor = parts[i].header.minor_text; } sprintf(mimetype,"%s/%s",major,minor); comp = icalcomponent_new(ICAL_XLICMIMEPART_COMPONENT); if(comp == 0){ /* HACK Handle Error */ assert(0); } if(parts[i].header.error!=SSPM_NO_ERROR){ char *str; char* temp[256]; if(parts[i].header.error==SSPM_UNEXPECTED_BOUNDARY_ERROR){ str = "Got an unexpected boundary, possibly due to a MIME header for a MULTIPART part that is missing the Content-Type line"; } if(parts[i].header.error==SSPM_WRONG_BOUNDARY_ERROR){ str = "Got the wrong boundary for the opening of a MULTIPART part."; } if(parts[i].header.error==SSPM_NO_BOUNDARY_ERROR){ str = "Got a multipart header that did not specify a boundary"; } if(parts[i].header.error==SSPM_NO_HEADER_ERROR){ str = "Did not get a header for the part. Is there a blank\ line between the header and the previous boundary\?"; } if(parts[i].header.error_text != 0){ snprintf((char*)temp,256, "%s: %s",str,parts[i].header.error_text); } else { strcpy((char*)temp,str); } icalcomponent_add_property (comp, icalproperty_vanew_xlicerror( (char*)temp, icalparameter_new_xlicerrortype( ICAL_XLICERRORTYPE_MIMEPARSEERROR), 0)); } if(parts[i].header.major != SSPM_NO_MAJOR_TYPE && parts[i].header.major != SSPM_UNKNOWN_MAJOR_TYPE){ icalcomponent_add_property(comp, icalproperty_new_xlicmimecontenttype((char*) icalmemory_strdup(mimetype))); } if (parts[i].header.encoding != SSPM_NO_ENCODING){ icalcomponent_add_property(comp, icalproperty_new_xlicmimeencoding( sspm_encoding_string(parts[i].header.encoding))); } if (parts[i].header.filename != 0){ icalcomponent_add_property(comp, icalproperty_new_xlicmimefilename(parts[i].header.filename)); } if (parts[i].header.content_id != 0){ icalcomponent_add_property(comp, icalproperty_new_xlicmimecid(parts[i].header.content_id)); } if (parts[i].header.charset != 0){ icalcomponent_add_property(comp, icalproperty_new_xlicmimecharset(parts[i].header.charset)); } /* Add iCal components as children of the component */ if(parts[i].header.major == SSPM_TEXT_MAJOR_TYPE && parts[i].header.minor == SSPM_CALENDAR_MINOR_TYPE && parts[i].data != 0){ icalcomponent_add_component(comp, (icalcomponent*)parts[i].data); parts[i].data = 0; } else if(parts[i].header.major == SSPM_TEXT_MAJOR_TYPE && parts[i].header.minor != SSPM_CALENDAR_MINOR_TYPE && parts[i].data != 0){ /* Add other text components as "DESCRIPTION" properties */ icalcomponent_add_property(comp, icalproperty_new_description( (char*)icalmemory_strdup((char*)parts[i].data))); parts[i].data = 0; } if(root!= 0 && parts[i].level == 0){ /* We've already assigned the root, but there is another part at the root level. This is probably a parse error*/ icalcomponent_free(comp); continue; } if(parts[i].level == last_level && last_level != 0){ icalerror_assert(parent!=0,"No parent for adding component"); icalcomponent_add_component(parent,comp); } else if (parts[i].level == last_level && last_level == 0 && root == 0) { root = comp; parent = comp; } else if (parts[i].level > last_level){ parent = last; icalcomponent_add_component(parent,comp); last_level = parts[i].level; } else if (parts[i].level < last_level){ parent = icalcomponent_get_parent(parent); icalcomponent_add_component(parent,comp); last_level = parts[i].level; } else { assert(0); } last = comp; last_level = parts[i].level; assert(parts[i].data == 0); } sspm_free_parts(parts,NUM_PARTS); free(parts); return root; } int icalmime_test(char* (*get_string)(char *s, size_t size, void *d), void *data) { char *out; struct sspm_part *parts; int i; if ( (parts = (struct sspm_part *) malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } memset(parts,0,sizeof(parts)); sspm_parse_mime(parts, NUM_PARTS, /* Max parts */ icalmime_local_action_map, /* Actions */ get_string, data, /* data for get_string*/ 0 /* First header */); for(i = 0; i <NUM_PARTS && parts[i].header.major != SSPM_NO_MAJOR_TYPE ; i++){ if(parts[i].header.minor == SSPM_CALENDAR_MINOR_TYPE){ parts[i].data = icalmemory_strdup( icalcomponent_as_ical_string((icalcomponent*)parts[i].data)); } } sspm_write_mime(parts,NUM_PARTS,&out,"To: bob@bob.org"); printf("%s\n",out); return 0; } diff --git a/libical/src/libical/icalparameter.c b/libical/src/libical/icalparameter.c index 156ecdb..759306f 100644 --- a/libical/src/libical/icalparameter.c +++ b/libical/src/libical/icalparameter.c @@ -1,382 +1,385 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalderivedparameters.{c,h} CREATOR: eric 09 May 1999 $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 icalderivedparameters.{c,h} Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ /*#line 29 "icalparameter.c.in"*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalparameter.h" #include "icalproperty.h" #include "icalerror.h" #include "icalmemory.h" #include "icalparameterimpl.h" #include <stdlib.h> /* for malloc() */ #include <errno.h> #include <string.h> /* for memset() */ /* In icalderivedparameter */ icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind,const char* val); struct icalparameter_impl* icalparameter_new_impl(icalparameter_kind kind) { struct icalparameter_impl* v; if ( ( v = (struct icalparameter_impl*) malloc(sizeof(struct icalparameter_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } strcpy(v->id,"para"); v->kind = kind; v->size = 0; v->string = 0; v->x_name = 0; v->parent = 0; v->data = 0; return v; } icalparameter* icalparameter_new (icalparameter_kind kind) { struct icalparameter_impl* v = icalparameter_new_impl(kind); return (icalparameter*) v; } void -icalparameter_free (icalparameter* parameter) +icalparameter_free (icalparameter* param) { - struct icalparameter_impl * impl; - - impl = (struct icalparameter_impl*)parameter; /* HACK. This always triggers, even when parameter is non-zero icalerror_check_arg_rv((parameter==0),"parameter");*/ #ifdef ICAL_FREE_ON_LIST_IS_ERROR - icalerror_assert( (impl->parent ==0),"Tried to free a parameter that is still attached to a component. "); + icalerror_assert( (param->parent ==0),"Tried to free a parameter that is still attached to a component. "); #else - if(impl->parent !=0){ + if(param->parent !=0){ return; } #endif - if (impl->string != 0){ - free ((void*)impl->string); + if (param->string != 0){ + free ((void*)param->string); } - if (impl->x_name != 0){ - free ((void*)impl->x_name); + if (param->x_name != 0){ + free ((void*)param->x_name); } - memset(impl,0,sizeof(impl)); + memset(param,0,sizeof(param)); - impl->parent = 0; - impl->id[0] = 'X'; - free(impl); + param->parent = 0; + param->id[0] = 'X'; + free(param); } icalparameter* -icalparameter_new_clone(icalparameter* param) +icalparameter_new_clone(icalparameter* old) { - struct icalparameter_impl *old; struct icalparameter_impl *new; - old = (struct icalparameter_impl *)param; new = icalparameter_new_impl(old->kind); - icalerror_check_arg_rz((param!=0),"param"); + icalerror_check_arg_rz((old!=0),"param"); if (new == 0){ return 0; } memcpy(new,old,sizeof(struct icalparameter_impl)); if (old->string != 0){ new->string = icalmemory_strdup(old->string); if (new->string == 0){ icalparameter_free(new); return 0; } } if (old->x_name != 0){ new->x_name = icalmemory_strdup(old->x_name); if (new->x_name == 0){ icalparameter_free(new); return 0; } } return new; } icalparameter* icalparameter_new_from_string(const char *str) { char* eq; char* cpy; icalparameter_kind kind; icalparameter *param; icalerror_check_arg_rz(str != 0,"str"); cpy = icalmemory_strdup(str); if (cpy == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } eq = strchr(cpy,'='); if(eq == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } *eq = '\0'; eq++; kind = icalparameter_string_to_kind(cpy); if(kind == ICAL_NO_PARAMETER){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } param = icalparameter_new_from_value_string(kind,eq); if(kind == ICAL_X_PARAMETER){ icalparameter_set_xname(param,cpy); } free(cpy); return param; } +/** + * Return a string representation of the parameter according to RFC2445. + * + * param = param-name "=" param-value + * param-name = iana-token / x-token + * param-value = paramtext /quoted-string + * paramtext = *SAFE-SHARE + * quoted-string= DQUOTE *QSAFE-CHARE DQUOTE + * QSAFE-CHAR = any character except CTLs and DQUOTE + * SAFE-CHAR = any character except CTLs, DQUOTE. ";", ":", "," + */ char* -icalparameter_as_ical_string (icalparameter* parameter) +icalparameter_as_ical_string (icalparameter* param) { - struct icalparameter_impl* impl; size_t buf_size = 1024; char* buf; char* buf_ptr; char *out_buf; const char *kind_string; - icalerror_check_arg_rz( (parameter!=0), "parameter"); + icalerror_check_arg_rz( (param!=0), "parameter"); /* Create new buffer that we can append names, parameters and a value to, and reallocate as needed. Later, this buffer will be copied to a icalmemory_tmp_buffer, which is managed internally by libical, so it can be given to the caller without fear of the caller forgetting to free it */ buf = icalmemory_new_buffer(buf_size); buf_ptr = buf; - impl = (struct icalparameter_impl*)parameter; - if(impl->kind == ICAL_X_PARAMETER) { + if(param->kind == ICAL_X_PARAMETER) { icalmemory_append_string(&buf, &buf_ptr, &buf_size, - icalparameter_get_xname(impl)); + icalparameter_get_xname(param)); } else { - kind_string = icalparameter_kind_to_string(impl->kind); + kind_string = icalparameter_kind_to_string(param->kind); - if (impl->kind == ICAL_NO_PARAMETER || - impl->kind == ICAL_ANY_PARAMETER || + if (param->kind == ICAL_NO_PARAMETER || + param->kind == ICAL_ANY_PARAMETER || kind_string == 0) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0; } /* Put the parameter name into the string */ icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); } icalmemory_append_string(&buf, &buf_ptr, &buf_size, "="); - if(impl->string !=0){ - icalmemory_append_string(&buf, &buf_ptr, &buf_size, impl->string); - } else if (impl->data != 0){ - const char* str = icalparameter_enum_to_string(impl->data); + if(param->string !=0){ + int qm = 0; + + /* Encapsulate the property in quotes if necessary */ + if (strpbrk(param->string, ";:,") != 0) { + icalmemory_append_char (&buf, &buf_ptr, &buf_size, '"'); + qm = 1; + } + icalmemory_append_string(&buf, &buf_ptr, &buf_size, param->string); + if (qm == 1) { + icalmemory_append_char (&buf, &buf_ptr, &buf_size, '"'); + } + } else if (param->data != 0){ + const char* str = icalparameter_enum_to_string(param->data); icalmemory_append_string(&buf, &buf_ptr, &buf_size, str); } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* Now, copy the buffer to a tmp_buffer, which is safe to give to the caller without worring about de-allocating it. */ out_buf = icalmemory_tmp_buffer(strlen(buf)); strcpy(out_buf, buf); icalmemory_free_buffer(buf); return out_buf; } int icalparameter_is_valid (icalparameter* parameter); icalparameter_kind icalparameter_isa (icalparameter* parameter) { if(parameter == 0){ return ICAL_NO_PARAMETER; } - return ((struct icalparameter_impl *)parameter)->kind; + return parameter->kind; } int icalparameter_isa_parameter (void* parameter) { struct icalparameter_impl *impl = (struct icalparameter_impl *)parameter; if (parameter == 0){ return 0; } if (strcmp(impl->id,"para") == 0) { return 1; } else { return 0; } } void icalparameter_set_xname (icalparameter* param, const char* v) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; icalerror_check_arg_rv( (param!=0),"param"); icalerror_check_arg_rv( (v!=0),"v"); - if (impl->x_name != 0){ - free((void*)impl->x_name); + if (param->x_name != 0){ + free((void*)param->x_name); } - impl->x_name = icalmemory_strdup(v); + param->x_name = icalmemory_strdup(v); - if (impl->x_name == 0){ + if (param->x_name == 0){ errno = ENOMEM; } } const char* icalparameter_get_xname (icalparameter* param) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; icalerror_check_arg_rz( (param!=0),"param"); - return impl->x_name; + return param->x_name; } void icalparameter_set_xvalue (icalparameter* param, const char* v) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; - icalerror_check_arg_rv( (param!=0),"param"); icalerror_check_arg_rv( (v!=0),"v"); - if (impl->string != 0){ - free((void*)impl->string); + if (param->string != 0){ + free((void*)param->string); } - impl->string = icalmemory_strdup(v); + param->string = icalmemory_strdup(v); - if (impl->string == 0){ + if (param->string == 0){ errno = ENOMEM; } } const char* icalparameter_get_xvalue (icalparameter* param) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; - icalerror_check_arg_rz( (param!=0),"param"); - return impl->string; - + return param->string; } void icalparameter_set_parent(icalparameter* param, icalproperty* property) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; - icalerror_check_arg_rv( (param!=0),"param"); - impl->parent = property; + param->parent = property; } icalproperty* icalparameter_get_parent(icalparameter* param) { - struct icalparameter_impl *impl = (struct icalparameter_impl*)param; - icalerror_check_arg_rz( (param!=0),"param"); - return impl->parent; + return param->parent; } /* Everything below this line is machine generated. Do not edit. */ /* ALTREP */ diff --git a/libical/src/libical/icalparameter.h b/libical/src/libical/icalparameter.h index 3f3b59f..f3d64ab 100644 --- a/libical/src/libical/icalparameter.h +++ b/libical/src/libical/icalparameter.h @@ -1,69 +1,69 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalparam.h CREATOR: eric 20 March 1999 $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 icalparam.h ======================================================================*/ #ifndef ICALPARAM_H #define ICALPARAM_H #include "icalderivedparameter.h" /* Declared in icalderivedparameter.h */ -/*typedef void icalparameter;*/ +/*typedef struct icalparameter_impl icalparameter;*/ icalparameter* icalparameter_new(icalparameter_kind kind); icalparameter* icalparameter_new_clone(icalparameter* p); /* Create from string of form "PARAMNAME=VALUE" */ icalparameter* icalparameter_new_from_string(const char* value); /* Create from just the value, the part after the "=" */ icalparameter* icalparameter_new_from_value_string(icalparameter_kind kind, const char* value); void icalparameter_free(icalparameter* parameter); char* icalparameter_as_ical_string(icalparameter* parameter); int icalparameter_is_valid(icalparameter* parameter); icalparameter_kind icalparameter_isa(icalparameter* parameter); int icalparameter_isa_parameter(void* param); /* Acess the name of an X parameer */ void icalparameter_set_xname (icalparameter* param, const char* v); const char* icalparameter_get_xname(icalparameter* param); void icalparameter_set_xvalue (icalparameter* param, const char* v); const char* icalparameter_get_xvalue(icalparameter* param); /* Convert enumerations */ const char* icalparameter_kind_to_string(icalparameter_kind kind); icalparameter_kind icalparameter_string_to_kind(const char* string); #endif diff --git a/libical/src/libical/icalparser.c b/libical/src/libical/icalparser.c index b5824d5..5c4296b 100644 --- a/libical/src/libical/icalparser.c +++ b/libical/src/libical/icalparser.c @@ -1,1111 +1,1104 @@ -/* -*- Mode: C -*- +/* -*- Mode: C; tab-width: 4; c-basic-offset: 8; -*- ====================================================================== FILE: icalparser.c CREATOR: eric 04 August 1999 $Id$ $Locker$ The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. 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 Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "icalparser.h" #include "pvl.h" -#include "icalmemory.h" #include "icalerror.h" #include "icalvalue.h" #include "icalderivedparameter.h" #include "icalparameter.h" #include "icalproperty.h" #include "icalcomponent.h" #include <string.h> /* For strncpy & size_t */ #include <stdio.h> /* For FILE and fgets and sprintf */ #include <stdlib.h> /* for free */ -int snprintf(char *str, size_t n, char const *fmt, ...); +#include "icalmemory.h" +#include "icalparser.h" + +#ifdef HAVE_WCTYPE_H +# include <wctype.h> +/* Some systems have an imcomplete implementation on wctype (FreeBSD, + * Darwin). Cope with that. */ +# ifndef HAVE_ISWSPACE +# define iswspace isspace +# endif +#else +# ifndef HAVE_ISWSPACE +# define iswspace isspace +# endif +#endif -extern icalvalue* icalparser_yy_value; -void set_parser_value_state(icalvalue_kind kind); -int ical_yyparse(void); +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif -char* icalparser_get_next_char(char c, char *str); +char* icalparser_get_next_char(char c, char *str, int qm); char* icalparser_get_next_parameter(char* line,char** end); char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind); char* icalparser_get_prop_name(char* line, char** end); char* icalparser_get_param_name(char* line, char **end); #define TMP_BUF_SIZE 80 struct icalparser_impl { int buffer_full; /* flag indicates that temp is smaller that data being read into it*/ int continuation_line; /* last line read was a continuation line */ size_t tmp_buf_size; char temp[TMP_BUF_SIZE]; icalcomponent *root_component; int version; int level; int lineno; icalparser_state state; pvl_list components; void *line_gen_data; - + }; icalparser* icalparser_new(void) { struct icalparser_impl* impl = 0; if ( ( impl = (struct icalparser_impl*) malloc(sizeof(struct icalparser_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } impl->root_component = 0; impl->components = pvl_newlist(); impl->level = 0; impl->state = ICALPARSER_SUCCESS; impl->tmp_buf_size = TMP_BUF_SIZE; impl->buffer_full = 0; + impl->continuation_line = 0; impl->lineno = 0; impl->continuation_line = 0; memset(impl->temp,0, TMP_BUF_SIZE); return (icalparser*)impl; } void icalparser_free(icalparser* parser) { - struct icalparser_impl* impl = (struct icalparser_impl*)parser; icalcomponent *c; - if (impl->root_component != 0){ - icalcomponent_free(impl->root_component); + if (parser->root_component != 0){ + icalcomponent_free(parser->root_component); } - while( (c=pvl_pop(impl->components)) != 0){ + while( (c=pvl_pop(parser->components)) != 0){ icalcomponent_free(c); } - pvl_free(impl->components); + pvl_free(parser->components); - free(impl); + free(parser); } void icalparser_set_gen_data(icalparser* parser, void* data) { - struct icalparser_impl* impl = (struct icalparser_impl*)parser; - - impl->line_gen_data = data; + parser->line_gen_data = data; } icalvalue* icalvalue_new_From_string_with_error(icalvalue_kind kind, char* str, icalproperty **error); -char* icalparser_get_next_char(char c, char *str) +char* icalparser_get_next_char(char c, char *str, int qm) { int quote_mode = 0; char* p; - for(p=str; *p!=0; p++){ - - if ( quote_mode == 0 && *p=='"' && *(p-1) != '\\' ){ - quote_mode =1; - continue; - } - - if ( quote_mode == 1 && *p=='"' && *(p-1) != '\\' ){ - quote_mode =0; - continue; - } - - if (quote_mode == 0 && *p== c && *(p-1) != '\\' ){ - return p; - } + if (qm == 1) { + if ( quote_mode == 0 && *p=='"' && *(p-1) != '\\' ){ + quote_mode =1; + continue; + } + + if ( quote_mode == 1 && *p=='"' && *(p-1) != '\\' ){ + quote_mode =0; + continue; + } + } + + if (quote_mode == 0 && *p== c && *(p-1) != '\\' ){ + return p; + } } return 0; } -/* make a new tmp buffer out of a substring */ -char* make_segment(char* start, char* end) + +/** make a new tmp buffer out of a substring */ +static char* make_segment(char* start, char* end) { - char *buf; + char *buf, *tmp; size_t size = (size_t)end - (size_t)start; buf = icalmemory_tmp_buffer(size+1); strncpy(buf,start,size); *(buf+size) = 0; + + tmp = (buf+size); + while ( *tmp == '\0' || iswspace(*tmp) ) + { + *tmp = 0; + tmp--; + } return buf; - } -const char* input_buffer; -const char* input_buffer_p; -//#define min(a,b) ((a) < (b) ? (a) : (b)) - -int icalparser_flex_input(char* buf, int max_size) -{ - int n = max_size; // = min(max_size,strlen(input_buffer_p)); - if ( n < ((int )strlen(input_buffer_p)) ) - n = strlen(input_buffer_p); - if (n > 0){ - memcpy(buf, input_buffer_p, n); - input_buffer_p += n; - return n; - } else { - return 0; - } -} - -void icalparser_clear_flex_input(void) -{ - input_buffer_p = input_buffer+strlen(input_buffer); -} - -/* Call the flex/bison parser to parse a complex value */ - -icalvalue* icalparser_parse_value(icalvalue_kind kind, - const char* str, icalproperty** error) -{ - int r; - input_buffer_p = input_buffer = str; - - set_parser_value_state(kind); - icalparser_yy_value = 0; - - r = ical_yyparse(); - - /* Error. Parse failed */ - if( icalparser_yy_value == 0 || r != 0){ - - if(icalparser_yy_value !=0){ - icalvalue_free(icalparser_yy_value); - icalparser_yy_value = 0; - } - - return 0; - } - - if (error != 0){ - *error = 0; - } - - return icalparser_yy_value; -} char* icalparser_get_prop_name(char* line, char** end) { char* p; char* v; char *str; - p = icalparser_get_next_char(';',line); - v = icalparser_get_next_char(':',line); + p = icalparser_get_next_char(';',line,1); + v = icalparser_get_next_char(':',line,1); if (p== 0 && v == 0) { return 0; } /* There is no ';' or, it is after the ';' that marks the beginning of the value */ if (v!=0 && ( p == 0 || p > v)){ str = make_segment(line,v); *end = v+1; } else { str = make_segment(line,p); *end = p+1; } return str; } + char* icalparser_get_param_name(char* line, char **end) { - char* next; char *str; - next = icalparser_get_next_char('=',line); + next = icalparser_get_next_char('=',line,1); if (next == 0) { return 0; } str = make_segment(line,next); *end = next+1; + if (**end == '"') { + *end = *end+1; + next = icalparser_get_next_char('"',*end,0); + if (next == 0) { + return 0; + } + + *end = make_segment(*end,next); + } + return str; - } + char* icalparser_get_next_paramvalue(char* line, char **end) { - char* next; char *str; - next = icalparser_get_next_char(',',line); + next = icalparser_get_next_char(',',line,1); if (next == 0){ next = (char*)(size_t)line+(size_t)strlen(line);\ } if (next == line){ return 0; } else { str = make_segment(line,next); *end = next+1; return str; } - } -/* A property may have multiple values, if the values are seperated by + +/** + A property may have multiple values, if the values are seperated by commas in the content line. This routine will look for the next comma after line and will set the next place to start searching in end. */ char* icalparser_get_next_value(char* line, char **end, icalvalue_kind kind) { char* next; char *p; char *str; size_t length = strlen(line); p = line; while(1){ - next = icalparser_get_next_char(',',p); + next = icalparser_get_next_char(',',p,1); /* Unforunately, RFC2445 says that for the RECUR value, COMMA can both seperate digits in a list, and it can seperate multiple recurrence specifications. This is not a friendly part of the spec. This weirdness tries to distinguish the two uses. it is probably a HACK*/ if( kind == ICAL_RECUR_VALUE ) { if ( next != 0 && (*end+length) > next+5 && strncmp(next,"FREQ",4) == 0 ) { /* The COMMA was followed by 'FREQ', is it a real seperator*/ /* Fall through */ } else if (next != 0){ /* Not real, get the next COMMA */ p = next+1; next = 0; continue; } } + /* ignore all , for query value. select dtstart, dtend etc ... */ + else if( kind == ICAL_QUERY_VALUE) { + if ( next != 0) { + p = next+1; + continue; + } + else + break; + } /* If the comma is preceeded by a '\', then it is a literal and not a value seperator*/ if ( (next!=0 && *(next-1) == '\\') || (next!=0 && *(next-3) == '\\') ) /*second clause for '/' is on prev line. HACK may be out of bounds */ { p = next+1; } else { break; } } if (next == 0){ next = (char*)(size_t)line+length; *end = next; } else { *end = next+1; } if (next == line){ return 0; } str = make_segment(line,next); return str; } char* icalparser_get_next_parameter(char* line,char** end) { char *next; char *v; char *str; - v = icalparser_get_next_char(':',line); - next = icalparser_get_next_char(';', line); + v = icalparser_get_next_char(':',line,1); + next = icalparser_get_next_char(';', line,1); /* There is no ';' or, it is after the ':' that marks the beginning of the value */ if (next == 0 || next > v) { - next = icalparser_get_next_char(':', line); + next = icalparser_get_next_char(':', line,1); } if (next != 0) { str = make_segment(line,next); *end = next+1; return str; } else { *end = line; return 0; } } -/* Get a single property line, from the property name through the - final new line, and include any continuation lines */ +/** + * Get a single property line, from the property name through the + * final new line, and include any continuation lines + */ char* icalparser_get_line(icalparser *parser, char* (*line_gen_func)(char *s, size_t size, void *d)) { char *line; char *line_p; - struct icalparser_impl* impl = (struct icalparser_impl*)parser; - size_t buf_size = impl->tmp_buf_size; - + size_t buf_size = parser->tmp_buf_size; line_p = line = icalmemory_new_buffer(buf_size); line[0] = '\0'; /* Read lines by calling line_gen_func and putting the data into - impl->temp. If the line is a continuation line ( begins with a + parser->temp. If the line is a continuation line ( begins with a space after a newline ) then append the data onto line and read again. Otherwise, exit the loop. */ while(1) { /* The first part of the loop deals with the temp buffer, which was read on he last pass through the loop. The routine is split like this because it has to read lone line ahead to determine if a line is a continuation line. */ /* The tmp buffer is not clear, so transfer the data in it to the output. This may be left over from a previous call */ - if (impl->temp[0] != '\0' ) { + if (parser->temp[0] != '\0' ) { /* If the last position in the temp buffer is occupied, mark the buffer as full. The means we will do another read later, because the line is not finished */ - if (impl->temp[impl->tmp_buf_size-1] == 0 && - impl->temp[impl->tmp_buf_size-2] != '\n'&& - impl->temp[impl->tmp_buf_size-2] != 0 ){ - impl->buffer_full = 1; + if (parser->temp[parser->tmp_buf_size-1] == 0 && + parser->temp[parser->tmp_buf_size-2] != '\n'&& + parser->temp[parser->tmp_buf_size-2] != 0 ){ + parser->buffer_full = 1; } else { - impl->buffer_full = 0; + parser->buffer_full = 0; } /* Copy the temp to the output and clear the temp buffer. */ - if(impl->continuation_line==1){ + if(parser->continuation_line==1){ /* back up the pointer to erase the continuation characters */ - impl->continuation_line = 0; + parser->continuation_line = 0; line_p--; if ( *(line_p-1) == '\r'){ line_p--; } /* copy one space up to eliminate the leading space*/ icalmemory_append_string(&line,&line_p,&buf_size, - impl->temp+1); + parser->temp+1); } else { - icalmemory_append_string(&line,&line_p,&buf_size,impl->temp); + icalmemory_append_string(&line,&line_p,&buf_size,parser->temp); } - impl->temp[0] = '\0' ; + parser->temp[0] = '\0' ; } - impl->temp[impl->tmp_buf_size-1] = 1; /* Mark end of buffer */ + parser->temp[parser->tmp_buf_size-1] = 1; /* Mark end of buffer */ /****** Here is where the routine gets string data ******************/ - if ((*line_gen_func)(impl->temp,impl->tmp_buf_size,impl->line_gen_data) + if ((*line_gen_func)(parser->temp,parser->tmp_buf_size,parser->line_gen_data) ==0){/* Get more data */ /* If the first position is clear, it means we didn't get any more data from the last call to line_ge_func*/ - if (impl->temp[0] == '\0'){ + if (parser->temp[0] == '\0'){ if(line[0] != '\0'){ /* There is data in the output, so fall trhough and process it*/ break; } else { /* No data in output; return and signal that there is no more input*/ free(line); return 0; } } } /* If the output line ends in a '\n' and the temp buffer begins with a ' ', then the buffer holds a continuation line, so keep reading. */ - if ( line_p > line+1 && *(line_p-1) == '\n' - && (impl->temp[0] == ' ' || impl->temp[0] == '\t') ) { + if ( line_p > line+1 && *(line_p-1) == '\n' && parser->temp[0] == ' ') { - impl->continuation_line = 1; + parser->continuation_line = 1; - } else if ( impl->buffer_full == 1 ) { + } else if ( parser->buffer_full == 1 ) { /* The buffer was filled on the last read, so read again */ } else { /* Looks like the end of this content line, so break */ break; } } /* Erase the final newline and/or carriage return*/ if ( line_p > line+1 && *(line_p-1) == '\n') { *(line_p-1) = '\0'; if ( *(line_p-2) == '\r'){ *(line_p-2) = '\0'; } } else { *(line_p) = '\0'; } + while ( (*line_p == '\0' || iswspace(*line_p)) && line_p > line ) + { + *line_p = '\0'; + line_p--; + } + return line; } -void insert_error(icalcomponent* comp, char* text, +static void insert_error(icalcomponent* comp, char* text, char* message, icalparameter_xlicerrortype type) { char temp[1024]; if (text == 0){ snprintf(temp,1024,"%s:",message); } else { snprintf(temp,1024,"%s: %s",message,text); } icalcomponent_add_property (comp, icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype(type), 0)); } -int line_is_blank(char* line){ + +static int line_is_blank(char* line){ int i=0; for(i=0; *(line+i)!=0; i++){ char c = *(line+i); if(c != ' ' && c != '\n' && c != '\t'){ return 0; } } return 1; } icalcomponent* icalparser_parse(icalparser *parser, char* (*line_gen_func)(char *s, size_t size, void* d)) { char* line; icalcomponent *c=0; icalcomponent *root=0; - struct icalparser_impl *impl = (struct icalparser_impl*)parser; icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); + int cont; icalerror_check_arg_rz((parser !=0),"parser"); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); do{ line = icalparser_get_line(parser, line_gen_func); if ((c = icalparser_add_line(parser,line)) != 0){ if(icalcomponent_get_parent(c) !=0){ /* This is bad news... assert? */ } - assert(impl->root_component == 0); - assert(pvl_count(impl->components) ==0); + assert(parser->root_component == 0); + assert(pvl_count(parser->components) ==0); if (root == 0){ /* Just one component */ root = c; } else if(icalcomponent_isa(root) != ICAL_XROOT_COMPONENT) { /*Got a second component, so move the two components under an XROOT container */ icalcomponent *tempc = icalcomponent_new(ICAL_XROOT_COMPONENT); icalcomponent_add_component(tempc, root); icalcomponent_add_component(tempc, c); root = tempc; } else if(icalcomponent_isa(root) == ICAL_XROOT_COMPONENT) { /* Already have an XROOT container, so add the component to it*/ icalcomponent_add_component(root, c); } else { /* Badness */ assert(0); } c = 0; } + cont = 0; if(line != 0){ free(line); + cont = 1; } - } while ( line != 0); + } while ( cont ); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); return root; } icalcomponent* icalparser_add_line(icalparser* parser, char* line) { - char *p; char *str; char *end; int vcount = 0; icalproperty *prop; icalproperty_kind prop_kind; icalvalue *value; icalvalue_kind value_kind = ICAL_NO_VALUE; - struct icalparser_impl *impl = (struct icalparser_impl*)parser; icalerror_check_arg_rz((parser != 0),"parser"); if (line == 0) { - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } if(line_is_blank(line) == 1){ return 0; } /* Begin by getting the property name at the start of the line. The property name may end up being "BEGIN" or "END" in which case it is not really a property, but the marker for the start or end of a component */ end = 0; str = icalparser_get_prop_name(line, &end); if (str == 0 || strlen(str) == 0 ){ /* Could not get a property name */ - icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + icalcomponent *tail = pvl_data(pvl_tail(parser->components)); if (tail){ insert_error(tail,line, "Got a data line, but could not find a property name or component begin tag", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); } tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } /********************************************************************** * Handle begin and end of components **********************************************************************/ /* If the property name is BEGIN or END, we are actually starting or ending a new component */ + if(strcmp(str,"BEGIN") == 0){ icalcomponent *c; icalcomponent_kind comp_kind; - impl->level++; + + parser->level++; str = icalparser_get_next_value(end,&end, value_kind); comp_kind = icalenum_string_to_component_kind(str); + if (comp_kind == ICAL_NO_COMPONENT){ + + c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); insert_error(c,str,"Parse error in component name", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); } c = icalcomponent_new(comp_kind); if (c == 0){ c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT); insert_error(c,str,"Parse error in component name", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); } - pvl_push(impl->components,c); + pvl_push(parser->components,c); - impl->state = ICALPARSER_BEGIN_COMP; + parser->state = ICALPARSER_BEGIN_COMP; return 0; } else if (strcmp(str,"END") == 0 ) { icalcomponent* tail; - impl->level--; + parser->level--; str = icalparser_get_next_value(end,&end, value_kind); /* Pop last component off of list and add it to the second-to-last*/ - impl->root_component = pvl_pop(impl->components); + parser->root_component = pvl_pop(parser->components); - tail = pvl_data(pvl_tail(impl->components)); + tail = pvl_data(pvl_tail(parser->components)); if(tail != 0){ - icalcomponent_add_component(tail,impl->root_component); + icalcomponent_add_component(tail,parser->root_component); } tail = 0; /* Return the component if we are back to the 0th level */ - if (impl->level == 0){ + if (parser->level == 0){ icalcomponent *rtrn; - if(pvl_count(impl->components) != 0){ + if(pvl_count(parser->components) != 0){ /* There are still components on the stack -- this means that one of them did not have a proper "END" */ - pvl_push(impl->components,impl->root_component); - icalparser_clean(parser); /* may reset impl->root_component*/ + pvl_push(parser->components,parser->root_component); + icalparser_clean(parser); /* may reset parser->root_component*/ } - assert(pvl_count(impl->components) == 0); + assert(pvl_count(parser->components) == 0); - impl->state = ICALPARSER_SUCCESS; - rtrn = impl->root_component; - impl->root_component = 0; + parser->state = ICALPARSER_SUCCESS; + rtrn = parser->root_component; + parser->root_component = 0; return rtrn; } else { - impl->state = ICALPARSER_END_COMP; + parser->state = ICALPARSER_END_COMP; return 0; } } /* There is no point in continuing if we have not seen a component yet */ - if(pvl_data(pvl_tail(impl->components)) == 0){ - impl->state = ICALPARSER_ERROR; + if(pvl_data(pvl_tail(parser->components)) == 0){ + parser->state = ICALPARSER_ERROR; return 0; } /********************************************************************** * Handle property names **********************************************************************/ /* At this point, the property name really is a property name, (Not a component name) so make a new property and add it to the component */ prop_kind = icalproperty_string_to_kind(str); prop = icalproperty_new(prop_kind); if (prop != 0){ - icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + icalcomponent *tail = pvl_data(pvl_tail(parser->components)); if(prop_kind==ICAL_X_PROPERTY){ icalproperty_set_x_name(prop,str); } icalcomponent_add_property(tail, prop); /* Set the value kind for the default for this type of property. This may be re-set by a VALUE parameter */ value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop)); } else { - icalcomponent* tail = pvl_data(pvl_tail(impl->components)); + icalcomponent* tail = pvl_data(pvl_tail(parser->components)); insert_error(tail,str,"Parse error in property name", ICAL_XLICERRORTYPE_PROPERTYPARSEERROR); tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } /********************************************************************** * Handle parameter values **********************************************************************/ /* Now, add any parameters to the last property */ - p = 0; while(1) { if (*(end-1) == ':'){ /* if the last seperator was a ":" and the value is a URL, icalparser_get_next_parameter will find the ':' in the URL, so better break now. */ break; } str = icalparser_get_next_parameter(end,&end); if (str != 0){ char* name; char* pvalue; icalparameter *param = 0; icalparameter_kind kind; - icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + icalcomponent *tail = pvl_data(pvl_tail(parser->components)); name = icalparser_get_param_name(str,&pvalue); if (name == 0){ /* 'tail' defined above */ insert_error(tail, str, "Cant parse parameter name", ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); tail = 0; break; } kind = icalparameter_string_to_kind(name); if(kind == ICAL_X_PARAMETER){ param = icalparameter_new(ICAL_X_PARAMETER); if(param != 0){ icalparameter_set_xname(param,name); icalparameter_set_xvalue(param,pvalue); } } else if (kind != ICAL_NO_PARAMETER){ param = icalparameter_new_from_value_string(kind,pvalue); } else { /* Error. Failed to parse the parameter*/ /* 'tail' defined above */ insert_error(tail, str, "Cant parse parameter name", ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR); tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } if (param == 0){ /* 'tail' defined above */ insert_error(tail,str,"Cant parse parameter value", ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; continue; } /* If it is a VALUE parameter, set the kind of value*/ if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){ value_kind = (icalvalue_kind) icalparameter_value_to_value_kind( icalparameter_get_value(param) ); if (value_kind == ICAL_NO_VALUE){ /* Ooops, could not parse the value of the parameter ( it was not one of the defined values ), so reset the value_kind */ insert_error( tail, str, "Got a VALUE parameter with an unknown type", ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR); icalparameter_free(param); value_kind = icalproperty_kind_to_value_kind( icalproperty_isa(prop)); icalparameter_free(param); tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } } /* Everything is OK, so add the parameter */ icalproperty_add_parameter(prop,param); tail = 0; } else { /* if ( str != 0) */ /* If we did not get a param string, go on to looking for a value */ break; } /* if ( str != 0) */ } /* while(1) */ /********************************************************************** * Handle values **********************************************************************/ /* Look for values. If there are ',' characters in the values, then there are multiple values, so clone the current parameter and add one part of the value to each clone */ vcount=0; while(1) { str = icalparser_get_next_value(end,&end, value_kind); if (str != 0){ if (vcount > 0){ /* Actually, only clone after the second value */ icalproperty* clone = icalproperty_new_clone(prop); - icalcomponent* tail = pvl_data(pvl_tail(impl->components)); + icalcomponent* tail = pvl_data(pvl_tail(parser->components)); icalcomponent_add_property(tail, clone); prop = clone; tail = 0; } value = icalvalue_new_from_string(value_kind, str); /* Don't add properties without value */ if (value == 0){ char temp[200]; /* HACK */ icalproperty_kind prop_kind = icalproperty_isa(prop); - icalcomponent* tail = pvl_data(pvl_tail(impl->components)); + icalcomponent* tail = pvl_data(pvl_tail(parser->components)); sprintf(temp,"Cant parse as %s value in %s property. Removing entire property", icalvalue_kind_to_string(value_kind), icalproperty_kind_to_string(prop_kind)); insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR); /* Remove the troublesome property */ icalcomponent_remove_property(tail,prop); icalproperty_free(prop); prop = 0; tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } else { vcount++; icalproperty_set_value(prop, value); } } else { if (vcount == 0){ char temp[200]; /* HACK */ icalproperty_kind prop_kind = icalproperty_isa(prop); - icalcomponent *tail = pvl_data(pvl_tail(impl->components)); + icalcomponent *tail = pvl_data(pvl_tail(parser->components)); sprintf(temp,"No value for %s property. Removing entire property", icalproperty_kind_to_string(prop_kind)); insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR); /* Remove the troublesome property */ icalcomponent_remove_property(tail,prop); icalproperty_free(prop); prop = 0; tail = 0; - impl->state = ICALPARSER_ERROR; + parser->state = ICALPARSER_ERROR; return 0; } else { break; } } } /**************************************************************** * End of component parsing. *****************************************************************/ - if (pvl_data(pvl_tail(impl->components)) == 0 && - impl->level == 0){ + if (pvl_data(pvl_tail(parser->components)) == 0 && + parser->level == 0){ /* HACK. Does this clause ever get executed? */ - impl->state = ICALPARSER_SUCCESS; + parser->state = ICALPARSER_SUCCESS; assert(0); - return impl->root_component; + return parser->root_component; } else { - impl->state = ICALPARSER_IN_PROGRESS; + parser->state = ICALPARSER_IN_PROGRESS; return 0; } } icalparser_state icalparser_get_state(icalparser* parser) { - struct icalparser_impl* impl = (struct icalparser_impl*) parser; - return impl->state; + return parser->state; } icalcomponent* icalparser_clean(icalparser* parser) { - struct icalparser_impl* impl = (struct icalparser_impl*) parser; icalcomponent *tail; icalerror_check_arg_rz((parser != 0 ),"parser"); /* We won't get a clean exit if some components did not have an "END" tag. Clear off any component that may be left in the list */ - while((tail=pvl_data(pvl_tail(impl->components))) != 0){ + while((tail=pvl_data(pvl_tail(parser->components))) != 0){ insert_error(tail," ", "Missing END tag for this component. Closing component at end of input.", ICAL_XLICERRORTYPE_COMPONENTPARSEERROR); - impl->root_component = pvl_pop(impl->components); - tail=pvl_data(pvl_tail(impl->components)); + parser->root_component = pvl_pop(parser->components); + tail=pvl_data(pvl_tail(parser->components)); if(tail != 0){ - if(icalcomponent_get_parent(impl->root_component)!=0){ + if(icalcomponent_get_parent(parser->root_component)!=0){ icalerror_warn("icalparser_clean is trying to attach a component for the second time"); } else { - icalcomponent_add_component(tail,impl->root_component); + icalcomponent_add_component(tail,parser->root_component); } } } - return impl->root_component; + return parser->root_component; } struct slg_data { const char* pos; const char* str; }; -char* string_line_generator(char *out, size_t buf_size, void *d) + +char* icalparser_string_line_generator(char *out, size_t buf_size, void *d) { char *n; size_t size; struct slg_data* data = (struct slg_data*)d; if(data->pos==0){ data->pos=data->str; } /* If the pointer is at the end of the string, we are done */ if (*(data->pos)==0){ return 0; } n = strchr(data->pos,'\n'); if (n == 0){ size = strlen(data->pos); } else { n++; /* include newline in output */ size = (n-data->pos); } if (size > buf_size-1){ size = buf_size-1; } strncpy(out,data->pos,size); *(out+size) = '\0'; data->pos += size; return out; } icalcomponent* icalparser_parse_string(const char* str) { icalcomponent *c; struct slg_data d; icalparser *p; icalerrorstate es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); d.pos = 0; d.str = str; p = icalparser_new(); icalparser_set_gen_data(p,&d); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); - c = icalparser_parse(p,string_line_generator); + c = icalparser_parse(p,icalparser_string_line_generator); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); icalparser_free(p); return c; } diff --git a/libical/src/libical/icalparser.h b/libical/src/libical/icalparser.h index 5e1c88f..7773af4 100644 --- a/libical/src/libical/icalparser.h +++ b/libical/src/libical/icalparser.h @@ -1,93 +1,96 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalparser.h CREATOR: eric 20 April 1999 $Id$ (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 icalparser.h ======================================================================*/ #ifndef ICALPARSER_H #define ICALPARSER_H #include "icalenums.h" #include "icaltypes.h" #include"icalcomponent.h" #include <stdio.h> /* For FILE* */ -typedef void* icalparser; +typedef struct icalparser_impl icalparser; -/*********************************************************************** - * Line-oriented parsing. +/** + * @file icalparser.h + * @brief Line-oriented parsing. * - * Create a new parser via icalparse_new_parser, then add ines one at + * Create a new parser via icalparse_new_parser, then add lines one at * a time with icalparse_add_line(). icalparser_add_line() will return * non-zero when it has finished with a component. - ***********************************************************************/ + */ typedef enum icalparser_state { ICALPARSER_ERROR, ICALPARSER_SUCCESS, ICALPARSER_BEGIN_COMP, ICALPARSER_END_COMP, ICALPARSER_IN_PROGRESS } icalparser_state; icalparser* icalparser_new(void); icalcomponent* icalparser_add_line(icalparser* parser, char* str ); icalcomponent* icalparser_clean(icalparser* parser); icalparser_state icalparser_get_state(icalparser* parser); void icalparser_free(icalparser* parser); -/*********************************************************************** +/** * Message oriented parsing. icalparser_parse takes a string that * holds the text ( in RFC 2445 format ) and returns a pointer to an * icalcomponent. The caller owns the memory. line_gen_func is a * pointer to a function that returns one content line per invocation - **********************************************************************/ + */ icalcomponent* icalparser_parse(icalparser *parser, - char* (*line_gen_func)(char *s, size_t size, void *d)); + char* (*line_gen_func)(char *s, size_t size, void *d)); -/* Set the data that icalparser_parse will give to the line_gen_func - as the parameter 'd'*/ +/** + Set the data that icalparser_parse will give to the line_gen_func + as the parameter 'd' + */ void icalparser_set_gen_data(icalparser* parser, void* data); icalcomponent* icalparser_parse_string(const char* str); /*********************************************************************** * Parser support functions ***********************************************************************/ -/* Use the flex/bison parser to turn a string into a value type */ +/** Use the flex/bison parser to turn a string into a value type */ icalvalue* icalparser_parse_value(icalvalue_kind kind, const char* str, icalcomponent** errors); -/* Given a line generator function, return a single iCal content line.*/ +/** Given a line generator function, return a single iCal content line.*/ char* icalparser_get_line(icalparser* parser, char* (*line_gen_func)(char *s, size_t size, void *d)); -char* string_line_generator(char *out, size_t buf_size, void *d); +char* icalparser_string_line_generator(char *out, size_t buf_size, void *d); #endif /* !ICALPARSE_H */ diff --git a/libical/src/libical/icalperiod.c b/libical/src/libical/icalperiod.c index c74c157..0dfbe81 100644 --- a/libical/src/libical/icalperiod.c +++ b/libical/src/libical/icalperiod.c @@ -1,170 +1,170 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalperiod.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 "icalperiod.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 struct icalperiodtype icalperiodtype_from_string (const char* str) { struct icalperiodtype p, null_p; char *s = icalmemory_strdup(str); char *start, *end = s; icalerrorstate es; /* Errors are normally generated in the following code, so save the error state for resoration later */ icalerrorenum e = icalerrno; p.start = p.end = icaltime_null_time(); p.duration = icaldurationtype_from_int(0); null_p = p; if(s == 0) goto error; start = s; end = strchr(s, '/'); if(end == 0) goto error; *end = 0; end++; p.start = icaltime_from_string(start); if (icaltime_is_null_time(p.start)) goto error; es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); p.end = icaltime_from_string(end); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); if (icaltime_is_null_time(p.end)){ p.duration = icaldurationtype_from_string(end); if(icaldurationtype_as_int(p.duration) == 0) goto error; } icalerrno = e; + icalmemory_free_buffer(s); + return p; error: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + + if (s) + icalmemory_free_buffer (s); return null_p; } const char* icalperiodtype_as_ical_string(struct icalperiodtype p) { const char* start; const char* end; char *buf; size_t buf_size = 40; char* buf_ptr = 0; buf = (char*)icalmemory_new_buffer(buf_size); buf_ptr = buf; start = icaltime_as_ical_string(p.start); icalmemory_append_string(&buf, &buf_ptr, &buf_size, start); if(!icaltime_is_null_time(p.end)){ end = icaltime_as_ical_string(p.end); } else { end = icaldurationtype_as_ical_string(p.duration); } icalmemory_append_char(&buf, &buf_ptr, &buf_size, '/'); icalmemory_append_string(&buf, &buf_ptr, &buf_size, end); + icalmemory_add_tmp_buffer(buf); return buf; } -struct icalperiodtype icalperiodtype_null_period() { +struct icalperiodtype icalperiodtype_null_period(void) { struct icalperiodtype p; p.start = icaltime_null_time(); p.end = icaltime_null_time(); p.duration = icaldurationtype_null_duration(); return p; } int icalperiodtype_is_null_period(struct icalperiodtype p){ if(icaltime_is_null_time(p.start) && icaltime_is_null_time(p.end) && icaldurationtype_is_null_duration(p.duration)){ return 1; } else { return 0; } } int icalperiodtype_is_valid_period(struct icalperiodtype p){ if(icaltime_is_valid_time(p.start) && (icaltime_is_valid_time(p.end) || icaltime_is_null_time(p.end)) ) { return 1; } return 0; } diff --git a/libical/src/libical/icalperiod.h b/libical/src/libical/icalperiod.h index 64d5323..5f07dd4 100644 --- a/libical/src/libical/icalperiod.h +++ b/libical/src/libical/icalperiod.h @@ -1,55 +1,55 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalperiod.h CREATOR: eric 26 Jan 2001 $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 ======================================================================*/ #ifndef ICALPERIOD_H #define ICALPERIOD_H #include "icaltime.h" #include "icalduration.h" struct icalperiodtype { struct icaltimetype start; struct icaltimetype end; struct icaldurationtype duration; }; struct icalperiodtype icalperiodtype_from_string (const char* str); const char* icalperiodtype_as_ical_string(struct icalperiodtype p); -struct icalperiodtype icalperiodtype_null_period(); -int icalperiodtype_is_null_period(struct icalperiodtype p); -int icalperiodtype_is_valid_period(struct icalperiodtype p); +struct icalperiodtype icalperiodtype_null_period(void); +int icalperiodtype_is_null_period(struct icalperiodtype p); +int icalperiodtype_is_valid_period(struct icalperiodtype p); #endif /* !ICALTIME_H */ diff --git a/libical/src/libical/icalproperty.c b/libical/src/libical/icalproperty.c index 7f2cfa5..45d7a75 100644 --- a/libical/src/libical/icalproperty.c +++ b/libical/src/libical/icalproperty.c @@ -1,810 +1,997 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalproperty.c CREATOR: eric 28 April 1999 $Id$ (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 icalproperty.c ======================================================================*/ -/*#line 27 "icalproperty.c.in"*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalproperty.h" #include "icalparameter.h" #include "icalcomponent.h" #include "pvl.h" #include "icalenums.h" #include "icalerror.h" #include "icalmemory.h" #include "icalparser.h" #include <string.h> /* For icalmemory_strdup, rindex */ #include <assert.h> #include <stdlib.h> #include <errno.h> #include <stdio.h> /* for printf */ #include <stdarg.h> /* for va_list, va_start, etc. */ -int snprintf(char *str, size_t n, char const *fmt, ...); - -#define TMP_BUF_SIZE 1024 +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif /* Private routines for icalproperty */ void icalvalue_set_parent(icalvalue* value, icalproperty* property); icalproperty* icalvalue_get_parent(icalvalue* value); void icalparameter_set_parent(icalparameter* param, icalproperty* property); icalproperty* icalparameter_get_parent(icalparameter* value); void icalproperty_set_x_name(icalproperty* prop, const char* name); struct icalproperty_impl { char id[5]; icalproperty_kind kind; char* x_name; pvl_list parameters; pvl_elem parameter_iterator; icalvalue* value; icalcomponent *parent; }; -void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args) +void icalproperty_add_parameters(icalproperty* prop, va_list args) { - void* vp; - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - while((vp = va_arg(args, void*)) != 0) { if (icalvalue_isa_value(vp) != 0 ){ } else if (icalparameter_isa_parameter(vp) != 0 ){ - icalproperty_add_parameter((icalproperty*)impl, + icalproperty_add_parameter((icalproperty*)prop, (icalparameter*)vp); } else { - assert(0); + icalerror_set_errno(ICAL_BADARG_ERROR); } } - - } -struct icalproperty_impl* -icalproperty_new_impl (icalproperty_kind kind) +icalproperty* +icalproperty_new_impl(icalproperty_kind kind) { - struct icalproperty_impl* prop; + icalproperty* prop; + + if (!icalproperty_kind_is_valid(kind)) + return NULL; - if ( ( prop = (struct icalproperty_impl*) - malloc(sizeof(struct icalproperty_impl))) == 0) { + if ( ( prop = (icalproperty*) malloc(sizeof(icalproperty))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } strcpy(prop->id,"prop"); prop->kind = kind; prop->parameters = pvl_newlist(); prop->parameter_iterator = 0; prop->value = 0; prop->x_name = 0; prop->parent = 0; return prop; } icalproperty* icalproperty_new (icalproperty_kind kind) { - if(kind == ICAL_NO_PROPERTY){ + if (kind == ICAL_NO_PROPERTY){ return 0; } return (icalproperty*)icalproperty_new_impl(kind); } icalproperty* -icalproperty_new_clone(icalproperty* prop) +icalproperty_new_clone(icalproperty* old) { - struct icalproperty_impl *old = (struct icalproperty_impl*)prop; - struct icalproperty_impl *new = icalproperty_new_impl(old->kind); + icalproperty *new = icalproperty_new_impl(old->kind); pvl_elem p; - icalerror_check_arg_rz((prop!=0),"Prop"); icalerror_check_arg_rz((old!=0),"old"); icalerror_check_arg_rz((new!=0),"new"); if (old->value !=0) { new->value = icalvalue_new_clone(old->value); } if (old->x_name != 0) { new->x_name = icalmemory_strdup(old->x_name); if (new->x_name == 0) { icalproperty_free(new); icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } } for(p=pvl_head(old->parameters);p != 0; p = pvl_next(p)){ icalparameter *param = icalparameter_new_clone(pvl_data(p)); if (param == 0){ icalproperty_free(new); icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } pvl_push(new->parameters,param); } return new; } icalproperty* icalproperty_new_from_string(const char* str) { size_t buf_size = 1024; char* buf = icalmemory_new_buffer(buf_size); char* buf_ptr = buf; icalproperty *prop; icalcomponent *comp; int errors = 0; icalerror_check_arg_rz( (str!=0),"str"); /* Is this a HACK or a crafty reuse of code? */ icalmemory_append_string(&buf, &buf_ptr, &buf_size, "BEGIN:VCALENDAR\n"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, str); icalmemory_append_string(&buf, &buf_ptr, &buf_size, "\n"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, "END:VCALENDAR\n"); comp = icalparser_parse_string(buf); if(comp == 0){ icalerror_set_errno(ICAL_PARSE_ERROR); return 0; } errors = icalcomponent_count_errors(comp); prop = icalcomponent_get_first_property(comp,ICAL_ANY_PROPERTY); icalcomponent_remove_property(comp,prop); icalcomponent_free(comp); free(buf); if(errors > 0){ icalproperty_free(prop); return 0; } else { return prop; } } void -icalproperty_free (icalproperty* prop) +icalproperty_free (icalproperty* p) { - struct icalproperty_impl *p; - icalparameter* param; - icalerror_check_arg_rv((prop!=0),"prop"); - - p = (struct icalproperty_impl*)prop; + icalerror_check_arg_rv((p!=0),"prop"); #ifdef ICAL_FREE_ON_LIST_IS_ERROR icalerror_assert( (p->parent ==0),"Tried to free a property that is still attached to a component. "); #else if(p->parent !=0){ return; } #endif if (p->value != 0){ icalvalue_set_parent(p->value,0); icalvalue_free(p->value); } while( (param = pvl_pop(p->parameters)) != 0){ icalparameter_free(param); } pvl_free(p->parameters); if (p->x_name != 0) { free(p->x_name); } p->kind = ICAL_NO_PROPERTY; p->parameters = 0; p->parameter_iterator = 0; p->value = 0; p->x_name = 0; p->id[0] = 'X'; free(p); } -const char* -icalproperty_as_ical_string (icalproperty* prop) -{ - icalparameter *param; +/* This returns where the start of the next line should be. chars_left does + not include the trailing '\0'. */ +#define MAX_LINE_LEN 75 +/*#define MAX_LINE_LEN 120*/ - /* Create new buffer that we can append names, parameters and a - value to, and reallocate as needed. Later, this buffer will be - copied to a icalmemory_tmp_buffer, which is managed internally - by libical, so it can be given to the caller without fear of - the caller forgetting to free it */ - - const char* property_name = 0; - size_t buf_size = 1024; - char* buf = icalmemory_new_buffer(buf_size); - char* buf_ptr = buf; - icalvalue* value; - char *out_buf; +static char* +get_next_line_start (char *line_start, int chars_left) +{ + char *pos; - char newline[] = "\n"; + /* If we have 74 chars or less left, we can output all of them. + we return a pointer to the '\0' at the end of the string. */ + if (chars_left < MAX_LINE_LEN) { + return line_start + chars_left; + } - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - - icalerror_check_arg_rz( (prop!=0),"prop"); + /* Now we jump to the last possible character of the line, and step back + trying to find a ';' ':' or ' '. If we find one, we return the character + after it. */ + pos = line_start + MAX_LINE_LEN - 2; + while (pos > line_start) { + if (*pos == ';' || *pos == ':' || *pos == ' ') { + return pos + 1; + } + pos--; + } + /* Now try to split on a UTF-8 boundary defined as a 7-bit + value or as a byte with the two high-most bits set: + 11xxxxxx. See http://czyborra.com/utf/ */ + pos = line_start + MAX_LINE_LEN - 1; + while (pos > line_start) { + /* plain ascii */ + if ((*pos & 128) == 0) + return pos; - /* Append property name */ + /* utf8 escape byte */ + if ((*pos & 192) == 192) + return pos; - if (impl->kind == ICAL_X_PROPERTY && impl->x_name != 0){ - property_name = impl->x_name; - } else { - property_name = icalproperty_kind_to_string(impl->kind); + pos--; } - if (property_name == 0 ) { - icalerror_warn("Got a property of an unknown kind."); - icalmemory_free_buffer(buf); - return 0; - - } + /* Give up, just break at 74 chars (the 75th char is the space at + the start of the line). */ + + return line_start + MAX_LINE_LEN - 1; +} - icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); +/** This splits the property into lines less than 75 octects long (as + * specified in RFC2445). It tries to split after a ';' if it can. + * It returns a tmp buffer. NOTE: I'm not sure if it matters if we + * split a line in the middle of a UTF-8 character. It probably won't + * look nice in a text editor. + */ +static char* +fold_property_line (char *text) +{ + size_t buf_size; + char *buf, *buf_ptr, *line_start, *next_line_start, *out_buf; + int len, chars_left, first_line; + char ch; + + /* Start with a buffer twice the size of our property line, so we almost + certainly won't overflow it. */ + len = strlen (text); + buf_size = len * 2; + buf = icalmemory_new_buffer (buf_size); + buf_ptr = buf; + + /* Step through the text, finding each line to add to the output. */ + line_start = text; + chars_left = len; + first_line = 1; + for (;;) { + if (chars_left <= 0) + break; + + /* This returns the first character for the next line. */ + next_line_start = get_next_line_start (line_start, chars_left); + + /* If this isn't the first line, we need to output a newline and space + first. */ + if (!first_line) { + icalmemory_append_string (&buf, &buf_ptr, &buf_size, "\n "); + } + first_line = 0; + + /* This adds the line to our tmp buffer. We temporarily place a '\0' + in text, so we can copy the line in one go. */ + ch = *next_line_start; + *next_line_start = '\0'; + icalmemory_append_string (&buf, &buf_ptr, &buf_size, line_start); + *next_line_start = ch; + /* Now we move on to the next line. */ + chars_left -= (next_line_start - line_start); + line_start = next_line_start; + } + + /* Copy it to a temporary buffer, and then free it. */ + out_buf = icalmemory_tmp_buffer (strlen (buf) + 1); + strcpy (out_buf, buf); + icalmemory_free_buffer (buf); + + return out_buf; +} - /* Determine what VALUE parameter to include. The VALUE parameters - are ignored in the normal parameter printing ( the block after - this one, so we need to do it here */ - { +/* Determine what VALUE parameter to include. The VALUE parameters + are ignored in the normal parameter printing ( the block after + this one, so we need to do it here */ +static const char * +icalproperty_get_value_kind(icalproperty *prop) +{ const char* kind_string = 0; icalparameter *orig_val_param = icalproperty_get_first_parameter(prop,ICAL_VALUE_PARAMETER); - icalvalue *value = icalproperty_get_value(impl); + icalvalue *value = icalproperty_get_value(prop); icalvalue_kind orig_kind = ICAL_NO_VALUE; icalvalue_kind this_kind = ICAL_NO_VALUE; icalvalue_kind default_kind - = icalproperty_kind_to_value_kind(impl->kind); + = icalproperty_kind_to_value_kind(prop->kind); if(orig_val_param){ orig_kind = (icalvalue_kind)icalparameter_get_value(orig_val_param); } if(value != 0){ this_kind = icalvalue_isa(value); } if(this_kind == default_kind && orig_kind != ICAL_NO_VALUE){ /* The kind is the default, so it does not need to be included, but do it anyway, since it was explicit in the property. But, use the default, not the one specified in the property */ kind_string = icalvalue_kind_to_string(default_kind); } else if (this_kind != default_kind && this_kind != ICAL_NO_VALUE){ /* Not the default, so it must be specified */ kind_string = icalvalue_kind_to_string(this_kind); } else { /* Don'tinclude the VALUE parameter at all */ } - if(kind_string!=0){ - icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, "VALUE="); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); - } + return kind_string; +} + +const char* +icalproperty_as_ical_string (icalproperty* prop) +{ + icalparameter *param; + + /* Create new buffer that we can append names, parameters and a + value to, and reallocate as needed. Later, this buffer will be + copied to a icalmemory_tmp_buffer, which is managed internally + by libical, so it can be given to the caller without fear of + the caller forgetting to free it */ + + const char* property_name = 0; + size_t buf_size = 1024; + char* buf = icalmemory_new_buffer(buf_size); + char* buf_ptr = buf; + icalvalue* value; + char *out_buf; + const char* kind_string = 0; + + char newline[] = "\n"; + + + icalerror_check_arg_rz( (prop!=0),"prop"); + + + /* Append property name */ + + if (prop->kind == ICAL_X_PROPERTY && prop->x_name != 0){ + property_name = prop->x_name; + } else { + property_name = icalproperty_kind_to_string(prop->kind); + } + + if (property_name == 0 ) { + icalerror_warn("Got a property of an unknown kind."); + icalmemory_free_buffer(buf); + return 0; + } + icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); + + kind_string = icalproperty_get_value_kind(prop); + if(kind_string!=0){ + icalmemory_append_string(&buf, &buf_ptr, &buf_size, ";VALUE="); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); } /* Append parameters */ for(param = icalproperty_get_first_parameter(prop,ICAL_ANY_PARAMETER); param != 0; param = icalproperty_get_next_parameter(prop,ICAL_ANY_PARAMETER)) { - char* kind_string = icalparameter_as_ical_string(param); icalparameter_kind kind = icalparameter_isa(param); + kind_string = icalparameter_as_ical_string(param); if(kind==ICAL_VALUE_PARAMETER){ continue; } if (kind_string == 0 ) { - char temp[TMP_BUF_SIZE]; - snprintf(temp, TMP_BUF_SIZE,"Got a parameter of unknown kind in %s property",property_name); - icalerror_warn(temp); + icalerror_warn("Got a parameter of unknown kind for the following property"); + + icalerror_warn((property_name) ? property_name : "(NULL)"); continue; } - icalmemory_append_string(&buf, &buf_ptr, &buf_size, " ;"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, ";"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, kind_string); - icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); - } /* Append value */ - icalmemory_append_string(&buf, &buf_ptr, &buf_size, " :"); + icalmemory_append_string(&buf, &buf_ptr, &buf_size, ":"); value = icalproperty_get_value(prop); if (value != 0){ const char *str = icalvalue_as_ical_string(value); icalerror_assert((str !=0),"Could not get string representation of a value"); icalmemory_append_string(&buf, &buf_ptr, &buf_size, str); } else { icalmemory_append_string(&buf, &buf_ptr, &buf_size,"ERROR: No Value"); } icalmemory_append_string(&buf, &buf_ptr, &buf_size, newline); /* Now, copy the buffer to a tmp_buffer, which is safe to give to the caller without worring about de-allocating it. */ - - out_buf = icalmemory_tmp_buffer(strlen(buf)+1); - strcpy(out_buf, buf); + /* We now use a function to fold the line properly every 75 characters. */ + out_buf = fold_property_line (buf); icalmemory_free_buffer(buf); return out_buf; } icalproperty_kind -icalproperty_isa (icalproperty* property) +icalproperty_isa (icalproperty* p) { - struct icalproperty_impl *p = (struct icalproperty_impl*)property; - - if(property != 0){ + if(p != 0){ return p->kind; } return ICAL_NO_PROPERTY; } int icalproperty_isa_property (void* property) { - struct icalproperty_impl *impl = (struct icalproperty_impl*)property; + icalproperty *impl = (icalproperty *) property; icalerror_check_arg_rz( (property!=0), "property"); - if (strcmp(impl->id,"prop") == 0) { return 1; } else { return 0; } } void -icalproperty_add_parameter (icalproperty* prop,icalparameter* parameter) +icalproperty_add_parameter (icalproperty* p,icalparameter* parameter) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; - - icalerror_check_arg_rv( (prop!=0),"prop"); + icalerror_check_arg_rv( (p!=0),"prop"); icalerror_check_arg_rv( (parameter!=0),"parameter"); pvl_push(p->parameters, parameter); } void icalproperty_set_parameter (icalproperty* prop,icalparameter* parameter) { icalparameter_kind kind; icalerror_check_arg_rv( (prop!=0),"prop"); icalerror_check_arg_rv( (parameter!=0),"parameter"); kind = icalparameter_isa(parameter); - - icalproperty_remove_parameter(prop,kind); + if (kind != ICAL_X_PARAMETER) + icalproperty_remove_parameter_by_kind(prop,kind); + else + icalproperty_remove_parameter_by_name(prop, + icalparameter_get_xname(parameter)); icalproperty_add_parameter(prop,parameter); } void icalproperty_set_parameter_from_string(icalproperty* prop, const char* name, const char* value) { icalparameter_kind kind; icalparameter *param; icalerror_check_arg_rv( (prop!=0),"prop"); icalerror_check_arg_rv( (name!=0),"name"); icalerror_check_arg_rv( (value!=0),"value"); kind = icalparameter_string_to_kind(name); if(kind == ICAL_NO_PARAMETER){ icalerror_set_errno(ICAL_BADARG_ERROR); return; } - + param = icalparameter_new_from_value_string(kind,value); if (param == 0){ icalerror_set_errno(ICAL_BADARG_ERROR); return; } + if(kind == ICAL_X_PARAMETER){ + icalparameter_set_xname(param, name); + } + icalproperty_set_parameter(prop,param); } const char* icalproperty_get_parameter_as_string(icalproperty* prop, const char* name) { icalparameter_kind kind; icalparameter *param; char* str; char* pv; icalerror_check_arg_rz( (prop!=0),"prop"); icalerror_check_arg_rz( (name!=0),"name"); kind = icalparameter_string_to_kind(name); - if(kind == ICAL_NO_PROPERTY){ + if(kind == ICAL_NO_PARAMETER){ /* icalenum_string_to_parameter_kind will set icalerrno */ return 0; } + + for(param = icalproperty_get_first_parameter(prop,kind); + param != 0; + param = icalproperty_get_next_parameter(prop,kind)) { + if (kind != ICAL_X_PARAMETER) { + break; + } - param = icalproperty_get_first_parameter(prop,kind); + if (strcmp(icalparameter_get_xname(param),name)==0) { + break; + } + } if (param == 0){ return 0; } + str = icalparameter_as_ical_string(param); pv = strchr(str,'='); if(pv == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } return pv+1; } +/** @see icalproperty_remove_parameter_by_kind() + * + * @deprecated Please use icalproperty_remove_parameter_by_kind() + * instead. + */ + void -icalproperty_remove_parameter (icalproperty* prop, icalparameter_kind kind) +icalproperty_remove_parameter(icalproperty* prop, icalparameter_kind kind) +{ + icalproperty_remove_parameter_by_kind(prop, kind); +} + + +/** @brief Remove all parameters with the specified kind. + * + * @param prop A valid icalproperty. + * @param kind The kind to remove (ex. ICAL_TZID_PARAMETER) + * + * See icalproperty_remove_parameter_by_name() and + * icalproperty_remove_parameter_by_ref() for alternate ways of + * removing parameters + */ + +void +icalproperty_remove_parameter_by_kind(icalproperty* prop, icalparameter_kind kind) { pvl_elem p; - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; icalerror_check_arg_rv((prop!=0),"prop"); - for(p=pvl_head(impl->parameters);p != 0; p = pvl_next(p)){ + for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){ icalparameter* param = (icalparameter *)pvl_data (p); if (icalparameter_isa(param) == kind) { - pvl_remove (impl->parameters, p); - icalparameter_free (param); + pvl_remove (prop->parameters, p); + icalparameter_free(param); break; } } } -int -icalproperty_count_parameters (icalproperty* prop) +/** @brief Remove all parameters with the specified name. + * + * @param prop A valid icalproperty. + * @param name The name of the parameter to remove + * + * This function removes paramters with the given name. The name + * corresponds to either a built-in name (TZID, etc.) or the name of + * an extended parameter (X-FOO) + * + * See icalproperty_remove_parameter_by_kind() and + * icalproperty_remove_parameter_by_ref() for alternate ways of removing + * parameters + */ + + +void +icalproperty_remove_parameter_by_name(icalproperty* prop, const char *name) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; + pvl_elem p; + + icalerror_check_arg_rv((prop!=0),"prop"); + + for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){ + icalparameter* param = (icalparameter *)pvl_data (p); + const char * kind_string; + + if (icalparameter_isa(param) == ICAL_X_PARAMETER) + kind_string = icalparameter_get_xname(param); + else + kind_string = icalparameter_kind_to_string(icalparameter_isa(param)); + + if (!kind_string) + continue; + if (0 == strcmp(kind_string, name)) { + pvl_remove (prop->parameters, p); + break; + } + } +} + + +/** @brief Remove the specified parameter reference from the property. + * + * @param prop A valid icalproperty. + * @param parameter A reference to a specific icalparameter. + * + * This function removes the specified parameter reference from the + * property. + */ + +void +icalproperty_remove_parameter_by_ref(icalproperty* prop, icalparameter* parameter) +{ + pvl_elem p; + icalparameter_kind kind; + const char *name; + + icalerror_check_arg_rv((prop!=0),"prop"); + icalerror_check_arg_rv((parameter!=0),"parameter"); + + kind = icalparameter_isa(parameter); + name = icalparameter_get_xname(parameter); + + /* + * FIXME If it's an X- parameter, also compare the names. It would be nice + * to have a better abstraction like icalparameter_equals() + */ + for(p=pvl_head(prop->parameters);p != 0; p = pvl_next(p)){ + icalparameter* p_param = (icalparameter *)pvl_data (p); + if (icalparameter_isa(p_param) == kind && + (kind != ICAL_X_PARAMETER || + !strcmp(icalparameter_get_xname(p_param), name))) { + pvl_remove (prop->parameters, p); + icalparameter_free(p_param); + break; + } + } +} + + +int +icalproperty_count_parameters (const icalproperty* prop) +{ if(prop != 0){ - return pvl_count(p->parameters); + return pvl_count(prop->parameters); } icalerror_set_errno(ICAL_USAGE_ERROR); return -1; } icalparameter* -icalproperty_get_first_parameter (icalproperty* prop, icalparameter_kind kind) +icalproperty_get_first_parameter(icalproperty* p, icalparameter_kind kind) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; - - icalerror_check_arg_rz( (prop!=0),"prop"); + icalerror_check_arg_rz( (p!=0),"prop"); p->parameter_iterator = pvl_head(p->parameters); if (p->parameter_iterator == 0) { return 0; } for( p->parameter_iterator = pvl_head(p->parameters); p->parameter_iterator !=0; p->parameter_iterator = pvl_next(p->parameter_iterator)){ icalparameter *param = (icalparameter*)pvl_data(p->parameter_iterator); if(icalparameter_isa(param) == kind || kind == ICAL_ANY_PARAMETER){ return param; } } return 0; } icalparameter* -icalproperty_get_next_parameter (icalproperty* prop, icalparameter_kind kind) +icalproperty_get_next_parameter (icalproperty* p, icalparameter_kind kind) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; - - icalerror_check_arg_rz( (prop!=0),"prop"); + icalerror_check_arg_rz( (p!=0),"prop"); if (p->parameter_iterator == 0) { return 0; } for( p->parameter_iterator = pvl_next(p->parameter_iterator); p->parameter_iterator !=0; p->parameter_iterator = pvl_next(p->parameter_iterator)){ icalparameter *param = (icalparameter*)pvl_data(p->parameter_iterator); if(icalparameter_isa(param) == kind || kind == ICAL_ANY_PARAMETER){ return param; } } return 0; } void -icalproperty_set_value (icalproperty* prop, icalvalue* value) +icalproperty_set_value (icalproperty* p, icalvalue* value) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; - - icalerror_check_arg_rv((prop !=0),"prop"); + icalerror_check_arg_rv((p !=0),"prop"); icalerror_check_arg_rv((value !=0),"value"); if (p->value != 0){ icalvalue_set_parent(p->value,0); icalvalue_free(p->value); p->value = 0; } p->value = value; - icalvalue_set_parent(value,prop); + icalvalue_set_parent(value,p); } void icalproperty_set_value_from_string(icalproperty* prop,const char* str, const char* type) { icalvalue *oval,*nval; icalvalue_kind kind = ICAL_NO_VALUE; icalerror_check_arg_rv( (prop!=0),"prop"); icalerror_check_arg_rv( (str!=0),"str"); icalerror_check_arg_rv( (type!=0),"type"); if(strcmp(type,"NO")==0){ /* Get the type from the value the property already has, if it exists */ oval = icalproperty_get_value(prop); if(oval != 0){ /* Use the existing value kind */ kind = icalvalue_isa(oval); } else { /* Use the default kind for the property */ kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop)); } } else { /* Use the given kind string */ kind = icalvalue_string_to_kind(type); } if(kind == ICAL_NO_VALUE){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return; } nval = icalvalue_new_from_string(kind, str); if(nval == 0){ /* icalvalue_new_from_string sets errno */ assert(icalerrno != ICAL_NO_ERROR); return; } icalproperty_set_value(prop,nval); } icalvalue* -icalproperty_get_value (icalproperty* prop) +icalproperty_get_value(const icalproperty* prop) { - struct icalproperty_impl *p = (struct icalproperty_impl*)prop; - icalerror_check_arg_rz( (prop!=0),"prop"); - return p->value; + return prop->value; } -const char* icalproperty_get_value_as_string(icalproperty* prop) +const char* icalproperty_get_value_as_string(const icalproperty* prop) { icalvalue *value; - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - icalerror_check_arg_rz( (prop!=0),"prop"); - value = impl->value; + value = prop->value; return icalvalue_as_ical_string(value); } void icalproperty_set_x_name(icalproperty* prop, const char* name) { - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - icalerror_check_arg_rv( (name!=0),"name"); icalerror_check_arg_rv( (prop!=0),"prop"); - if (impl->x_name != 0) { - free(impl->x_name); + if (prop->x_name != 0) { + free(prop->x_name); } - impl->x_name = icalmemory_strdup(name); + prop->x_name = icalmemory_strdup(name); - if(impl->x_name == 0){ + if(prop->x_name == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); } } const char* icalproperty_get_x_name(icalproperty* prop){ - - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - icalerror_check_arg_rz( (prop!=0),"prop"); - return impl->x_name; + return prop->x_name; } -/* From Jonathan Yue <jonathan.yue@cp.net> */ -const char* icalproperty_get_name (icalproperty* prop) +const char* icalproperty_get_name(const icalproperty* prop) +{ +#ifndef NO_WARN_DEPRECATED + icalerror_warn("icalproperty_get_name() is DEPRECATED, please use icalproperty_get_property_name() instead."); +#endif + return icalproperty_get_property_name(prop); +} + +const char* icalproperty_get_property_name(const icalproperty* prop) { const char* property_name = 0; size_t buf_size = 256; char* buf = icalmemory_new_buffer(buf_size); char* buf_ptr = buf; - struct icalproperty_impl *impl = (struct icalproperty_impl*)prop; - icalerror_check_arg_rz( (prop!=0),"prop"); - if (impl->kind == ICAL_X_PROPERTY && impl->x_name != 0){ - property_name = impl->x_name; + if (prop->kind == ICAL_X_PROPERTY && prop->x_name != 0){ + property_name = prop->x_name; } else { - property_name = icalproperty_kind_to_string(impl->kind); + property_name = icalproperty_kind_to_string(prop->kind); } if (property_name == 0 ) { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } else { /* _append_string will automatically grow the buffer if property_name is longer than the initial buffer size */ icalmemory_append_string(&buf, &buf_ptr, &buf_size, property_name); } /* Add the buffer to the temporary buffer ring -- the caller will not have to free the memory. */ icalmemory_add_tmp_buffer(buf); return buf; } void icalproperty_set_parent(icalproperty* property, icalcomponent* component) { - struct icalproperty_impl *impl = (struct icalproperty_impl*)property; - icalerror_check_arg_rv( (property!=0),"property"); - impl->parent = component; + property->parent = component; } -icalcomponent* icalproperty_get_parent(icalproperty* property) +icalcomponent* icalproperty_get_parent(const icalproperty* property) { - struct icalproperty_impl *impl = (struct icalproperty_impl*)property; - icalerror_check_arg_rz( (property!=0),"property"); - return impl->parent; + return property->parent; } - - - - - - - -/* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icalproperty.h b/libical/src/libical/icalproperty.h index e39c6b5..472adb9 100644 --- a/libical/src/libical/icalproperty.h +++ b/libical/src/libical/icalproperty.h @@ -1,122 +1,134 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalproperty.h CREATOR: eric 20 March 1999 $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 icalparam.h ======================================================================*/ #ifndef ICALPROPERTY_H #define ICALPROPERTY_H #include <time.h> - -#ifdef _WIN32 -#include <stdio.h> /* for printf */ -#include <stdarg.h> /* for va_list, va_start, etc. */ -#endif +#include <stdarg.h> /* for va_... */ #include "icalderivedparameter.h" #include "icalvalue.h" #include "icalrecur.h" /* Actually in icalderivedproperty.h: - typedef void icalproperty; */ + typedef struct icalproperty_impl icalproperty; */ #include "icalderivedproperty.h" /* To get icalproperty_kind enumerations */ -// void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args); - icalproperty* icalproperty_new(icalproperty_kind kind); icalproperty* icalproperty_new_clone(icalproperty * prop); icalproperty* icalproperty_new_from_string(const char* str); const char* icalproperty_as_ical_string(icalproperty* prop); void icalproperty_free(icalproperty* prop); icalproperty_kind icalproperty_isa(icalproperty* property); int icalproperty_isa_property(void* property); +void icalproperty_add_parameters(struct icalproperty_impl *prop,va_list args); void icalproperty_add_parameter(icalproperty* prop,icalparameter* parameter); void icalproperty_set_parameter(icalproperty* prop,icalparameter* parameter); void icalproperty_set_parameter_from_string(icalproperty* prop, const char* name, const char* value); const char* icalproperty_get_parameter_as_string(icalproperty* prop, const char* name); void icalproperty_remove_parameter(icalproperty* prop, icalparameter_kind kind); -int icalproperty_count_parameters(icalproperty* prop); +void icalproperty_remove_parameter_by_kind(icalproperty* prop, + icalparameter_kind kind); + +void icalproperty_remove_parameter_by_name(icalproperty* prop, + const char *name); + +void icalproperty_remove_parameter_by_ref(icalproperty* prop, + icalparameter *param); + + + +int icalproperty_count_parameters(const icalproperty* prop); /* Iterate through the parameters */ icalparameter* icalproperty_get_first_parameter(icalproperty* prop, icalparameter_kind kind); icalparameter* icalproperty_get_next_parameter(icalproperty* prop, icalparameter_kind kind); /* Access the value of the property */ void icalproperty_set_value(icalproperty* prop, icalvalue* value); void icalproperty_set_value_from_string(icalproperty* prop,const char* value, const char* kind); -icalvalue* icalproperty_get_value(icalproperty* prop); -const char* icalproperty_get_value_as_string(icalproperty* prop); +icalvalue* icalproperty_get_value(const icalproperty* prop); +const char* icalproperty_get_value_as_string(const icalproperty* prop); /* Deal with X properties */ void icalproperty_set_x_name(icalproperty* prop, const char* name); const char* icalproperty_get_x_name(icalproperty* prop); -/* Return the name of the property -- the type name converted to a - string, or the value of _get_x_name if the type is and X property */ -const char* icalproperty_get_name (icalproperty* prop); +/** Return the name of the property -- the type name converted to a + * string, or the value of _get_x_name if the type is and X + * property + */ +const char* icalproperty_get_property_name (const icalproperty* prop); icalvalue_kind icalparameter_value_to_value_kind(icalparameter_value value); /* Convert kinds to string and get default value type */ icalvalue_kind icalproperty_kind_to_value_kind(icalproperty_kind kind); -icalvalue_kind icalproperty_value_kind_to_kind(icalvalue_kind kind); +icalproperty_kind icalproperty_value_kind_to_kind(icalvalue_kind kind); const char* icalproperty_kind_to_string(icalproperty_kind kind); icalproperty_kind icalproperty_string_to_kind(const char* string); +/** Check validity of a specific icalproperty_kind **/ +int icalproperty_kind_is_valid(const icalproperty_kind kind); + icalproperty_method icalproperty_string_to_method(const char* str); const char* icalproperty_method_to_string(icalproperty_method method); const char* icalproperty_enum_to_string(int e); int icalproperty_string_to_enum(const char* str); +int icalproperty_kind_and_string_to_enum(const int kind, const char* str); const char* icalproperty_status_to_string(icalproperty_status); icalproperty_status icalproperty_string_to_status(const char* string); int icalproperty_enum_belongs_to_property(icalproperty_kind kind, int e); #endif /*ICALPROPERTY_H*/ diff --git a/libical/src/libical/icalrecur.c b/libical/src/libical/icalrecur.c index 203ce70..d5a59c6 100644 --- a/libical/src/libical/icalrecur.c +++ b/libical/src/libical/icalrecur.c @@ -1,2315 +1,2392 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalrecur.c CREATOR: eric 16 May 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/ +*/ +/** + @file icalrecur.c + @brief Implementation of routines for dealing with recurring time How this code works: Processing starts when the caller generates a new recurrence iterator via icalrecur_iterator_new(). This routine copies the recurrence rule into the iterator and extracts things like start and end dates. Then, it checks if the rule is legal, using some logic from RFC2445 and some logic that probably should be in RFC2445. Then, icalrecur_iterator_new() re-writes some of the BY* arrays. This involves ( via a call to setup_defaults() ) : 1) For BY rule parts with no data ( ie BYSECOND was not specified ) copy the corresponding time part from DTSTART into the BY array. ( So impl->by_ptrs[BY_SECOND] will then have one element if is originally had none ) This only happens if the BY* rule part data would expand the number of occurrences in the occurrence set. This lets the code ignore DTSTART later on and still use it to get the time parts that were not specified in any other way. 2) For the by rule part that are not the same interval as the frequency -- for HOURLY anything but BYHOUR, for instance -- copy the first data element from the rule part into the first occurrence. For example, for "INTERVAL=MONTHLY and BYHOUR=10,30", initialize the first time to be returned to have an hour of 10. Finally, for INTERVAL=YEARLY, the routine expands the rule to get all of the days specified in the rule. The code will do this for each new year, and this is the first expansion. This is a special case for the yearly interval; no other frequency gets expanded this way. The yearly interval is the most complex, so some special processing is required. After creating a new iterator, the caller will make successive calls to icalrecur_iterator_next() to get the next time specified by the rule. The main part of this routine is a switch on the frequency of the rule. Each different frequency is handled by a different routine. For example, next_hour handles the case of INTERVAL=HOURLY, and it is called by other routines to get the next hour. First, the routine tries to get the next minute part of a time with a call to next_minute(). If next_minute() returns 1, it has reached the end of its data, usually the last element of the BYMINUTE array. Then, if there is data in the BYHOUR array, the routine changes the hour to the next one in the array. If INTERVAL=HOURLY, the routine advances the hour by the interval. If the routine used the last hour in the BYHOUR array, and the INTERVAL=HOURLY, then the routine calls increment_monthday() to set the next month day. The increment_* routines may call higher routine to increment the month or year also. The code for INTERVAL=DAILY is handled by next_day(). First, the routine tries to get the next hour part of a time with a call to next_hour. If next_hour() returns 1, it has reached the end of its data, usually the last element of the BYHOUR array. This means that next_day() should increment the time to the next day. If FREQUENCY==DAILY, the routine increments the day by the interval; otherwise, it increments the day by 1. Next_day() differs from next_hour because it does not use the BYDAY array to select an appropriate day. Instead, it returns every day ( incrementing by 1 if the frequency is not DAILY with INTERVAL!=1) Any days that are not specified in an non-empty BYDAY array are filtered out later. Generally, the flow of these routine is for a next_* call a next_* routine of a lower interval ( next_day calls next_hour) and then to possibly call an increment_* routine of an equal or higher interval. ( next_day calls increment_monthday() ) When the call to the original next_* routine returns, icalrecur_iterator_next() will check the returned data against other BYrule parts to determine if is should be excluded by calling check_contracting_rules. Generally, a contracting rule is any with a larger time span than the interval. For instance, if INTERVAL=DAILY, BYMONTH is a contracting rule part. Check_contracting_rules() uses icalrecur_check_rulepart() to do its work. icalrecur_check_rulepart() uses expand_map[] to determine if a rule is contracting, and if it is, and if the BY rule part has some data, then the routine checks if the value of a component of the time is part of the byrule part. For instance, for "INTERVAL=DAILY; BYMONTH=6,10", icalrecur_check_rulepart() would check that the time value given to it has a month of either 6 or 10. Finally, icalrecur_iterator_next() does a few other checks on the time value, and if it passes, it returns the time. A note about the end_of_data flag. The flag indicates that the routine is at the end of its data -- the last BY rule if the routine is using by rules, or the last day of the week/month/year/etc if not. This flag is usually set early in a next_* routine and returned in the end. The way it is used allows the next_* routine to set the last time back to the first element in a BYxx rule, and then signal to the higer level routine to increment the next higher level. For instance. WITH FREQ=MONTHLY;BYDAY=TU,FR, After next_weekday_by_month runs though both TU and FR, it sets the week day back to TU and sets end_of_data to 1x. This signals next_month to increment the month. ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + #include "icalrecur.h" -#ifdef ICAL_NO_LIBICAL -#define icalerror_set_errno(x) -#define icalerror_check_arg_rv(x,y) -#else #include "icalerror.h" #include "icalmemory.h" -#endif #include <stdlib.h> /* for malloc */ #include <errno.h> /* for errno */ #include <string.h> /* for strdup and strchr*/ #include <assert.h> #include <stddef.h> /* For offsetof() macro */ #include "pvl.h" +/** This is the last year we will go up to, since 32-bit time_t values + only go up to the start of 2038. */ +#define MAX_TIME_T_YEAR 2037 + #define TEMP_MAX 1024 #define BYDAYIDX impl->by_indices[BY_DAY] #define BYDAYPTR impl->by_ptrs[BY_DAY] #define BYMONIDX impl->by_indices[BY_MONTH] #define BYMONPTR impl->by_ptrs[BY_MONTH] #define BYMDIDX impl->by_indices[BY_MONTH_DAY] #define BYMDPTR impl->by_ptrs[BY_MONTH_DAY] #define BYWEEKIDX impl->by_indices[BY_WEEK_NO] #define BYWEEKPTR impl->by_ptrs[BY_WEEK_NO] const char* icalrecur_freq_to_string(icalrecurrencetype_frequency kind); icalrecurrencetype_frequency icalrecur_string_to_freq(const char* str); const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind); icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str); - /*********************** Rule parsing routines ************************/ struct icalrecur_parser { const char* rule; char* copy; char* this_clause; char* next_clause; struct icalrecurrencetype rt; }; const char* icalrecur_first_clause(struct icalrecur_parser *parser) { char *idx; parser->this_clause = parser->copy; idx = strchr(parser->this_clause,';'); if (idx == 0){ parser->next_clause = 0; return 0; } *idx = 0; idx++; parser->next_clause = idx; return parser->this_clause; } const char* icalrecur_next_clause(struct icalrecur_parser *parser) { char* idx; parser->this_clause = parser->next_clause; if(parser->this_clause == 0){ return 0; } idx = strchr(parser->this_clause,';'); if (idx == 0){ parser->next_clause = 0; } else { *idx = 0; idx++; parser->next_clause = idx; } return parser->this_clause; } void icalrecur_clause_name_and_value(struct icalrecur_parser *parser, char** name, char** value) { char *idx; *name = parser->this_clause; idx = strchr(parser->this_clause,'='); if (idx == 0){ *name = 0; *value = 0; return; } *idx = 0; idx++; *value = idx; } void icalrecur_add_byrules(struct icalrecur_parser *parser, short *array, int size, char* vals) { char *t, *n; int i=0; int sign = 1; - short v; + int v; n = vals; while(n != 0){ if(i == size){ return; } t = n; n = strchr(t,','); if(n != 0){ *n = 0; n++; } /* Get optional sign. HACK. sign is not allowed for all BYxxx rule parts */ if( *t == '-'){ sign = -1; t++; } else if (*t == '+'){ sign = 1; t++; + } else { + sign = 1; } v = atoi(t) * sign ; - array[i++] = v; + array[i++] = (short)v; array[i] = ICAL_RECURRENCE_ARRAY_MAX; } } void icalrecur_add_bydayrules(struct icalrecur_parser *parser, const char* vals) { char *t, *n; int i=0; int sign = 1; int weekno = 0; icalrecurrencetype_weekday wd; short *array = parser->rt.by_day; char* end; char* vals_copy; vals_copy = icalmemory_strdup(vals); end = (char*)vals_copy+strlen(vals_copy); n = vals_copy; while(n != 0){ t = n; n = strchr(t,','); if(n != 0){ *n = 0; n++; } /* Get optional sign. */ if( *t == '-'){ sign = -1; t++; } else if (*t == '+'){ sign = 1; t++; } else { sign = 1; } - weekno = 0; /* Get Optional weekno */ - if( sscanf(t,"%d",&weekno) != 0){ - if (n != 0){ - int weeknolen = (n-t)-3; /* 3 -> one for \0, 2 for day name */ - /* could use abs(log10(weekno))+1, but that needs libm */ - t += weeknolen; - } else { - t = end -2; - } - } + weekno = strtol(t,&t,10); + + /* Outlook/Exchange generate "BYDAY=MO, FR" and "BYDAY=2 TH". + * Cope with that. + */ + if (*t == ' ') + t++; wd = icalrecur_string_to_weekday(t); - array[i++] = sign* ((int)wd + 8*weekno); + array[i++] = (short)(sign* (wd + 8*weekno)); array[i] = ICAL_RECURRENCE_ARRAY_MAX; } free(vals_copy); } struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) { struct icalrecur_parser parser; memset(&parser,0,sizeof(parser)); icalrecurrencetype_clear(&parser.rt); icalerror_check_arg_re(str!=0,"str",parser.rt); /* Set up the parser struct */ parser.rule = str; parser.copy = icalmemory_strdup(parser.rule); parser.this_clause = parser.copy; if(parser.copy == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return parser.rt; } /* Loop through all of the clauses */ for(icalrecur_first_clause(&parser); parser.this_clause != 0; icalrecur_next_clause(&parser)) { char *name, *value; icalrecur_clause_name_and_value(&parser,&name,&value); if(name == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); + free(parser.copy); return parser.rt; } if (strcmp(name,"FREQ") == 0){ parser.rt.freq = icalrecur_string_to_freq(value); } else if (strcmp(name,"COUNT") == 0){ parser.rt.count = atoi(value); } else if (strcmp(name,"UNTIL") == 0){ parser.rt.until = icaltime_from_string(value); } else if (strcmp(name,"INTERVAL") == 0){ - parser.rt.interval = atoi(value); + parser.rt.interval = (short)atoi(value); } else if (strcmp(name,"WKST") == 0){ parser.rt.week_start = icalrecur_string_to_weekday(value); } else if (strcmp(name,"BYSECOND") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_second, ICAL_BY_SECOND_SIZE,value); } else if (strcmp(name,"BYMINUTE") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_minute, ICAL_BY_MINUTE_SIZE,value); } else if (strcmp(name,"BYHOUR") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_hour, ICAL_BY_HOUR_SIZE,value); } else if (strcmp(name,"BYDAY") == 0){ icalrecur_add_bydayrules(&parser,value); } else if (strcmp(name,"BYMONTHDAY") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_month_day, ICAL_BY_MONTHDAY_SIZE,value); } else if (strcmp(name,"BYYEARDAY") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_year_day, ICAL_BY_YEARDAY_SIZE,value); } else if (strcmp(name,"BYWEEKNO") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_week_no, ICAL_BY_WEEKNO_SIZE,value); } else if (strcmp(name,"BYMONTH") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_month, ICAL_BY_MONTH_SIZE,value); } else if (strcmp(name,"BYSETPOS") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_set_pos, ICAL_BY_SETPOS_SIZE,value); } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); + free(parser.copy); return parser.rt; } } free(parser.copy); return parser.rt; } -#ifndef ICAL_NO_LIBICAL - -struct { char* str;size_t offset; short limit; } recurmap[] = +static struct { char* str;size_t offset; int limit; } recurmap[] = { {";BYSECOND=",offsetof(struct icalrecurrencetype,by_second),60}, {";BYMINUTE=",offsetof(struct icalrecurrencetype,by_minute),60}, {";BYHOUR=",offsetof(struct icalrecurrencetype,by_hour),24}, {";BYDAY=",offsetof(struct icalrecurrencetype,by_day),7}, {";BYMONTHDAY=",offsetof(struct icalrecurrencetype,by_month_day),31}, {";BYYEARDAY=",offsetof(struct icalrecurrencetype,by_year_day),366}, {";BYWEEKNO=",offsetof(struct icalrecurrencetype,by_week_no),52}, {";BYMONTH=",offsetof(struct icalrecurrencetype,by_month),12}, {";BYSETPOS=",offsetof(struct icalrecurrencetype,by_set_pos),366}, {0,0,0}, }; /* A private routine in icalvalue.c */ +void print_date_to_string(char* str, struct icaltimetype *data); void print_datetime_to_string(char* str, struct icaltimetype *data); char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur) { char* str; char *str_p; size_t buf_sz = 200; char temp[20]; int i,j; if(recur->freq == ICAL_NO_RECURRENCE){ return 0; } str = (char*)icalmemory_tmp_buffer(buf_sz); str_p = str; icalmemory_append_string(&str,&str_p,&buf_sz,"FREQ="); icalmemory_append_string(&str,&str_p,&buf_sz, icalrecur_freq_to_string(recur->freq)); if(recur->until.year != 0){ temp[0] = 0; - print_datetime_to_string(temp,&(recur->until)); + if (recur->until.is_date) + print_date_to_string(temp,&(recur->until)); + else + print_datetime_to_string(temp,&(recur->until)); icalmemory_append_string(&str,&str_p,&buf_sz,";UNTIL="); icalmemory_append_string(&str,&str_p,&buf_sz, temp); } if(recur->count != 0){ sprintf(temp,"%d",recur->count); icalmemory_append_string(&str,&str_p,&buf_sz,";COUNT="); icalmemory_append_string(&str,&str_p,&buf_sz, temp); } if(recur->interval != 0){ sprintf(temp,"%d",recur->interval); icalmemory_append_string(&str,&str_p,&buf_sz,";INTERVAL="); icalmemory_append_string(&str,&str_p,&buf_sz, temp); } for(j =0; recurmap[j].str != 0; j++){ short* array = (short*)(recurmap[j].offset+ (size_t)recur); - short limit = recurmap[j].limit; + int limit = recurmap[j].limit; /* Skip unused arrays */ if( array[0] != ICAL_RECURRENCE_ARRAY_MAX ) { icalmemory_append_string(&str,&str_p,&buf_sz,recurmap[j].str); for(i=0; i< limit && array[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ if (j == 3) { /* BYDAY */ - short dow = icalrecurrencetype_day_day_of_week(array[i]); - const char *daystr = icalrecur_weekday_to_string(dow); - short pos; + const char *daystr = icalrecur_weekday_to_string( + icalrecurrencetype_day_day_of_week(array[i])); + int pos; pos = icalrecurrencetype_day_position(array[i]); if (pos == 0) icalmemory_append_string(&str,&str_p,&buf_sz,daystr); else { sprintf(temp,"%d%s",pos,daystr); icalmemory_append_string(&str,&str_p,&buf_sz,temp); } } else { sprintf(temp,"%d",array[i]); icalmemory_append_string(&str,&str_p,&buf_sz, temp); } if( (i+1)<limit &&array[i+1] != ICAL_RECURRENCE_ARRAY_MAX){ icalmemory_append_char(&str,&str_p,&buf_sz,','); } } } } return str; } -#endif - /************************* occurrence iteration routiens ******************/ enum byrule { NO_CONTRACTION = -1, BY_SECOND = 0, BY_MINUTE = 1, BY_HOUR = 2, BY_DAY = 3, BY_MONTH_DAY = 4, BY_YEAR_DAY = 5, BY_WEEK_NO = 6, BY_MONTH = 7, BY_SET_POS }; struct icalrecur_iterator_impl { struct icaltimetype dtstart; /* Hack. Make into time_t */ struct icaltimetype last; /* last time return from _iterator_next*/ int occurrence_no; /* number of step made on t iterator */ struct icalrecurrencetype rule; short days[366]; short days_index; enum byrule byrule; short by_indices[9]; - short orig_data[9]; /* 1 if there was data in the byrule */ + short orig_data[9]; /**< 1 if there was data in the byrule */ - short *by_ptrs[9]; /* Pointers into the by_* array elements of the rule */ + short *by_ptrs[9]; /**< Pointers into the by_* array elements of the rule */ }; +static void increment_year(icalrecur_iterator* impl, int inc); + int icalrecur_iterator_sizeof_byarray(short* byarray) { int array_itr; for(array_itr = 0; byarray[array_itr] != ICAL_RECURRENCE_ARRAY_MAX; array_itr++){ } return array_itr; } enum expand_table { UNKNOWN = 0, CONTRACT = 1, EXPAND =2, ILLEGAL=3 }; -/* The split map indicates, for a particular interval, wether a BY_* - rule part expands the number of instances in the occcurrence set or - contracts it. 1=> contract, 2=>expand, and 3 means the pairing is - not allowed. */ +/** + * The split map indicates, for a particular interval, wether a BY_* + * rule part expands the number of instances in the occcurrence set or + * contracts it. 1=> contract, 2=>expand, and 3 means the pairing is + * not allowed. + */ + struct expand_split_map_struct { icalrecurrencetype_frequency frequency; /* Elements of the 'map' array correspond to the BYxxx rules: Second,Minute,Hour,Day,Month Day,Year Day,Week No,Month*/ short map[8]; }; -struct expand_split_map_struct expand_map[] = +static struct expand_split_map_struct expand_map[] = { {ICAL_SECONDLY_RECURRENCE,{1,1,1,1,1,1,1,1}}, {ICAL_MINUTELY_RECURRENCE,{2,1,1,1,1,1,1,1}}, {ICAL_HOURLY_RECURRENCE, {2,2,1,1,1,1,1,1}}, {ICAL_DAILY_RECURRENCE, {2,2,2,1,1,1,1,1}}, {ICAL_WEEKLY_RECURRENCE, {2,2,2,2,3,3,1,1}}, {ICAL_MONTHLY_RECURRENCE, {2,2,2,2,2,3,3,1}}, {ICAL_YEARLY_RECURRENCE, {2,2,2,2,2,2,2,2}}, {ICAL_NO_RECURRENCE, {0,0,0,0,0,0,0,0}} }; -/* Check that the rule has only the two given interday byrule parts. */ -int icalrecur_two_byrule(struct icalrecur_iterator_impl* impl, +/** Check that the rule has only the two given interday byrule parts. */ +static +int icalrecur_two_byrule(icalrecur_iterator* impl, enum byrule one,enum byrule two) { short test_array[9]; enum byrule itr; int passes = 0; - memset(test_array,0,9); + memset(test_array,0,sizeof(test_array)); test_array[one] = 1; test_array[two] = 1; for(itr = BY_DAY; itr != BY_SET_POS; itr++){ if( (test_array[itr] == 0 && impl->by_ptrs[itr][0] != ICAL_RECURRENCE_ARRAY_MAX ) || (test_array[itr] == 1 && impl->by_ptrs[itr][0] == ICAL_RECURRENCE_ARRAY_MAX ) ) { /* test failed */ passes = 0; } } return passes; } -/* Check that the rule has only the one given interdat byrule parts. */ -int icalrecur_one_byrule(struct icalrecur_iterator_impl* impl,enum byrule one) +/** Check that the rule has only the one given interdat byrule parts. */ +static int icalrecur_one_byrule(icalrecur_iterator* impl,enum byrule one) { int passes = 1; enum byrule itr; for(itr = BY_DAY; itr != BY_SET_POS; itr++){ if ((itr==one && impl->by_ptrs[itr][0] == ICAL_RECURRENCE_ARRAY_MAX) || (itr!=one && impl->by_ptrs[itr][0] != ICAL_RECURRENCE_ARRAY_MAX)) { passes = 0; } } return passes; } -int count_byrules(struct icalrecur_iterator_impl* impl) +static int count_byrules(icalrecur_iterator* impl) { int count = 0; enum byrule itr; for(itr = BY_DAY; itr <= BY_SET_POS; itr++){ if(impl->by_ptrs[itr][0] != ICAL_RECURRENCE_ARRAY_MAX){ count++; } } return count; } -void setup_defaults(struct icalrecur_iterator_impl* impl, +static void setup_defaults(icalrecur_iterator* impl, enum byrule byrule, icalrecurrencetype_frequency req, - short deftime, int *timepart) + int deftime, int *timepart) { icalrecurrencetype_frequency freq; freq = impl->rule.freq; /* Re-write the BY rule arrays with data from the DTSTART time so we don't have to explicitly deal with DTSTART */ if(impl->by_ptrs[byrule][0] == ICAL_RECURRENCE_ARRAY_MAX && expand_map[freq].map[byrule] != CONTRACT){ - impl->by_ptrs[byrule][0] = deftime; + impl->by_ptrs[byrule][0] = (short)deftime; } /* Initialize the first occurence */ if( freq != req && expand_map[freq].map[byrule] != CONTRACT){ *timepart = impl->by_ptrs[byrule][0]; } } -int has_by_data(struct icalrecur_iterator_impl* impl, enum byrule byrule){ +static int has_by_data(icalrecur_iterator* impl, enum byrule byrule){ return (impl->orig_data[byrule] == 1); } -int expand_year_days(struct icalrecur_iterator_impl* impl,short year); +static int expand_year_days(icalrecur_iterator* impl, int year); icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart) { - struct icalrecur_iterator_impl* impl; + icalrecur_iterator* impl; icalrecurrencetype_frequency freq; - short days_in_month; - - if ( ( impl = (struct icalrecur_iterator_impl *) - malloc(sizeof(struct icalrecur_iterator_impl))) == 0) { + if ( ( impl = (icalrecur_iterator*) + malloc(sizeof(icalrecur_iterator))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } - memset(impl,0,sizeof(struct icalrecur_iterator_impl)); + memset(impl,0,sizeof(icalrecur_iterator)); impl->rule = rule; impl->last = dtstart; impl->dtstart = dtstart; impl->days_index =0; impl->occurrence_no = 0; freq = impl->rule.freq; /* Set up convienience pointers to make the code simpler. Allows us to iterate through all of the BY* arrays in the rule. */ impl->by_ptrs[BY_MONTH]=impl->rule.by_month; impl->by_ptrs[BY_WEEK_NO]=impl->rule.by_week_no; impl->by_ptrs[BY_YEAR_DAY]=impl->rule.by_year_day; impl->by_ptrs[BY_MONTH_DAY]=impl->rule.by_month_day; impl->by_ptrs[BY_DAY]=impl->rule.by_day; impl->by_ptrs[BY_HOUR]=impl->rule.by_hour; impl->by_ptrs[BY_MINUTE]=impl->rule.by_minute; impl->by_ptrs[BY_SECOND]=impl->rule.by_second; impl->by_ptrs[BY_SET_POS]=impl->rule.by_set_pos; - memset(impl->orig_data,0,9); + memset(impl->orig_data,0,9*sizeof(short)); /* Note which by rules had data in them when the iterator was created. We can't use the actuall by_x arrays, because the empty ones will be given default values later in this routine. The orig_data array will be used later in has_by_data */ impl->orig_data[BY_MONTH] - = (impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_month[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_WEEK_NO] - =(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_week_no[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_YEAR_DAY] - =(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_year_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_MONTH_DAY] - =(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + =(short)(impl->rule.by_month_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_DAY] - = (impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_day[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_HOUR] - = (impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_hour[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_MINUTE] - = (impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_minute[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_SECOND] - = (impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_second[0]!=ICAL_RECURRENCE_ARRAY_MAX); impl->orig_data[BY_SET_POS] - = (impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX); + = (short)(impl->rule.by_set_pos[0]!=ICAL_RECURRENCE_ARRAY_MAX); /* Check if the recurrence rule is legal */ /* If the BYYEARDAY appears, no other date rule part may appear. */ if(icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_MONTH) || icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_WEEK_NO) || icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_MONTH_DAY) || icalrecur_two_byrule(impl,BY_YEAR_DAY,BY_DAY) ){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* BYWEEKNO and BYMONTH rule parts may not both appear.*/ if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH)){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* BYWEEKNO and BYMONTHDAY rule parts may not both appear.*/ if(icalrecur_two_byrule(impl,BY_WEEK_NO,BY_MONTH_DAY)){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /*For MONTHLY recurrences (FREQ=MONTHLY) neither BYYEARDAY nor BYWEEKNO may appear. */ if(freq == ICAL_MONTHLY_RECURRENCE && icalrecur_one_byrule(impl,BY_WEEK_NO)){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /*For WEEKLY recurrences (FREQ=WEEKLY) neither BYMONTHDAY nor BYYEARDAY may appear. */ if(freq == ICAL_WEEKLY_RECURRENCE && icalrecur_one_byrule(impl,BY_MONTH_DAY )) { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* BYYEARDAY may only appear in YEARLY rules */ if(freq != ICAL_YEARLY_RECURRENCE && icalrecur_one_byrule(impl,BY_YEAR_DAY )) { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } /* Rewrite some of the rules and set up defaults to make later processing easier. Primarily, t involves copying an element from the start time into the coresponding BY_* array when the BY_* array is empty */ - setup_defaults(impl,BY_SECOND,ICAL_SECONDLY_RECURRENCE,impl->dtstart.second, + setup_defaults(impl,BY_SECOND,ICAL_SECONDLY_RECURRENCE, + impl->dtstart.second, &(impl->last.second)); - setup_defaults(impl,BY_MINUTE,ICAL_MINUTELY_RECURRENCE,impl->dtstart.minute, + setup_defaults(impl,BY_MINUTE,ICAL_MINUTELY_RECURRENCE, + impl->dtstart.minute, &(impl->last.minute)); - setup_defaults(impl,BY_HOUR,ICAL_HOURLY_RECURRENCE,impl->dtstart.hour, + setup_defaults(impl,BY_HOUR,ICAL_HOURLY_RECURRENCE, + impl->dtstart.hour, &(impl->last.hour)); - setup_defaults(impl,BY_MONTH_DAY,ICAL_DAILY_RECURRENCE,impl->dtstart.day, + setup_defaults(impl,BY_MONTH_DAY,ICAL_DAILY_RECURRENCE, + impl->dtstart.day, &(impl->last.day)); - setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE,impl->dtstart.month, + setup_defaults(impl,BY_MONTH,ICAL_MONTHLY_RECURRENCE, + impl->dtstart.month, &(impl->last.month)); if(impl->rule.freq == ICAL_WEEKLY_RECURRENCE ){ if(impl->by_ptrs[BY_DAY][0] == ICAL_RECURRENCE_ARRAY_MAX){ /* Weekly recurrences with no BY_DAY data should occur on the same day of the week as the start time . */ - impl->by_ptrs[BY_DAY][0] = icaltime_day_of_week(impl->dtstart); + impl->by_ptrs[BY_DAY][0] = (short)icaltime_day_of_week(impl->dtstart); } else { /* If there is BY_DAY data, then we need to move the initial time to the start of the BY_DAY data. That is if the start time is on a Wednesday, and the rule has BYDAY=MO,WE,FR, move the initial time back to monday. Otherwise, jumping to the next week ( jumping 7 days ahead ) will skip over some occurrences in the second week. */ /* This is probably a HACK. There should be some more general way to solve this problem */ - short dow = impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last); + short dow = (short)(impl->by_ptrs[BY_DAY][0]-icaltime_day_of_week(impl->last)); if(dow < 0) { /* initial time is after first day of BY_DAY data */ impl->last.day += dow; impl->last = icaltime_normalize(impl->last); } } } - /* For YEARLY rule, begin by setting up the year days array */ + /* For YEARLY rule, begin by setting up the year days array . The + YEARLY rules work by expanding one year at a time. */ if(impl->rule.freq == ICAL_YEARLY_RECURRENCE){ - expand_year_days(impl,impl->last.year); + struct icaltimetype next; + + for (;;) { + expand_year_days(impl, impl->last.year); + if (impl->days[0] != ICAL_RECURRENCE_ARRAY_MAX) + break; /* break when no days are expanded */ + increment_year(impl,impl->rule.interval); + } + + /* Copy the first day into last. */ + next = icaltime_from_day_of_year(impl->days[0], impl->last.year); + + impl->last.day = next.day; + impl->last.month = next.month; } /* If this is a monthly interval with by day data, then we need to set the last value to the appropriate day of the month */ if(impl->rule.freq == ICAL_MONTHLY_RECURRENCE && has_by_data(impl,BY_DAY)) { - short dow = icalrecurrencetype_day_day_of_week( + int dow = icalrecurrencetype_day_day_of_week( impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); - short pos = icalrecurrencetype_day_position( + int pos = icalrecurrencetype_day_position( impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]); - short poscount = 0; - days_in_month = + int poscount = 0; + int days_in_month = icaltime_days_in_month(impl->last.month, impl->last.year); if(pos >= 0){ /* Count up from the first day pf the month to find the pos'th weekday of dow ( like the second monday. ) */ for(impl->last.day = 1; impl->last.day <= days_in_month; impl->last.day++){ if(icaltime_day_of_week(impl->last) == dow){ if(++poscount == pos || pos == 0){ break; } } } } else { /* Count down from the last day pf the month to find the pos'th weekday of dow ( like the second to last monday. ) */ pos = -pos; for(impl->last.day = days_in_month; impl->last.day != 0; impl->last.day--){ if(icaltime_day_of_week(impl->last) == dow){ if(++poscount == pos ){ break; } } } } if(impl->last.day > days_in_month || impl->last.day == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } } return impl; } void icalrecur_iterator_free(icalrecur_iterator* i) { + icalerror_check_arg_rv((i!=0),"impl"); - struct icalrecur_iterator_impl* impl = - (struct icalrecur_iterator_impl*)i; - - icalerror_check_arg_rv((impl!=0),"impl"); - - free(impl); + free(i); } - -void increment_year(struct icalrecur_iterator_impl* impl, int inc) +static void increment_year(icalrecur_iterator* impl, int inc) { impl->last.year+=inc; } -/* Increment month is different that the other incement_* routines -- +/** Increment month is different that the other incement_* routines -- it figures out the interval for itself, and uses BYMONTH data if available. */ -void increment_month(struct icalrecur_iterator_impl* impl) +static void increment_month(icalrecur_iterator* impl) { int years; if(has_by_data(impl,BY_MONTH) ){ /* Ignore the frequency and use the byrule data */ impl->by_indices[BY_MONTH]++; if (impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_MONTH] = 0; increment_year(impl,1); } impl->last.month = impl->by_ptrs[BY_MONTH][impl->by_indices[BY_MONTH]]; } else { int inc; if(impl->rule.freq == ICAL_MONTHLY_RECURRENCE){ inc = impl->rule.interval; } else { inc = 1; } impl->last.month+=inc; /* Months are offset by one */ impl->last.month--; years = impl->last.month / 12; impl->last.month = impl->last.month % 12; impl->last.month++; if (years != 0){ increment_year(impl,years); } } } -void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) +static void increment_monthday(icalrecur_iterator* impl, int inc) { int i; for(i=0; i<inc; i++){ - short days_in_month = - icaltime_days_in_month(impl->last.month,impl->last.year); + int days_in_month = + icaltime_days_in_month(impl->last.month, impl->last.year); impl->last.day++; if (impl->last.day > days_in_month){ impl->last.day = impl->last.day-days_in_month; increment_month(impl); } } } -void increment_hour(struct icalrecur_iterator_impl* impl, int inc) +static void increment_hour(icalrecur_iterator* impl, int inc) { - short days; + int days; impl->last.hour+=inc; days = impl->last.hour / 24; impl->last.hour = impl->last.hour % 24; if (impl->days != 0){ increment_monthday(impl,days); } } -void increment_minute(struct icalrecur_iterator_impl* impl, int inc) +static void increment_minute(icalrecur_iterator* impl, int inc) { - short hours; + int hours; impl->last.minute+=inc; hours = impl->last.minute / 60; impl->last.minute = impl->last.minute % 60; if (hours != 0){ increment_hour(impl,hours); } } -void increment_second(struct icalrecur_iterator_impl* impl, int inc) +static void increment_second(icalrecur_iterator* impl, int inc) { - short minutes; + int minutes; impl->last.second+=inc; minutes = impl->last.second / 60; impl->last.second = impl->last.second % 60; if (minutes != 0) { increment_minute(impl, minutes); } } #if 0 #include "ical.h" void test_increment() { - struct icalrecur_iterator_impl impl; + icalrecur_iterator impl; impl.last = icaltime_from_string("20000101T000000Z"); printf("Orig: %s\n",icaltime_as_ctime(impl.last)); increment_second(&impl,5); printf("+ 5 sec : %s\n",icaltime_as_ctime(impl.last)); increment_second(&impl,355); printf("+ 355 sec : %s\n",icaltime_as_ctime(impl.last)); increment_minute(&impl,5); printf("+ 5 min : %s\n",icaltime_as_ctime(impl.last)); increment_minute(&impl,360); printf("+ 360 min : %s\n",icaltime_as_ctime(impl.last)); increment_hour(&impl,5); printf("+ 5 hours : %s\n",icaltime_as_ctime(impl.last)); increment_hour(&impl,43); printf("+ 43 hours : %s\n",icaltime_as_ctime(impl.last)); increment_monthday(&impl,3); printf("+ 3 days : %s\n",icaltime_as_ctime(impl.last)); increment_monthday(&impl,600); printf("+ 600 days : %s\n",icaltime_as_ctime(impl.last)); } #endif -short next_second(struct icalrecur_iterator_impl* impl) +static int next_second(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_SECOND][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_SECONDLY_RECURRENCE); + int has_by_second = (impl->by_ptrs[BY_SECOND][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_SECONDLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_second || this_frequency); - if( has_by_data ){ + if( has_by_second ){ /* Ignore the frequency and use the byrule data */ impl->by_indices[BY_SECOND]++; if (impl->by_ptrs[BY_SECOND][impl->by_indices[BY_SECOND]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_SECOND] = 0; end_of_data = 1; } impl->last.second = impl->by_ptrs[BY_SECOND][impl->by_indices[BY_SECOND]]; - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_second && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_second(impl, impl->rule.interval); } /* If we have gone through all of the seconds on the BY list, then we need to move to the next minute */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_second && end_of_data && this_frequency ){ increment_minute(impl,1); } return end_of_data; } -int next_minute(struct icalrecur_iterator_impl* impl) +static int next_minute(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_MINUTE][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_MINUTELY_RECURRENCE); + int has_by_minute = (impl->by_ptrs[BY_MINUTE][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_MINUTELY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_minute || this_frequency); if (next_second(impl) == 0){ return 0; } - if( has_by_data ){ + if( has_by_minute ){ /* Ignore the frequency and use the byrule data */ impl->by_indices[BY_MINUTE]++; if (impl->by_ptrs[BY_MINUTE][impl->by_indices[BY_MINUTE]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_MINUTE] = 0; end_of_data = 1; } impl->last.minute = impl->by_ptrs[BY_MINUTE][impl->by_indices[BY_MINUTE]]; - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_minute && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_minute(impl,impl->rule.interval); } /* If we have gone through all of the minutes on the BY list, then we need to move to the next hour */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_minute && end_of_data && this_frequency ){ increment_hour(impl,1); } return end_of_data; } -int next_hour(struct icalrecur_iterator_impl* impl) +static int next_hour(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_HOUR][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_HOURLY_RECURRENCE); + int has_by_hour = (impl->by_ptrs[BY_HOUR][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_HOURLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data || this_frequency); + assert(has_by_hour || this_frequency); if (next_minute(impl) == 0){ return 0; } - if( has_by_data ){ + if( has_by_hour ){ /* Ignore the frequency and use the byrule data */ impl->by_indices[BY_HOUR]++; if (impl->by_ptrs[BY_HOUR][impl->by_indices[BY_HOUR]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_HOUR] = 0; end_of_data = 1; } impl->last.hour = impl->by_ptrs[BY_HOUR][impl->by_indices[BY_HOUR]]; - } else if( !has_by_data && this_frequency ){ + } else if( !has_by_hour && this_frequency ){ /* Compute the next value from the last time and the frequency interval*/ increment_hour(impl,impl->rule.interval); } /* If we have gone through all of the hours on the BY list, then we need to move to the next day */ - if(has_by_data && end_of_data && this_frequency ){ + if(has_by_hour && end_of_data && this_frequency ){ increment_monthday(impl,1); } return end_of_data; } -int next_day(struct icalrecur_iterator_impl* impl) +static int next_day(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_DAILY_RECURRENCE); + int has_by_day = (impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int this_frequency = (impl->rule.freq == ICAL_DAILY_RECURRENCE); - assert(has_by_data || this_frequency); + assert(has_by_day || this_frequency); if (next_hour(impl) == 0){ return 0; } /* Always increment through the interval, since this routine is not called by any other next_* routine, and the days that are excluded will be taken care of by restriction filtering */ if(this_frequency){ increment_monthday(impl,impl->rule.interval); } else { increment_monthday(impl,1); } return 0; } -int next_yearday(struct icalrecur_iterator_impl* impl) +static int next_yearday(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_YEAR_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); + int has_by_yearday = (impl->by_ptrs[BY_YEAR_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short end_of_data = 0; + int end_of_data = 0; - assert(has_by_data ); + assert(has_by_yearday ); if (next_hour(impl) == 0){ return 0; } impl->by_indices[BY_YEAR_DAY]++; if (impl->by_ptrs[BY_YEAR_DAY][impl->by_indices[BY_YEAR_DAY]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_YEAR_DAY] = 0; end_of_data = 1; } impl->last.day = impl->by_ptrs[BY_YEAR_DAY][impl->by_indices[BY_YEAR_DAY]]; - if(has_by_data && end_of_data){ + if(has_by_yearday && end_of_data){ increment_year(impl,1); } return end_of_data; } -/* This routine is only called by next_week. It is certain that BY_DAY -has data */ - -int next_weekday_by_week(struct icalrecur_iterator_impl* impl) -{ - - short end_of_data = 0; - short start_of_week, dow; - struct icaltimetype next; - - if (next_hour(impl) == 0){ - return 0; - } - - assert( impl->by_ptrs[BY_DAY][0]!=ICAL_RECURRENCE_ARRAY_MAX); - - while(1) { - - impl->by_indices[BY_DAY]++; /* Look at next elem in BYDAY array */ - - /* Are we at the end of the BYDAY array? */ - if (impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]] - ==ICAL_RECURRENCE_ARRAY_MAX){ - - impl->by_indices[BY_DAY] = 0; /* Reset to 0 */ - end_of_data = 1; /* Signal that we're at the end */ - } - - /* Add the day of week offset to to the start of this week, and use - that to get the next day */ - dow = impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]; - start_of_week = icaltime_start_doy_of_week(impl->last); - - dow--; /*Sun is 1, not 0 */ - - if(dow+start_of_week <1 && !end_of_data){ - /* The selected date is in the previous year. */ - continue; - } - - next = icaltime_from_day_of_year(start_of_week + dow,impl->last.year); - - impl->last.day = next.day; - impl->last.month = next.month; - impl->last.year = next.year; - - return end_of_data; - } -} +/* Returns the day of the month for the current month of t that is the + pos'th instance of the day-of-week dow */ -int nth_weekday(short dow, short pos, struct icaltimetype t){ +static int nth_weekday(int dow, int pos, struct icaltimetype t){ - short days_in_month = icaltime_days_in_month(t.month,t.year); - short end_dow, start_dow; - short wd; + int days_in_month = icaltime_days_in_month(t.month, t.year); + int end_dow, start_dow; + int wd; if(pos >= 0){ t.day = 1; start_dow = icaltime_day_of_week(t); if (pos != 0) { pos--; } /* find month day of first occurrence of dow -- such as the month day of the first monday */ wd = dow-start_dow+1; if (wd <= 0){ wd = wd + 7; } wd = wd + pos * 7; } else { t.day = days_in_month; end_dow = icaltime_day_of_week(t); pos++; /* find month day of last occurrence of dow -- such as the month day of the last monday */ wd = (end_dow - dow); if (wd < 0){ wd = wd+ 7; } wd = days_in_month - wd; wd = wd + pos * 7; } return wd; } +static int is_day_in_byday(icalrecur_iterator* impl,struct icaltimetype tt){ + + int idx; -int next_month(struct icalrecur_iterator_impl* impl) + for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); + int pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + int this_dow = icaltime_day_of_week(tt); + + if( (pos == 0 && dow == this_dow ) || /* Just a dow, like "TU" or "FR" */ + (nth_weekday(dow,pos,tt) == tt.day)){ /*pos+wod: "3FR" or -1TU" */ + return 1; + } + } + + return 0; +} + +static int next_month(icalrecur_iterator* impl) { int data_valid = 1; - short this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); + int this_frequency = (impl->rule.freq == ICAL_MONTHLY_RECURRENCE); assert( has_by_data(impl,BY_MONTH) || this_frequency); /* Iterate through the occurrences within a day. If we don't get to the end of the intra-day data, don't bother going to the next month */ if (next_hour(impl) == 0){ return data_valid; /* Signal that the data is valid */ } - /* Now iterate through the occurrences within a month -- by days, weeks or weekdays. */ + + /* + * Case 1: + * Rules Like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR;BYMONTHDAY=13 + */ if(has_by_data(impl,BY_DAY) && has_by_data(impl,BY_MONTH_DAY)){ - /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR;BYMONTHDAY=13 */ - short day, idx,j; - short days_in_month = icaltime_days_in_month(impl->last.month, + int day, idx,j; + int days_in_month = icaltime_days_in_month(impl->last.month, impl->last.year); /* Iterate through the remaining days in the month and check if each day is listed in the BY_DAY array and in the BY_MONTHDAY array. This seems very inneficient, but I think it is the simplest way to account for both BYDAY=1FR (First friday in month) and BYDAY=FR ( every friday in month ) */ for(day = impl->last.day+1; day <= days_in_month; day++){ for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short dow = + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); - short mday = BYMDPTR[j]; - short this_dow; + int pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); + int mday = BYMDPTR[j]; + int this_dow; impl->last.day = day; this_dow = icaltime_day_of_week(impl->last); if( (pos == 0 && dow == this_dow && mday == day) || (nth_weekday(dow,pos,impl->last) == day && mday==day)){ goto MDEND; } } } } MDEND: if ( day > days_in_month){ impl->last.day = 1; increment_month(impl); data_valid = 0; /* signal that impl->last is invalid */ } - + + /* + * Case 2: + * Rules Like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR + */ + } else if(has_by_data(impl,BY_DAY)){ - /* Cases like: FREQ=MONTHLY;INTERVAL=1;BYDAY=FR */ /* For this case, the weekdays are relative to the month. BYDAY=FR -> First Friday in month, etc. */ - short day, idx; - short days_in_month = icaltime_days_in_month(impl->last.month, - impl->last.year); + /* This code iterates through the remaining days in the month + and checks if each day is listed in the BY_DAY array. This + seems very inneficient, but I think it is the simplest way to + account for both BYDAY=1FR (First friday in month) and + BYDAY=FR ( every friday in month ) */ + int day; + int days_in_month = icaltime_days_in_month(impl->last.month, + impl->last.year); assert( BYDAYPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); - /* Iterate through the remaining days in the month and check if - each day is listed in the BY_DAY array. This seems very - inneficient, but I think it is the simplest way to account - for both BYDAY=1FR (First friday in month) and BYDAY=FR ( - every friday in month ) */ - for(day = impl->last.day+1; day <= days_in_month; day++){ - for(idx = 0; BYDAYPTR[idx] != ICAL_RECURRENCE_ARRAY_MAX; idx++){ - short dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[idx]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[idx]); - short this_dow; - - impl->last.day = day; - this_dow = icaltime_day_of_week(impl->last); - - if( (pos == 0 && dow == this_dow ) || - (nth_weekday(dow,pos,impl->last) == day)){ - goto DEND; - } + impl->last.day = day; + if(is_day_in_byday(impl,impl->last)){ + data_valid = 1; + break; } } - DEND: - if ( day > days_in_month){ impl->last.day = 1; increment_month(impl); - data_valid = 0; /* signal that impl->last is invalid */ + + /* Did moving to the next month put us on a valid date? if + so, note that the new data is valid, if, not, mark it + invalid */ + + if(is_day_in_byday(impl,impl->last)){ + data_valid = 1; + } else { + data_valid = 0; /* signal that impl->last is invalid */ + } } + /* + * Case 3 + * Rules Like: FREQ=MONTHLY;COUNT=10;BYMONTHDAY=-3 + */ + } else if (has_by_data(impl,BY_MONTH_DAY)) { - /* Cases like: FREQ=MONTHLY;COUNT=10;BYMONTHDAY=-3 */ - short day; + int day; assert( BYMDPTR[0]!=ICAL_RECURRENCE_ARRAY_MAX); BYMDIDX++; /* Are we at the end of the BYDAY array? */ if (BYMDPTR[BYMDIDX] ==ICAL_RECURRENCE_ARRAY_MAX){ BYMDIDX = 0; /* Reset to 0 */ increment_month(impl); } day = BYMDPTR[BYMDIDX]; if (day < 0) { - day = icaltime_days_in_month(impl->last.month,impl->last.year)+ - day + 1; + day = icaltime_days_in_month(impl->last.month, impl->last.year) + day + 1; } impl->last.day = day; } else { increment_month(impl); } - return data_valid; /* Signal that the data is valid */ + return data_valid; } +static int next_weekday_by_week(icalrecur_iterator* impl) +{ + + int end_of_data = 0; + int start_of_week, dow; + struct icaltimetype next; + + if (next_hour(impl) == 0){ + return 0; + } + + if(!has_by_data(impl,BY_DAY)){ + return 1; + } + + /* If we get here, we need to step to tne next day */ + + for (;;) { + struct icaltimetype tt = icaltime_null_time(); + BYDAYIDX++; /* Look at next elem in BYDAY array */ + + /* Are we at the end of the BYDAY array? */ + if (BYDAYPTR[BYDAYIDX]==ICAL_RECURRENCE_ARRAY_MAX){ + BYDAYIDX = 0; /* Reset to 0 */ + end_of_data = 1; /* Signal that we're at the end */ + } + + /* Add the day of week offset to to the start of this week, and use + that to get the next day */ + /* ignore position of dow ("4FR"), only use dow ("FR")*/ + dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[BYDAYIDX]); + tt.year = impl->last.year; + tt.day = impl->last.day; + tt.month = impl->last.month; + + start_of_week = icaltime_start_doy_of_week(tt); + + dow--; /* Set Sunday to be 0 */ + + if(dow+start_of_week <1){ + /* The selected date is in the previous year. */ + if(!end_of_data){ + continue; + } + } + + next = icaltime_from_day_of_year(start_of_week + dow,impl->last.year); + + impl->last.day = next.day; + impl->last.month = next.month; + impl->last.year = next.year; + + return end_of_data; + } + +} -int next_week(struct icalrecur_iterator_impl* impl) +static int next_week(icalrecur_iterator* impl) { - short has_by_data = (impl->by_ptrs[BY_WEEK_NO][0]!=ICAL_RECURRENCE_ARRAY_MAX); - short this_frequency = (impl->rule.freq == ICAL_WEEKLY_RECURRENCE); - short end_of_data = 0; + int end_of_data = 0; - /* Increment to the next week day */ + /* Increment to the next week day, if there is data at a level less than a week */ if (next_weekday_by_week(impl) == 0){ return 0; /* Have not reached end of week yet */ } /* If we get here, we have incremented through the entire week, and can increment to the next week */ - - if( has_by_data){ + if( has_by_data(impl,BY_WEEK_NO)){ + /*FREQ=WEEKLY;BYWEEK=20*/ /* Use the Week Number byrule data */ int week_no; struct icaltimetype t; impl->by_indices[BY_WEEK_NO]++; if (impl->by_ptrs[BY_WEEK_NO][impl->by_indices[BY_WEEK_NO]] ==ICAL_RECURRENCE_ARRAY_MAX){ impl->by_indices[BY_WEEK_NO] = 0; end_of_data = 1; } t = impl->last; t.month=1; /* HACK, should be setting to the date of the first week of year*/ t.day=1; week_no = impl->by_ptrs[BY_WEEK_NO][impl->by_indices[BY_WEEK_NO]]; impl->last.day += week_no*7; impl->last = icaltime_normalize(impl->last); - } else if( !has_by_data && this_frequency ){ - /* If there is no BY_WEEK_NO data, just jump forward 7 days. */ + } else { + /* Jump to the next week */ increment_monthday(impl,7*impl->rule.interval); } - - if(has_by_data && end_of_data && this_frequency ){ + if( has_by_data(impl,BY_WEEK_NO) && end_of_data){ increment_year(impl,1); } return end_of_data; } -/* Expand the BYDAY rule part and return a pointer to a newly allocated list of days. */ -pvl_list expand_by_day(struct icalrecur_iterator_impl* impl,short year) +/** Expand the BYDAY rule part and return a pointer to a newly allocated list of days. */ +static pvl_list expand_by_day(icalrecur_iterator* impl, int year) { /* Try to calculate each of the occurrences. */ int i; pvl_list days_list = pvl_newlist(); - short start_dow, end_dow, end_year_day, start_doy; + int start_dow, end_dow, end_year_day; struct icaltimetype tmp = impl->last; tmp.year= year; tmp.month = 1; tmp.day = 1; tmp.is_date = 1; + /* Find the day that 1st Jan falls on, 1 (Sun) to 7 (Sat). */ start_dow = icaltime_day_of_week(tmp); - start_doy = icaltime_start_doy_of_week(tmp); /* Get the last day of the year*/ - tmp.year++; - tmp = icaltime_normalize(tmp); - tmp.day--; - tmp = icaltime_normalize(tmp); + tmp.year= year; + tmp.month = 12; + tmp.day = 31; + tmp.is_date = 1; end_dow = icaltime_day_of_week(tmp); end_year_day = icaltime_day_of_year(tmp); for(i = 0; BYDAYPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ - short dow = + /* This is 1 (Sun) to 7 (Sat). */ + int dow = icalrecurrencetype_day_day_of_week(BYDAYPTR[i]); - short pos = icalrecurrencetype_day_position(BYDAYPTR[i]); + int pos = icalrecurrencetype_day_position(BYDAYPTR[i]); if(pos == 0){ /* The day was specified without a position -- it is just a bare day of the week ( BYDAY=SU) so add all of the days of the year with this day-of-week*/ - int week; - for(week = 0; week < 52 ; week ++){ - short doy = start_doy + (week * 7) + dow-1; + int doy, tmp_start_doy; - if(doy > end_year_day){ - break; - } else { + tmp_start_doy = ((dow + 7 - start_dow) % 7) + 1; + + for (doy = tmp_start_doy; doy <= end_year_day; doy += 7) pvl_push(days_list,(void*)(int)doy); - } - } + } else if ( pos > 0) { int first; /* First occurrence of dow in year */ if( dow >= start_dow) { first = dow - start_dow + 1; } else { first = dow - start_dow + 8; } - /* THen just multiple the position times 7 to get the pos'th day in the year */ + /* Then just multiple the position times 7 to get the pos'th day in the year */ pvl_push(days_list,(void*)(first+ (pos-1) * 7)); } else { /* pos < 0 */ int last; pos = -pos; /* last occurrence of dow in year */ if( dow <= end_dow) { last = end_year_day - end_dow + dow; } else { last = end_year_day - end_dow + dow - 7; } pvl_push(days_list,(void*)(last - (pos-1) * 7)); } } return days_list; } /* For INTERVAL=YEARLY, set up the days[] array in the iterator to list all of the days of the current year that are specified in this rule. */ -int expand_year_days(struct icalrecur_iterator_impl* impl,short year) +static int expand_year_days(icalrecur_iterator* impl, int year) { int j,k; int days_index=0; struct icaltimetype t; int flags; - t = icaltime_null_time(); + t = icaltime_null_date(); #define HBD(x) has_by_data(impl,x) - t.is_date = 1; /* Needed to make day_of_year routines work property */ - - memset(&t,0,sizeof(t)); memset(impl->days,ICAL_RECURRENCE_ARRAY_MAX_BYTE,sizeof(impl->days)); + /* The flags and the following switch statement select which code + to use to expand the yers days, based on which BY-rules are + present. */ + flags = (HBD(BY_DAY) ? 1<<BY_DAY : 0) + (HBD(BY_WEEK_NO) ? 1<<BY_WEEK_NO : 0) + (HBD(BY_MONTH_DAY) ? 1<<BY_MONTH_DAY : 0) + (HBD(BY_MONTH) ? 1<<BY_MONTH : 0) + (HBD(BY_YEAR_DAY) ? 1<<BY_YEAR_DAY : 0); switch(flags) { case 0: { /* FREQ=YEARLY; */ + t = impl->dtstart; + t.year = impl->last.year; + impl->days[days_index++] = (short)icaltime_day_of_year(t); + break; } case 1<<BY_MONTH: { /* FREQ=YEARLY; BYMONTH=3,11*/ for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ - struct icaltimetype t; - short month = impl->by_ptrs[BY_MONTH][j]; - short doy; + int month = impl->by_ptrs[BY_MONTH][j]; + int doy; t = impl->dtstart; t.year = year; t.month = month; t.is_date = 1; doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } break; } case 1<<BY_MONTH_DAY: { /* FREQ=YEARLY; BYMONTHDAY=1,15*/ for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) { - short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; - short doy; + int month_day = impl->by_ptrs[BY_MONTH_DAY][k]; + int doy; t = impl->dtstart; t.day = month_day; t.year = year; t.is_date = 1; doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } break; } case (1<<BY_MONTH_DAY) + (1<<BY_MONTH): { /* FREQ=YEARLY; BYMONTHDAY=1,15; BYMONTH=10 */ for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ for(k=0;impl->by_ptrs[BY_MONTH_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++) { - short month = impl->by_ptrs[BY_MONTH][j]; - short month_day = impl->by_ptrs[BY_MONTH_DAY][k]; - short doy; + int month = impl->by_ptrs[BY_MONTH][j]; + int month_day = impl->by_ptrs[BY_MONTH_DAY][k]; + int doy; t.day = month_day; t.month = month; t.year = year; t.is_date = 1; doy = icaltime_day_of_year(t); - impl->days[days_index++] = doy; + impl->days[days_index++] = (short)doy; } } break; } case 1<<BY_WEEK_NO: { /* FREQ=YEARLY; BYWEEKNO=20,50 */ - struct icaltimetype t; - short dow; + int dow; t.day = impl->dtstart.day; t.month = impl->dtstart.month; t.year = year; t.is_date = 1; dow = icaltime_day_of_week(t); /* HACK Not finished */ icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); break; } case (1<<BY_WEEK_NO) + (1<<BY_MONTH_DAY): { /*FREQ=YEARLY; WEEKNO=20,50; BYMONTH= 6,11 */ icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); break; } case 1<<BY_DAY: { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR*/ - int days_index = 0; pvl_elem i; pvl_list days = expand_by_day(impl,year); for(i=pvl_head(days);i!=0;i=pvl_next(i)){ - short day = (short)(int)pvl_data(i); + short day = (short)(*((int*)pvl_data(i))); impl->days[days_index++] = day; } pvl_free(days); break; } case (1<<BY_DAY)+(1<<BY_MONTH): { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTH = 12*/ - int days_index = 0; - pvl_elem itr; - pvl_list days = expand_by_day(impl,year); - for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short doy = (short)(int)pvl_data(itr); - struct icaltimetype tt; - short j; + for(j=0;impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ + int month = impl->by_ptrs[BY_MONTH][j]; + int days_in_month = icaltime_days_in_month(month,year); + int first_dow, last_dow, doy_offset; - tt = icaltime_from_day_of_year(doy,year); + t.year = year; + t.month = month; + t.day = 1; + t.is_date = 1; - for(j=0; - impl->by_ptrs[BY_MONTH][j]!=ICAL_RECURRENCE_ARRAY_MAX; - j++){ - short month = impl->by_ptrs[BY_MONTH][j]; + first_dow = icaltime_day_of_week(t); - if(tt.month == month){ - impl->days[days_index++] = doy; - } - } + /* This holds the day offset used to calculate the day of the year + from the month day. Just add the month day to this. */ + doy_offset = icaltime_day_of_year(t) - 1; - } + t.day = days_in_month; + last_dow = icaltime_day_of_week(t); - pvl_free(days); + for(k=0;impl->by_ptrs[BY_DAY][k]!=ICAL_RECURRENCE_ARRAY_MAX;k++){ + short day_coded = impl->by_ptrs[BY_DAY][k]; + enum icalrecurrencetype_weekday dow = + icalrecurrencetype_day_day_of_week(day_coded); + int pos = icalrecurrencetype_day_position(day_coded); + int first_matching_day, last_matching_day, day, month_day; + + /* Calculate the first day in the month with the given weekday, + and the last day. */ + first_matching_day = ((dow + 7 - first_dow) % 7) + 1; + last_matching_day = days_in_month - ((last_dow + 7 - dow) % 7); + + if (pos == 0) { + /* Add all of instances of the weekday within the month. */ + for (day = first_matching_day; day <= days_in_month; day += 7) + impl->days[days_index++] = (short)(doy_offset + day); + + } else if (pos > 0) { + /* Add the nth instance of the weekday within the month. */ + month_day = first_matching_day + (pos - 1) * 7; + + if (month_day <= days_in_month) + impl->days[days_index++] = (short)(doy_offset + month_day); + } else { + /* Add the -nth instance of the weekday within the month.*/ + month_day = last_matching_day + (pos + 1) * 7; + + if (month_day > 0) + impl->days[days_index++] = (short)(doy_offset + month_day); + } + } + } break; } case (1<<BY_DAY) + (1<<BY_MONTH_DAY) : { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=1,15*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short j; tt = icaltime_from_day_of_year(day,year); for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short mday = BYMDPTR[j]; + int mday = BYMDPTR[j]; if(tt.day == mday){ impl->days[days_index++] = day; } } } pvl_free(days); break; } case (1<<BY_DAY) + (1<<BY_MONTH_DAY) + (1<<BY_MONTH): { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; BYMONTHDAY=10; MYMONTH=6,11*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short i,j; + int i; tt = icaltime_from_day_of_year(day,year); for(i = 0; BYMONPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ for(j = 0; BYMDPTR[j]!=ICAL_RECURRENCE_ARRAY_MAX; j++){ - short mday = BYMDPTR[j]; - short month = BYMONPTR[i]; + int mday = BYMDPTR[j]; + int month = BYMONPTR[i]; if(tt.month == month && tt.day == mday){ impl->days[days_index++] = day; } } } } pvl_free(days); break; } case (1<<BY_DAY) + (1<<BY_WEEK_NO) : { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; WEEKNO=20,50*/ - int days_index = 0; pvl_elem itr; pvl_list days = expand_by_day(impl,year); for(itr=pvl_head(days);itr!=0;itr=pvl_next(itr)){ - short day = (short)(int)pvl_data(itr); + short day = (short)(*((int*)pvl_data(itr))); struct icaltimetype tt; - short i; + int i; tt = icaltime_from_day_of_year(day,year); for(i = 0; BYWEEKPTR[i] != ICAL_RECURRENCE_ARRAY_MAX; i++){ - short weekno = BYWEEKPTR[i]; - - if(weekno== icaltime_week_number(tt)){ + int weekno = BYWEEKPTR[i]; + int this_weekno = icaltime_week_number(tt); + if(weekno== this_weekno){ impl->days[days_index++] = day; } } } pvl_free(days); break; } case (1<<BY_DAY) + (1<<BY_WEEK_NO) + (1<<BY_MONTH_DAY): { /*FREQ=YEARLY; BYDAY=TH,20MO,-10FR; WEEKNO=20,50; BYMONTHDAY=1,15*/ icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); break; } case 1<<BY_YEAR_DAY: { for(j=0;impl->by_ptrs[BY_YEAR_DAY][j]!=ICAL_RECURRENCE_ARRAY_MAX;j++){ - short doy = impl->by_ptrs[BY_YEAR_DAY][j]; - impl->days[days_index++] = doy; + impl->days[days_index++] = impl->by_ptrs[BY_YEAR_DAY][j]; } break; } default: { icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); break; } } return 0; } -int next_year(struct icalrecur_iterator_impl* impl) +static int next_year(icalrecur_iterator* impl) { struct icaltimetype next; - /* Next_year does it's own interatio in days, so the next level down is hours */ if (next_hour(impl) == 0){ - return 1; + return 0; } if (impl->days[++impl->days_index] == ICAL_RECURRENCE_ARRAY_MAX){ impl->days_index = 0; + + for (;;) { increment_year(impl,impl->rule.interval); expand_year_days(impl,impl->last.year); + if (impl->days[0] != ICAL_RECURRENCE_ARRAY_MAX) + break; } - - if(impl->days[0] == ICAL_RECURRENCE_ARRAY_MAX) { - return 0; } - next = icaltime_from_day_of_year(impl->days[impl->days_index],impl->last.year); + next = icaltime_from_day_of_year(impl->days[impl->days_index], impl->last.year); impl->last.day = next.day; impl->last.month = next.month; return 1; } -int icalrecur_check_rulepart(struct icalrecur_iterator_impl* impl, - short v, enum byrule byrule) +int icalrecur_check_rulepart(icalrecur_iterator* impl, + int v, enum byrule byrule) { int itr; if(impl->by_ptrs[byrule][0]!=ICAL_RECURRENCE_ARRAY_MAX){ for(itr=0; impl->by_ptrs[byrule][itr]!=ICAL_RECURRENCE_ARRAY_MAX;itr++){ if(impl->by_ptrs[byrule][itr] == v){ return 1; } } } return 0; } -int check_contract_restriction(struct icalrecur_iterator_impl* impl, - enum byrule byrule, short v) +static int check_contract_restriction(icalrecur_iterator* impl, + enum byrule byrule, int v) { int pass = 0; int itr; icalrecurrencetype_frequency freq = impl->rule.freq; if(impl->by_ptrs[byrule][0]!=ICAL_RECURRENCE_ARRAY_MAX && expand_map[freq].map[byrule] == CONTRACT){ for(itr=0; impl->by_ptrs[byrule][itr]!=ICAL_RECURRENCE_ARRAY_MAX;itr++){ if(impl->by_ptrs[byrule][itr] == v){ pass=1; break; } } return pass; } else { /* This is not a contracting byrule, or it has no data, so the test passes*/ return 1; } } -int check_contracting_rules(struct icalrecur_iterator_impl* impl) +static int check_contracting_rules(icalrecur_iterator* impl) { - int day_of_week=0; - int week_no=0; - int year_day=0; + int day_of_week = icaltime_day_of_week(impl->last); + int week_no = icaltime_week_number(impl->last); + int year_day = icaltime_day_of_year(impl->last); if ( - check_contract_restriction(impl,BY_SECOND,impl->last.second) && - check_contract_restriction(impl,BY_MINUTE,impl->last.minute) && - check_contract_restriction(impl,BY_HOUR,impl->last.hour) && - check_contract_restriction(impl,BY_DAY,day_of_week) && - check_contract_restriction(impl,BY_WEEK_NO,week_no) && - check_contract_restriction(impl,BY_MONTH_DAY,impl->last.day) && - check_contract_restriction(impl,BY_MONTH,impl->last.month) && - check_contract_restriction(impl,BY_YEAR_DAY,year_day) ) + check_contract_restriction(impl,BY_SECOND, impl->last.second) && + check_contract_restriction(impl,BY_MINUTE, impl->last.minute) && + check_contract_restriction(impl,BY_HOUR, impl->last.hour) && + check_contract_restriction(impl,BY_DAY, day_of_week) && + check_contract_restriction(impl,BY_WEEK_NO, week_no) && + check_contract_restriction(impl,BY_MONTH_DAY, impl->last.day) && + check_contract_restriction(impl,BY_MONTH, impl->last.month) && + check_contract_restriction(impl,BY_YEAR_DAY, year_day) ) { return 1; } else { return 0; } } -struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) +struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *impl) { int valid = 1; - struct icalrecur_iterator_impl* impl = - (struct icalrecur_iterator_impl*)itr; if( (impl->rule.count!=0 &&impl->occurrence_no >= impl->rule.count) || (!icaltime_is_null_time(impl->rule.until) && icaltime_compare(impl->last,impl->rule.until) > 0)) { return icaltime_null_time(); } if(impl->occurrence_no == 0 && icaltime_compare(impl->last,impl->dtstart) >= 0){ impl->occurrence_no++; return impl->last; } do { valid = 1; switch(impl->rule.freq){ case ICAL_SECONDLY_RECURRENCE: { next_second(impl); break; } case ICAL_MINUTELY_RECURRENCE: { next_minute(impl); break; } case ICAL_HOURLY_RECURRENCE: { next_hour(impl); break; } case ICAL_DAILY_RECURRENCE: { next_day(impl); break; } case ICAL_WEEKLY_RECURRENCE: { next_week(impl); break; } case ICAL_MONTHLY_RECURRENCE: { valid = next_month(impl); break; } case ICAL_YEARLY_RECURRENCE:{ - valid = next_year(impl); + next_year(impl); break; } default:{ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return icaltime_null_time(); } } if(impl->last.year >= 2038 ){ /* HACK */ return icaltime_null_time(); } } while(!check_contracting_rules(impl) - || icaltime_compare(impl->last,impl->dtstart) <= 0 + || icaltime_compare(impl->last,impl->dtstart) < 0 || valid == 0); /* Ignore null times and times that are after the until time */ if( !icaltime_is_null_time(impl->rule.until) && icaltime_compare(impl->last,impl->rule.until) > 0 ) { return icaltime_null_time(); } impl->occurrence_no++; return impl->last; } /************************** Type Routines **********************/ void icalrecurrencetype_clear(struct icalrecurrencetype *recur) { memset(recur,ICAL_RECURRENCE_ARRAY_MAX_BYTE, sizeof(struct icalrecurrencetype)); recur->week_start = ICAL_MONDAY_WEEKDAY; recur->freq = ICAL_NO_RECURRENCE; recur->interval = 1; memset(&(recur->until),0,sizeof(struct icaltimetype)); recur->count = 0; } -/* The 'day' element of icalrecurrencetype_weekday is encoded to allow -reporesentation of both the day of the week ( Monday, Tueday), but -also the Nth day of the week ( First tuesday of the month, last -thursday of the year) These routines decode the day values. - -The day's position in the period ( Nth-ness) and the numerical value -of the day are encoded together as: pos*7 + dow - -A position of 0 means 'any' or 'every' - +/** The 'day' element of icalrecurrencetype_weekday is encoded to + * allow representation of both the day of the week ( Monday, Tueday), + * but also the Nth day of the week ( First tuesday of the month, last + * thursday of the year) These routines decode the day values. + * + * The day's position in the period ( Nth-ness) and the numerical + * value of the day are encoded together as: pos*7 + dow + * + * A position of 0 means 'any' or 'every' */ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day) { return abs(day)%8; } -short icalrecurrencetype_day_position(short day) +int icalrecurrencetype_day_position(short day) { - short wd, pos; + int wd, pos; wd = icalrecurrencetype_day_day_of_week(day); pos = (abs(day)-wd)/8 * ((day<0)?-1:1); return pos; } /****************** Enumeration Routines ******************/ -struct {icalrecurrencetype_weekday wd; const char * str; } +static struct {icalrecurrencetype_weekday wd; const char * str; } wd_map[] = { {ICAL_SUNDAY_WEEKDAY,"SU"}, {ICAL_MONDAY_WEEKDAY,"MO"}, {ICAL_TUESDAY_WEEKDAY,"TU"}, {ICAL_WEDNESDAY_WEEKDAY,"WE"}, {ICAL_THURSDAY_WEEKDAY,"TH"}, {ICAL_FRIDAY_WEEKDAY,"FR"}, {ICAL_SATURDAY_WEEKDAY,"SA"}, {ICAL_NO_WEEKDAY,0} }; const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind) { int i; for (i=0; wd_map[i].wd != ICAL_NO_WEEKDAY; i++) { if ( wd_map[i].wd == kind) { return wd_map[i].str; } } return 0; } icalrecurrencetype_weekday icalrecur_string_to_weekday(const char* str) { int i; for (i=0; wd_map[i].wd != ICAL_NO_WEEKDAY; i++) { if ( strcmp(str,wd_map[i].str) == 0){ return wd_map[i].wd; } } return ICAL_NO_WEEKDAY; } -struct { +static struct { icalrecurrencetype_frequency kind; const char* str; } freq_map[] = { {ICAL_SECONDLY_RECURRENCE,"SECONDLY"}, {ICAL_MINUTELY_RECURRENCE,"MINUTELY"}, {ICAL_HOURLY_RECURRENCE,"HOURLY"}, {ICAL_DAILY_RECURRENCE,"DAILY"}, {ICAL_WEEKLY_RECURRENCE,"WEEKLY"}, {ICAL_MONTHLY_RECURRENCE,"MONTHLY"}, {ICAL_YEARLY_RECURRENCE,"YEARLY"}, {ICAL_NO_RECURRENCE,0} }; const char* icalrecur_freq_to_string(icalrecurrencetype_frequency kind) { int i; for (i=0; freq_map[i].kind != ICAL_NO_RECURRENCE ; i++) { if ( freq_map[i].kind == kind ) { return freq_map[i].str; } } return 0; } icalrecurrencetype_frequency icalrecur_string_to_freq(const char* str) { int i; for (i=0; freq_map[i].kind != ICAL_NO_RECURRENCE ; i++) { if ( strcmp(str,freq_map[i].str) == 0){ return freq_map[i].kind; } } return ICAL_NO_RECURRENCE; } -/* Fill an array with the 'count' number of occurrences generated by - the rrule. Note that the times are returned in UTC, but the times - are calculated in local time. YOu will have to convert the results - back into local time before using them. */ +/** Fill an array with the 'count' number of occurrences generated by + * the rrule. Note that the times are returned in UTC, but the times + * are calculated in local time. YOu will have to convert the results + * back into local time before using them. + */ int icalrecur_expand_recurrence(char* rule, time_t start, int count, time_t* array) { struct icalrecurrencetype recur; icalrecur_iterator* ritr; time_t tt; struct icaltimetype icstart, next; int i = 0; memset(array, 0, count*sizeof(time_t)); - icstart = icaltime_from_timet(start,0); + icstart = icaltime_from_timet_with_zone(start,0,0); recur = icalrecurrencetype_from_string(rule); for(ritr = icalrecur_iterator_new(recur,icstart), next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next) && i < count; next = icalrecur_iterator_next(ritr)){ tt = icaltime_as_timet(next); if (tt >= start ){ array[i++] = tt; } } icalrecur_iterator_free(ritr); return 1; } diff --git a/libical/src/libical/icalrecur.h b/libical/src/libical/icalrecur.h index 5fcdc15..5f6ac55 100644 --- a/libical/src/libical/icalrecur.h +++ b/libical/src/libical/icalrecur.h @@ -1,189 +1,214 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalrecur.h CREATOR: eric 20 March 2000 (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/ +*/ + +/** +@file icalrecur.h +@brief Routines for dealing with recurring time How to use: 1) Get a rule and a start time from a component + +@code icalproperty rrule; struct icalrecurrencetype recur; struct icaltimetype dtstart; rrule = icalcomponent_get_first_property(comp,ICAL_RRULE_PROPERTY); recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); +@endcode Or, just make them up: + +@code recur = icalrecurrencetype_from_string("FREQ=YEARLY;BYDAY=SU,WE"); dtstart = icaltime_from_string("19970101T123000") +@endcode 2) Create an iterator + +@code icalrecur_iterator* ritr; ritr = icalrecur_iterator_new(recur,start); +@endcode 3) Iterator over the occurrences + +@code struct icaltimetype next; while (next = icalrecur_iterator_next(ritr) && !icaltime_is_null_time(next){ Do something with next } +@endcode Note that that the time returned by icalrecur_iterator_next is in whatever timezone that dtstart is in. -======================================================================*/ +*/ #ifndef ICALRECUR_H #define ICALRECUR_H #include <time.h> #include "icaltime.h" -/*********************************************************************** +/* * Recurrance enumerations -**********************************************************************/ + */ typedef enum icalrecurrencetype_frequency { /* These enums are used to index an array, so don't change the order or the integers */ ICAL_SECONDLY_RECURRENCE=0, ICAL_MINUTELY_RECURRENCE=1, ICAL_HOURLY_RECURRENCE=2, ICAL_DAILY_RECURRENCE=3, ICAL_WEEKLY_RECURRENCE=4, ICAL_MONTHLY_RECURRENCE=5, ICAL_YEARLY_RECURRENCE=6, ICAL_NO_RECURRENCE=7 } icalrecurrencetype_frequency; typedef enum icalrecurrencetype_weekday { ICAL_NO_WEEKDAY, ICAL_SUNDAY_WEEKDAY, ICAL_MONDAY_WEEKDAY, ICAL_TUESDAY_WEEKDAY, ICAL_WEDNESDAY_WEEKDAY, ICAL_THURSDAY_WEEKDAY, ICAL_FRIDAY_WEEKDAY, ICAL_SATURDAY_WEEKDAY } icalrecurrencetype_weekday; enum { ICAL_RECURRENCE_ARRAY_MAX = 0x7f7f, ICAL_RECURRENCE_ARRAY_MAX_BYTE = 0x7f }; -/********************** Recurrence type routines **************/ +/** + * Recurrence type routines + */ /* See RFC 2445 Section 4.3.10, RECUR Value, for an explaination of the values and fields in struct icalrecurrencetype */ #define ICAL_BY_SECOND_SIZE 61 #define ICAL_BY_MINUTE_SIZE 61 #define ICAL_BY_HOUR_SIZE 25 #define ICAL_BY_DAY_SIZE 364 /* 7 days * 52 weeks */ #define ICAL_BY_MONTHDAY_SIZE 32 #define ICAL_BY_YEARDAY_SIZE 367 #define ICAL_BY_WEEKNO_SIZE 54 #define ICAL_BY_MONTH_SIZE 13 #define ICAL_BY_SETPOS_SIZE 367 -/* Main struct for holding digested recurrence rules */ +/** Main struct for holding digested recurrence rules */ struct icalrecurrencetype { icalrecurrencetype_frequency freq; /* until and count are mutually exclusive. */ struct icaltimetype until; int count; short interval; icalrecurrencetype_weekday week_start; /* The BY* parameters can each take a list of values. Here I * assume that the list of values will not be larger than the * range of the value -- that is, the client will not name a * value more than once. * Each of the lists is terminated with the value * ICAL_RECURRENCE_ARRAY_MAX unless the the list is full. */ short by_second[ICAL_BY_SECOND_SIZE]; short by_minute[ICAL_BY_MINUTE_SIZE]; short by_hour[ICAL_BY_HOUR_SIZE]; short by_day[ICAL_BY_DAY_SIZE]; /* Encoded value, see below */ short by_month_day[ICAL_BY_MONTHDAY_SIZE]; short by_year_day[ ICAL_BY_YEARDAY_SIZE]; short by_week_no[ICAL_BY_WEEKNO_SIZE]; short by_month[ICAL_BY_MONTH_SIZE]; short by_set_pos[ICAL_BY_SETPOS_SIZE]; }; void icalrecurrencetype_clear(struct icalrecurrencetype *r); -/* The 'day' element of the by_day array is encoded to allow -representation of both the day of the week ( Monday, Tueday), but also -the Nth day of the week ( First tuesday of the month, last thursday of -the year) These routines decode the day values */ +/** + * Array Encoding + * + * The 'day' element of the by_day array is encoded to allow + * representation of both the day of the week ( Monday, Tueday), but also + * the Nth day of the week ( First tuesday of the month, last thursday of + * the year) These routines decode the day values + */ -/* 1 == Monday, etc. */ +/** 1 == Monday, etc. */ enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day); -/* 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */ -short icalrecurrencetype_day_position(short day); +/** 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */ +int icalrecurrencetype_day_position(short day); -/*********************************************************************** - * Recurrance rule parser -**********************************************************************/ +/** Recurrance rule parser */ -/* Convert between strings ans recurrencetype structures. */ +/** Convert between strings and recurrencetype structures. */ struct icalrecurrencetype icalrecurrencetype_from_string(const char* str); char* icalrecurrencetype_as_string(struct icalrecurrencetype *recur); -/********** recurrence iteration routines ********************/ +/** Recurrence iteration routines */ -typedef void icalrecur_iterator; +typedef struct icalrecur_iterator_impl icalrecur_iterator; -/* Create a new recurrence rule iterator */ +/** Create a new recurrence rule iterator */ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart); -/* Get the next occurrence from an iterator */ +/** Get the next occurrence from an iterator */ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator*); -/* Free the iterator */ +void icalrecur_iterator_decrement_count(icalrecur_iterator*); + +/** Free the iterator */ void icalrecur_iterator_free(icalrecur_iterator*); -/* Fills array up with at most 'count' time_t values, each - representing an occurrence time in seconds past the POSIX epoch */ +/** + * Fills array up with at most 'count' time_t values, each + * representing an occurrence time in seconds past the POSIX epoch + */ int icalrecur_expand_recurrence(char* rule, time_t start, int count, time_t* array); #endif diff --git a/libical/src/libical/icalrestriction.c b/libical/src/libical/icalrestriction.c index 0f863c4..3d2bd15 100644 --- a/libical/src/libical/icalrestriction.c +++ b/libical/src/libical/icalrestriction.c @@ -1,1781 +1,1861 @@ /* -*- Mode: C -*- */ /* ====================================================================== File: icalrestriction.c (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ /*#line 7 "icalrestriction.c.in"*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalrestriction.h" #include "icalenums.h" #include "icalerror.h" #include <assert.h> #include <stdio.h> /* For snprintf */ -int snprintf(char *str, size_t n, char const *fmt, ...); - #define TMP_BUF_SIZE 1024 +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif + /* Define the structs for the restrictions. these data are filled out in machine generated code below */ struct icalrestriction_property_record; typedef char* (*restriction_func)(struct icalrestriction_property_record* rec,icalcomponent* comp,icalproperty* prop); typedef struct icalrestriction_property_record { icalproperty_method method; icalcomponent_kind component; icalproperty_kind property; icalrestriction_kind restriction; restriction_func function; } icalrestriction_property_record; typedef struct icalrestriction_component_record { icalproperty_method method; icalcomponent_kind component; icalcomponent_kind subcomponent; icalrestriction_kind restriction; restriction_func function; } icalrestriction_component_record; icalrestriction_property_record* icalrestriction_get_property_restriction(icalproperty_method method, icalcomponent_kind component, icalproperty_kind property); icalrestriction_component_record* icalrestriction_get_component_restriction(icalproperty_method method, icalcomponent_kind component, icalcomponent_kind subcomponent); icalrestriction_component_record icalrestriction_component_records[]; icalrestriction_property_record icalrestriction_property_records[]; icalrestriction_property_record null_prop_record = {ICAL_METHOD_NONE,ICAL_NO_COMPONENT,ICAL_NO_PROPERTY,ICAL_RESTRICTION_UNKNOWN,0}; icalrestriction_component_record null_comp_record = {ICAL_METHOD_NONE,ICAL_NO_COMPONENT,ICAL_NO_COMPONENT,ICAL_RESTRICTION_UNKNOWN,0}; -/* The each row gives the result of comparing a restriction against a +/** The each row gives the result of comparing a restriction against a count. The columns in each row represent 0,1,2+. '-1' indicates 'invalid, 'don't care' or 'needs more analysis' So, for ICAL_RESTRICTION_ONE, if there is 1 of a property with that restriction, it passes, but if there are 0 or 2+, it fails. */ char compare_map[ICAL_RESTRICTION_UNKNOWN+1][3] = { { 1, 1, 1},/*ICAL_RESTRICTION_NONE*/ { 1, 0, 0},/*ICAL_RESTRICTION_ZERO*/ { 0, 1, 0},/*ICAL_RESTRICTION_ONE*/ { 1, 1, 1},/*ICAL_RESTRICTION_ZEROPLUS*/ { 0, 1, 1},/*ICAL_RESTRICTION_ONEPLUS*/ { 1, 1, 0},/*ICAL_RESTRICTION_ZEROORONE*/ { 1, 1, 0},/*ICAL_RESTRICTION_ONEEXCLUSIVE*/ { 1, 1, 0},/*ICAL_RESTRICTION_ONEMUTUAL*/ { 1, 1, 1} /*ICAL_RESTRICTION_UNKNOWN*/ }; char restr_string_map[ICAL_RESTRICTION_UNKNOWN+1][60] = { "unknown number",/*ICAL_RESTRICTION_NONE*/ "0",/*ICAL_RESTRICTION_ZERO*/ "1",/*ICAL_RESTRICTION_ONE*/ "zero or more",/*ICAL_RESTRICTION_ZEROPLUS*/ "one or more" ,/*ICAL_RESTRICTION_ONEPLUS*/ "zero or one",/*ICAL_RESTRICTION_ZEROORONE*/ "zero or one, exclusive with another property",/*ICAL_RESTRICTION_ONEEXCLUSIVE*/ "zero or one, mutual with another property",/*ICAL_RESTRICTION_ONEMUTUAL*/ "unknown number" /*ICAL_RESTRICTION_UNKNOWN*/ }; int icalrestriction_compare(icalrestriction_kind restr, int count){ if ( restr < ICAL_RESTRICTION_NONE || restr > ICAL_RESTRICTION_UNKNOWN || count < 0){ return -1; } if (count > 2) { count = 2; } return compare_map[restr][count]; } /* Special case routines */ char* icalrestriction_may_be_draft_final_canceled( icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop) { icalproperty_status stat = icalproperty_get_status(prop); if( !( stat == ICAL_STATUS_DRAFT || stat == ICAL_STATUS_FINAL || stat == ICAL_STATUS_CANCELLED )){ return "Failed iTIP restrictions for STATUS property. Value must be one of DRAFT, FINAL, or CANCELED"; } return 0; } char* icalrestriction_may_be_comp_need_process( icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop) { icalproperty_status stat = icalproperty_get_status(prop); if( !( stat == ICAL_STATUS_COMPLETED || stat == ICAL_STATUS_NEEDSACTION || stat == ICAL_STATUS_INPROCESS )){ return "Failed iTIP restrictions for STATUS property. Value must be one of COMPLETED, NEEDS-ACTION or IN-PROCESS"; } return 0; } char* icalrestriction_may_be_tent_conf(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ icalproperty_status stat = icalproperty_get_status(prop); if( !( stat == ICAL_STATUS_TENTATIVE || stat == ICAL_STATUS_CONFIRMED )){ return "Failed iTIP restrictions for STATUS property. Value must be one of TENTATIVE or CONFIRMED"; } return 0; } char* icalrestriction_may_be_tent_conf_cancel( icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop) { icalproperty_status stat = icalproperty_get_status(prop); if( !( stat == ICAL_STATUS_TENTATIVE || stat == ICAL_STATUS_CONFIRMED || stat == ICAL_STATUS_CANCELLED )){ return "Failed iTIP restrictions for STATUS property. Value must be one of TENTATIVE, CONFIRMED or CANCELED"; } return 0; } char* icalrestriction_must_be_cancel_if_present( icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop) { /* This routine will not be called if prop == 0 */ icalproperty_status stat = icalproperty_get_status(prop); if( stat != ICAL_STATUS_CANCELLED) { return "Failed iTIP restrictions for STATUS property. Value must be CANCELLED"; } return 0; } char* icalrestriction_must_be_canceled_no_attendee( icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop) { /* Hack. see rfc2446, 3.2.5 CANCEL for porperty STATUS. I don't understand the note */ return 0; } char* icalrestriction_must_be_recurring(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ /* Hack */ return 0; } char* icalrestriction_must_have_duration(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ if( !icalcomponent_get_first_property(comp,ICAL_DURATION_PROPERTY)){ - return "Failed iTIP restrictions for STATUS property. This component must have a DURATION property"; + return "Failed iTIP restrictions. This component must have a DURATION property"; } return 0; } char* icalrestriction_must_have_repeat(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ if( !icalcomponent_get_first_property(comp,ICAL_REPEAT_PROPERTY)){ - return "Failed iTIP restrictions for STATUS property. This component must have a REPEAT property"; + return "Failed iTIP restrictions. This component must have a REPEAT property"; } return 0; } char* icalrestriction_must_if_tz_ref(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ /* Hack */ return 0; } char* icalrestriction_no_dtend(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ - if( !icalcomponent_get_first_property(comp,ICAL_DTEND_PROPERTY)){ + if( icalcomponent_get_first_property(comp,ICAL_DTEND_PROPERTY)){ - return "Failed iTIP restrictions for STATUS property. The component must not have both DURATION and DTEND"; + return "Failed iTIP restrictions. The component must not have both DURATION and DTEND"; } return 0; } char* icalrestriction_no_duration(icalrestriction_property_record *rec, icalcomponent* comp, icalproperty* prop){ /* _no_dtend takes care of this one */ return 0; } +char* icalrestriction_must_be_email( + icalrestriction_property_record *rec, + icalcomponent* comp, + icalproperty* prop) +{ + icalproperty_status stat = icalproperty_get_action(prop); + if( !( stat == ICAL_ACTION_EMAIL)){ + + return "Failed iTIP restrictions for ACTION property. Value must be EMAIL."; + + } + + return 0; +} int icalrestriction_check_component(icalproperty_method method, icalcomponent* comp) { icalproperty_kind kind; icalcomponent_kind comp_kind; icalrestriction_kind restr; - icalrestriction_property_record *prop_record = 0L; - icalrestriction_component_record *comp_record = 0L; + icalrestriction_property_record *prop_record; char* funcr = 0; icalproperty *prop; int count; int compare; int valid = 1; comp_kind = icalcomponent_isa(comp); /* Check all of the properties in this component */ for(kind = ICAL_ANY_PROPERTY+1; kind != ICAL_NO_PROPERTY; kind++){ count = icalcomponent_count_properties(comp, kind); prop_record = icalrestriction_get_property_restriction(method, comp_kind, kind); restr = prop_record->restriction; if(restr == ICAL_RESTRICTION_ONEEXCLUSIVE || restr == ICAL_RESTRICTION_ONEMUTUAL) { /* First treat is as a 0/1 restriction */ restr = ICAL_RESTRICTION_ZEROORONE; compare = icalrestriction_compare(restr,count); } else { compare = icalrestriction_compare(restr,count); } assert(compare != -1); if (compare == 0){ char temp[TMP_BUF_SIZE]; snprintf(temp, TMP_BUF_SIZE,"Failed iTIP restrictions for %s property. Expected %s instances of the property and got %d", icalenum_property_kind_to_string(kind), restr_string_map[restr], count); icalcomponent_add_property (comp, icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype(ICAL_XLICERRORTYPE_INVALIDITIP), 0)); } prop = icalcomponent_get_first_property(comp, kind); if (prop != 0 && prop_record->function !=0 ){ funcr = prop_record->function(prop_record,comp,prop); } if(funcr !=0){ icalcomponent_add_property (comp, icalproperty_vanew_xlicerror( funcr, icalparameter_new_xlicerrortype( ICAL_XLICERRORTYPE_INVALIDITIP), 0)); compare = 0; } valid = valid && compare; } return valid; } int icalrestriction_check(icalcomponent* outer_comp) { icalcomponent_kind comp_kind; icalproperty_method method; icalcomponent* inner_comp; icalproperty *method_prop; int valid; icalerror_check_arg_rz( (outer_comp!=0), "outer comp"); /* Get the Method value from the outer component */ comp_kind = icalcomponent_isa(outer_comp); if (comp_kind != ICAL_VCALENDAR_COMPONENT){ icalerror_set_errno(ICAL_BADARG_ERROR); return 0; } method_prop = icalcomponent_get_first_property(outer_comp, ICAL_METHOD_PROPERTY); if (method_prop == 0){ method = ICAL_METHOD_NONE; } else { method = icalproperty_get_method(method_prop); } /* Check the VCALENDAR wrapper */ valid = icalrestriction_check_component(ICAL_METHOD_NONE,outer_comp); /* Now check the inner components */ for(inner_comp= icalcomponent_get_first_component(outer_comp, ICAL_ANY_COMPONENT); inner_comp != 0; inner_comp= icalcomponent_get_next_component(outer_comp, ICAL_ANY_COMPONENT)){ valid = valid && icalrestriction_check_component(method,inner_comp); } return valid; } icalrestriction_property_record* icalrestriction_get_property_restriction(icalproperty_method method, icalcomponent_kind component, icalproperty_kind property) { int i; for(i = 0; icalrestriction_property_records[i].restriction != ICAL_RESTRICTION_NONE; i++){ if (method == icalrestriction_property_records[i].method && component == icalrestriction_property_records[i].component && property == icalrestriction_property_records[i].property ){ return &icalrestriction_property_records[i]; } } return &null_prop_record; } icalrestriction_component_record* icalrestriction_get_component_restriction(icalproperty_method method, icalcomponent_kind component, icalcomponent_kind subcomponent) { int i; for(i = 0; icalrestriction_component_records[i].restriction != ICAL_RESTRICTION_NONE; i++){ if (method == icalrestriction_component_records[i].method && component == icalrestriction_component_records[i].component && subcomponent == icalrestriction_component_records[i].subcomponent ){ return &icalrestriction_component_records[i]; } } return &null_comp_record; } /* Everything below this line is machine generated. Do not edit. */ icalrestriction_property_record icalrestriction_property_records[] = { {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, - {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, - {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, + {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_tent_conf_cancel}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_tent_conf}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, - {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, + {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_tent_conf}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,icalrestriction_must_be_recurring}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE ,icalrestriction_no_duration}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, - {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, + {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_canceled_no_attendee}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, - {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, + {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_tent_conf_cancel}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, - {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, - {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_comp_need_process}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_comp_need_process}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,icalrestriction_must_be_recurring}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_canceled_no_attendee}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_comp_need_process}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_may_be_draft_final_canceled}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS ,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_cancel_if_present}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_PUBLISH,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_PUBLISH,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_PUBLISH,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_PUBLISH,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REQUEST,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REQUEST,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REQUEST,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REQUEST,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REPLY,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REPLY,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REPLY,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REPLY,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_ADD,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_ADD,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_ADD,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_ADD,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_CANCEL,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_CANCEL,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_CANCEL,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_CANCEL,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REFRESH,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_REFRESH,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REFRESH,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_REFRESH,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_COUNTER,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_COUNTER,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_COUNTER,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_COUNTER,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_DECLINECOUNTER,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_ALLOWCONFLICT_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_CALMASTER_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_OWNER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_DEFAULTCHARSET_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_DEFAULTLOCALE_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VAGENDA_COMPONENT,ICAL_DEFAULTTZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_VCALENDAR_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, - {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_duration}, + {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,icalrestriction_no_dtend}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_NONE,ICAL_VEVENT_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_NONE,ICAL_VTODO_COMPONENT,ICAL_RELCALID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEEXCLUSIVE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_be_recurring}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VJOURNAL_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VFREEBUSY_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XSTANDARD_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDAYLIGHT_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_repeat}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_duration}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XAUDIOALARM_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_repeat}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_duration}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XDISPLAYALARM_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, - {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ONE,icalrestriction_must_be_email}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ONEPLUS,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_repeat}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_duration}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XEMAILALARM_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_ACTION_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_ATTACH_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_ATTENDEE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_CALSCALE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_CATEGORIES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_CLASS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_COMMENT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_COMPLETED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_CONTACT_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_CREATED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DESCRIPTION_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DTEND_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DTSTAMP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DTSTART_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DUE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_DURATION_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_repeat}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_REPEAT_PROPERTY,ICAL_RESTRICTION_ONEMUTUAL,icalrestriction_must_have_duration}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_EXDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_EXRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_FREEBUSY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_GEO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_LASTMODIFIED_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_LOCATION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_METHOD_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_ORGANIZER_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_PERCENTCOMPLETE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_PRIORITY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_PRODID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_RDATE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_RECURRENCEID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_RELATEDTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_REQUESTSTATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_RESOURCES_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_RRULE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_SEQUENCE_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_STATUS_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_SUMMARY_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TRANSP_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TRIGGER_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TZID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TZNAME_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TZOFFSETFROM_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TZOFFSETTO_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_TZURL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_UID_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_URL_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_VERSION_PROPERTY,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_NONE,ICAL_XPROCEDUREALARM_COMPONENT,ICAL_X_PROPERTY,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_NONE,ICAL_VQUERY_COMPONENT,ICAL_QUERY_PROPERTY,ICAL_RESTRICTION_ZEROORONE,0}, + {ICAL_METHOD_NONE,ICAL_VQUERY_COMPONENT,ICAL_QUERYNAME_PROPERTY,ICAL_RESTRICTION_ONE,0}, + {ICAL_METHOD_NONE,ICAL_VQUERY_COMPONENT,ICAL_EXPAND_PROPERTY,ICAL_RESTRICTION_ONE,0}, {ICAL_METHOD_NONE,ICAL_NO_COMPONENT,ICAL_NO_PROPERTY,ICAL_RESTRICTION_NONE} }; icalrestriction_component_record icalrestriction_component_records[] = { {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_PUBLISH,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROORONE,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_REFRESH,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_COUNTER,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VEVENT_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,icalrestriction_must_if_tz_ref}, {ICAL_METHOD_PUBLISH,ICAL_VFREEBUSY_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VFREEBUSY_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VFREEBUSY_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VTODO_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REQUEST,ICAL_VTODO_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REPLY,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_VJOURNAL_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_REFRESH,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_COUNTER,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_DECLINECOUNTER,ICAL_VTODO_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_PUBLISH,ICAL_VJOURNAL_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROORONE,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_ADD,ICAL_VJOURNAL_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_VTIMEZONE_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_X_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_VALARM_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_VEVENT_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_VFREEBUSY_COMPONENT,ICAL_RESTRICTION_ZERO,0}, {ICAL_METHOD_CANCEL,ICAL_VJOURNAL_COMPONENT,ICAL_VTODO_COMPONENT,ICAL_RESTRICTION_ZERO,0}, + {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_XSTANDARD_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, + {ICAL_METHOD_NONE,ICAL_VTIMEZONE_COMPONENT,ICAL_XDAYLIGHT_COMPONENT,ICAL_RESTRICTION_ZEROPLUS,0}, {ICAL_METHOD_NONE,ICAL_NO_COMPONENT,ICAL_NO_COMPONENT,ICAL_RESTRICTION_NONE} }; diff --git a/libical/src/libical/icaltime.c b/libical/src/libical/icaltime.c index a04ca04..3aac74e 100644 --- a/libical/src/libical/icaltime.c +++ b/libical/src/libical/icaltime.c @@ -1,577 +1,1015 @@ /* -*- 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> +#include "config.h" #endif #include "icaltime.h" #include <assert.h> #include <string.h> #include <stdlib.h> #include <stdio.h> +#include <time.h> -int snprintf(char *str, size_t n, char const *fmt, ...); +#include "astime.h" /* Julian data handling routines */ -#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" + +#include "icaltimezone.h" +#include "icalvalue.h" + +#ifdef WIN32 +#include <Windows.h> +#define ERROR error +#define snprintf _snprintf +#define strcasecmp stricmp #endif +/* + * Function to convert a struct tm time specification + * to an ANSI time_t using the specified time zone. + * This is different from the standard mktime() function + * in that we dont want the automatic adjustments for + * local daylight savings time applied to the result. + * This function expects well-formed input. + */ +static time_t make_time(struct tm *tm, int tzm) +{ + time_t tim; + static int days[] = { -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364 }; + /* check that year specification within range */ -struct icaltimetype -icaltime_from_timet(time_t tm, int is_date) -{ - struct icaltimetype tt = icaltime_null_time(); - struct tm t; + if (tm->tm_year < 70 || tm->tm_year > 138) + return((time_t) -1); - t = *(gmtime(&tm)); - - if(is_date == 0){ - tt.second = t.tm_sec; - tt.minute = t.tm_min; - tt.hour = t.tm_hour; - } else { - tt.second = tt.minute =tt.hour = 0 ; - } + /* check that month specification within range */ - tt.day = t.tm_mday; - tt.month = t.tm_mon + 1; - tt.year = t.tm_year+ 1900; - - tt.is_utc = 1; - tt.is_date = is_date; + if (tm->tm_mon < 0 || tm->tm_mon > 11) + return((time_t) -1); - return tt; -} + /* check for upper bound of Jan 17, 2038 (to avoid possibility of + 32-bit arithmetic overflow) */ + + if (tm->tm_year == 138) { + if (tm->tm_mon > 0) + return((time_t) -1); + else if (tm->tm_mday > 17) + return((time_t) -1); + } -/* Structure used by set_tz to hold an old value of TZ, and the new - value, which is in memory we will have to free in unset_tz */ -struct set_tz_save {char* orig_tzid; char* new_env_str;}; + /* + * calculate elapsed days since start of the epoch (midnight Jan + * 1st, 1970 UTC) 17 = number of leap years between 1900 and 1970 + * (number of leap days to subtract) + */ -/* Temporarily change the TZ environmental variable. */ -struct set_tz_save set_tz(const char* tzid) -{ + tim = (tm->tm_year - 70) * 365 + ((tm->tm_year - 1) / 4) - 17; - char *orig_tzid = 0; - char *new_env_str; - struct set_tz_save savetz; - size_t tmp_sz; + /* add number of days elapsed in the current year */ - savetz.orig_tzid = 0; - savetz.new_env_str = 0; + tim += days[tm->tm_mon]; - if(getenv("TZ") != 0){ - orig_tzid = (char*)icalmemory_strdup(getenv("TZ")); + /* check and adjust for leap years (the leap year check only valid + during the 32-bit era */ - if(orig_tzid == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return savetz; - } - } + if ((tm->tm_year & 3) == 0 && tm->tm_mon > 1) + tim += 1; - tmp_sz =strlen(tzid)+4; - new_env_str = (char*)malloc(tmp_sz); + /* elapsed days to current date */ - if(new_env_str == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return savetz; - } - - /* Copy the TZid into a string with the form that putenv expects. */ - strcpy(new_env_str,"TZ="); - strcpy(new_env_str+3,tzid); + tim += tm->tm_mday; - putenv(new_env_str); - /* Old value of TZ and the string we will have to free later */ - savetz.orig_tzid = orig_tzid; - savetz.new_env_str = new_env_str; - return savetz; + /* calculate elapsed hours since start of the epoch */ + + tim = tim * 24 + tm->tm_hour; + + /* calculate elapsed minutes since start of the epoch */ + + tim = tim * 60 + tm->tm_min; + + /* adjust per time zone specification */ + + tim -= tzm; + + /* calculate elapsed seconds since start of the epoch */ + + tim = tim * 60 + tm->tm_sec; + + /* return number of seconds since start of the epoch */ + + return(tim); } -void unset_tz(struct set_tz_save savetz) +/** @brief Constructor (deprecated). + * + * Convert seconds past UNIX epoch to a timetype. + * + * @deprecated This constructor is deprecated and shouldn't be used in + * new software. Use icaltime_from_timet_with_zone(time_t, int, + * icaltimezone *) instead. In the meantime, calls to this method + * return a floating time, which can always be converted to a local + * time with an appropriate call to icaltime_convert_to_zone(). + */ + +struct icaltimetype +icaltime_from_timet(const time_t tm, const int is_date) { - /* restore the original TZ environment */ +#ifndef NO_WARN_DEPRECATED + icalerror_warn("icaltime_from_timet() is DEPRECATED, use icaltime_from_timet_with_zone() instead"); +#endif - char* orig_tzid = savetz.orig_tzid; + return icaltime_from_timet_with_zone(tm, is_date, 0); +} - if(orig_tzid!=0){ - size_t tmp_sz =strlen(orig_tzid)+4; - char* orig_env_str = (char*)icalmemory_tmp_buffer(tmp_sz); - if(orig_env_str == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return; - } - - strcpy(orig_env_str,"TZ="); - strcpy(orig_env_str+3,orig_tzid); -#ifndef _WIN32 - setenv("TZ", savetz.orig_tzid,1 ); -#else - putenv("TZ=MEZ");//, savetz.orig_tzid ); -#endif - free(orig_tzid); - } else { -#ifdef __FreeBSD__ - unsetenv("TZ"); +/** @brief Constructor. + * + * @param tm The time + * @param is_date Boolean: 1 means we should treat tm as a DATE + * @param zone The timezone tm is in, NULL means to treat tm as a + * floating time + * + * Return a new icaltime instance, initialized to the given time + * expressed as seconds past UNIX epoch, optionally using the given + * timezone. + * + * If the caller specifies the is_date param as TRUE, the returned + * object is of DATE type, otherwise the input is meant to be of + * DATE-TIME type. + * If the zone is not specified (NULL zone param) the time is taken + * to be floating, that is, valid in any timezone. Note that, in + * addition to the uses specified in [RFC2445], this can be used + * when doing simple math on couples of times. + * If the zone is specified (UTC or otherwise), it's stored in the + * object and it's used as the native timezone for this object. + * This means that the caller can convert this time to a different + * target timezone with no need to store the source timezone. + * + */ +struct icaltimetype +icaltime_from_timet_with_zone(const time_t tm, const int is_date, + const icaltimezone *zone) +{ + struct icaltimetype tt = icaltime_null_time(); + struct tm t; + icaltimezone *utc_zone; + + /* Convert the time_t to a struct tm. We can trust gmtime for this. */ +#ifdef HAVE_GMTIME_R + gmtime_r(&tm, &t); #else - putenv("TZ"); /* Delete from environment */ + { + struct tm *t_ptr = gmtime(&tm); + t = *t_ptr; + } #endif - } - if(savetz.new_env_str != 0){ - free(savetz.new_env_str); + tt.year = t.tm_year + 1900; + tt.month = t.tm_mon + 1; + tt.day = t.tm_mday; + + if (is_date) { + tt.is_date = 1; + return tt; } + + tt.hour = t.tm_hour; + tt.minute = t.tm_min; + tt.second = t.tm_sec; + + /* If it's a floating time, we don't do any conversion. */ + if (zone == NULL) { + return tt; + } + + utc_zone = icaltimezone_get_utc_timezone (); + tt.is_utc = (zone == utc_zone) ? 1 : 0; + tt.zone = zone; + + return tt; } +/** @brief Convenience constructor. + * + * Returns the current time in the given timezone, as an icaltimetype. + */ +struct icaltimetype icaltime_current_time_with_zone(const icaltimezone *zone) +{ + return icaltime_from_timet_with_zone (time (NULL), 0, zone); +} -time_t icaltime_as_timet(struct icaltimetype tt) +/** @brief Convenience constructor. + * + * Returns the current day as an icaltimetype, with is_date set. + */ +struct icaltimetype icaltime_today(void) +{ + return icaltime_from_timet_with_zone (time (NULL), 1, NULL); +} + +/** @brief Return the time as seconds past the UNIX epoch + */ +time_t icaltime_as_timet(const struct icaltimetype tt) { struct tm stm; time_t t; - memset(&stm,0,sizeof( struct tm)); - - if(icaltime_is_null_time(tt)) { + /* If the time is the special null time, return 0. */ + if (icaltime_is_null_time(tt)) { return 0; } + /* Copy the icaltimetype to a struct tm. */ + memset (&stm, 0, sizeof (struct tm)); + stm.tm_sec = tt.second; stm.tm_min = tt.minute; stm.tm_hour = tt.hour; stm.tm_mday = tt.day; stm.tm_mon = tt.month-1; stm.tm_year = tt.year-1900; stm.tm_isdst = -1; - if(tt.is_utc == 1 || tt.is_date == 1){ - struct set_tz_save old_tz = set_tz("UTC"); - t = mktime(&stm); - unset_tz(old_tz); - } else { - t = mktime(&stm); - } + t = make_time(&stm, 0); return t; } -char* icaltime_as_ical_string(struct icaltimetype tt) +/** @brief Return the time as seconds past the UNIX epoch, using the + * given timezone. + * + * This convenience method combines a call to icaltime_convert() with + * a call to icaltime_as_timet(). + * If the input timezone is null, no conversion is done; that is, the + * time is simply returned as time_t in its native timezone. + */ +time_t icaltime_as_timet_with_zone(const struct icaltimetype _tt, + const icaltimezone *zone) +{ + struct icaltimetype tt = _tt; + struct tm stm; + time_t t; + + /* If the time is the special null time, return 0. */ + if (icaltime_is_null_time(tt)) { + return 0; + } + + if (zone != NULL) { + tt = icaltime_convert_to_zone(_tt, zone); + } + + /* Copy the icaltimetype to a struct tm. */ + memset (&stm, 0, sizeof (struct tm)); + + stm.tm_sec = tt.second; + stm.tm_min = tt.minute; + stm.tm_hour = tt.hour; + stm.tm_mday = tt.day; + stm.tm_mon = tt.month-1; + stm.tm_year = tt.year-1900; + stm.tm_isdst = -1; + + t = make_time(&stm, 0); + + return t; +} + +/** + * Return a string represention of the time, in RFC2445 format. The + * string is owned by libical + */ +const char* icaltime_as_ical_string(const struct icaltimetype tt) { size_t size = 17; char* buf = icalmemory_new_buffer(size); if(tt.is_date){ snprintf(buf, size,"%04d%02d%02d",tt.year,tt.month,tt.day); } else { char* fmt; if(tt.is_utc){ fmt = "%04d%02d%02dT%02d%02d%02dZ"; } else { fmt = "%04d%02d%02dT%02d%02d%02d"; } snprintf(buf, size,fmt,tt.year,tt.month,tt.day, tt.hour,tt.minute,tt.second); } icalmemory_add_tmp_buffer(buf); return buf; } - -/* convert tt, of timezone tzid, into a utc time */ -struct icaltimetype icaltime_as_utc(struct icaltimetype tt,const char* tzid) -{ - int tzid_offset; - - if(tt.is_utc == 1 || tt.is_date == 1){ - return tt; - } - - tzid_offset = icaltime_utc_offset(tt,tzid); - - tt.second -= tzid_offset; - - tt.is_utc = 1; - - return icaltime_normalize(tt); -} - -/* convert tt, a time in UTC, into a time in timezone tzid */ -struct icaltimetype icaltime_as_zone(struct icaltimetype tt,const char* tzid) +/** + * Reset all of the time components to be in their normal ranges. For + * instance, given a time with minutes=70, the minutes will be reduces + * to 10, and the hour incremented. This allows the caller to do + * arithmetic on times without worrying about overflow or + * underflow. + * + * Implementation note: we call icaltime_adjust() with no adjustment. + */ +struct icaltimetype icaltime_normalize(const struct icaltimetype tt) { - int tzid_offset; - - tzid_offset = icaltime_utc_offset(tt,tzid); - - tt.second += tzid_offset; - - tt.is_utc = 0; - - return icaltime_normalize(tt); - -} - - -/* Return the offset of the named zone as seconds. tt is a time - indicating the date for which you want the offset */ -int icaltime_utc_offset(struct icaltimetype ictt, const char* tzid) -{ - - time_t tt = icaltime_as_timet(ictt); - time_t offset_tt; - struct tm gtm; - struct set_tz_save old_tz; - - if(tzid != 0){ - old_tz = set_tz(tzid); - } - - /* Mis-interpret a UTC broken out time as local time */ - gtm = *(gmtime(&tt)); - gtm.tm_isdst = localtime(&tt)->tm_isdst; - offset_tt = mktime(>m); - - if(tzid != 0){ - unset_tz(old_tz); - } - - return tt-offset_tt; -} - - - -/* Normalize by converting from localtime to utc and back to local - time. This uses localtime because localtime and mktime are inverses - of each other */ - -struct icaltimetype icaltime_normalize(struct icaltimetype tt) -{ - struct tm stm; - time_t tut; - - memset(&stm,0,sizeof( struct tm)); - - stm.tm_sec = tt.second; - stm.tm_min = tt.minute; - stm.tm_hour = tt.hour; - stm.tm_mday = tt.day; - stm.tm_mon = tt.month-1; - stm.tm_year = tt.year-1900; - stm.tm_isdst = -1; /* prevents mktime from changing hour based on - daylight savings */ - - tut = mktime(&stm); - - stm = *(localtime(&tut)); - - tt.second = stm.tm_sec; - tt.minute = stm.tm_min; - tt.hour = stm.tm_hour; - tt.day = stm.tm_mday; - tt.month = stm.tm_mon +1; - tt.year = stm.tm_year+1900; - - return tt; + struct icaltimetype ret = tt; + icaltime_adjust(&ret, 0, 0, 0, 0); + return ret; } -#ifndef ICAL_NO_LIBICAL -#include "icalvalue.h" +/** @brief Contructor. + * + * Create a time from an ISO format string. + * + * @todo If the given string specifies a DATE-TIME not in UTC, there + * is no way to know if this is a floating time or really refers to a + * timezone. We should probably add a new constructor: + * icaltime_from_string_with_zone() + */ struct icaltimetype icaltime_from_string(const char* str) { struct icaltimetype tt = icaltime_null_time(); int size; icalerror_check_arg_re(str!=0,"str",icaltime_null_time()); size = strlen(str); if(size == 15) { /* floating time */ tt.is_utc = 0; tt.is_date = 0; } else if (size == 16) { /* UTC time, ends in 'Z'*/ + if(str[15] != 'Z') + goto ERROR; + tt.is_utc = 1; + tt.zone = icaltimezone_get_utc_timezone(); tt.is_date = 0; - - if(str[15] != 'Z'){ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return icaltime_null_time(); - } - } else if (size == 8) { /* A DATE */ tt.is_utc = 1; tt.is_date = 1; } else { /* error */ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return icaltime_null_time(); + goto ERROR; } if(tt.is_date == 1){ - sscanf(str,"%04d%02d%02d",&tt.year,&tt.month,&tt.day); + if (sscanf(str,"%04d%02d%02d",&tt.year,&tt.month,&tt.day) < 3) + goto ERROR; } else { char tsep; - sscanf(str,"%04d%02d%02d%c%02d%02d%02d",&tt.year,&tt.month,&tt.day, - &tsep,&tt.hour,&tt.minute,&tt.second); - - if(tsep != 'T'){ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return icaltime_null_time(); - } + if (sscanf(str,"%04d%02d%02d%c%02d%02d%02d",&tt.year,&tt.month,&tt.day, + &tsep,&tt.hour,&tt.minute,&tt.second) < 7) + goto ERROR; + if(tsep != 'T') + goto ERROR; } return tt; + +ERROR: + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return icaltime_null_time(); } -#endif -char ctime_str[20]; -char* icaltime_as_ctime(struct icaltimetype t) -{ - time_t tt; - - tt = icaltime_as_timet(t); - sprintf(ctime_str,"%s",ctime(&tt)); - ctime_str[strlen(ctime_str)-1] = 0; +/* Returns whether the specified year is a leap year. Year is the normal year, + e.g. 2001. */ +int +icaltime_is_leap_year (const int year) +{ - return ctime_str; + if (year <= 1752) + return (year % 4 == 0); + else + return ( (year % 4==0) && (year % 100 !=0 )) || (year % 400 == 0); } +static int _days_in_month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; -short days_in_month[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; - -short icaltime_days_in_month(short month,short year) +int icaltime_days_in_month(const int month, const int year) { - int is_leap =0; - int days = days_in_month[month]; + int days = _days_in_month[month]; assert(month > 0); assert(month <= 12); - if( (year % 4 == 0 && year % 100 != 0) || - year % 400 == 0){ - is_leap =1; - } - if( month == 2){ - days += is_leap; + days += icaltime_is_leap_year(year); } return days; } /* 1-> Sunday, 7->Saturday */ -short icaltime_day_of_week(struct icaltimetype t){ +int icaltime_day_of_week(const struct icaltimetype t){ + UTinstant jt; - time_t tt = icaltime_as_timet(t); - struct tm *tm; + memset(&jt,0,sizeof(UTinstant)); - if(t.is_utc == 1 || t.is_date == 1){ - tm = gmtime(&tt); - } else { - tm = localtime(&tt); - } + jt.year = t.year; + jt.month = t.month; + jt.day = t.day; + jt.i_hour = 0; + jt.i_minute = 0; + jt.i_second = 0; + + juldat(&jt); - return tm->tm_wday+1; + return jt.weekday + 1; } -/* Day of the year that the first day of the week (Sunday) is on */ -short icaltime_start_doy_of_week(struct icaltimetype t){ - time_t tt = icaltime_as_timet(t); - time_t start_tt; - struct tm *stm; - int syear; +/** Day of the year that the first day of the week (Sunday) is on. + * + * @todo Doesn't take into account different week start days. + */ +int icaltime_start_doy_of_week(const struct icaltimetype t){ + UTinstant jt; - stm = gmtime(&tt); - syear = stm->tm_year; + memset(&jt,0,sizeof(UTinstant)); - start_tt = tt - stm->tm_wday*(60*60*24); + jt.year = t.year; + jt.month = t.month; + jt.day = t.day; + jt.i_hour = 0; + jt.i_minute = 0; + jt.i_second = 0; - stm = gmtime(&start_tt); - - if(syear == stm->tm_year){ - return stm->tm_yday+1; - } else { - /* return negative to indicate that start of week is in - previous year. */ - int is_leap = 0; - int year = stm->tm_year; - - if( (year % 4 == 0 && year % 100 != 0) || - year % 400 == 0){ - is_leap =1; - } + juldat(&jt); + caldat(&jt); - return (stm->tm_yday+1)-(365+is_leap); - } - + return jt.day_of_year - jt.weekday; } -short icaltime_week_number(struct icaltimetype ictt) +/** + * @todo Doesn't take into account the start day of the + * week. strftime assumes that weeks start on Monday. + */ +int icaltime_week_number(const struct icaltimetype ictt) { - char str[5]; - time_t t = icaltime_as_timet(ictt); - int week_no; + UTinstant jt; - strftime(str,5,"%V", gmtime(&t)); + memset(&jt,0,sizeof(UTinstant)); - week_no = atoi(str); + jt.year = ictt.year; + jt.month = ictt.month; + jt.day = ictt.day; + jt.i_hour = 0; + jt.i_minute = 0; + jt.i_second = 0; - return week_no; + juldat(&jt); + caldat(&jt); + return (jt.day_of_year - jt.weekday) / 7; } +/* The first array is for non-leap years, the second for leap years*/ +static const int days_in_year[2][13] = +{ /* jan feb mar apr may jun jul aug sep oct nov dec */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; -short icaltime_day_of_year(struct icaltimetype t){ - time_t tt; - struct tm *stm; - struct set_tz_save old_tz; - - tt = icaltime_as_timet(t); +/** + * Returns the day of the year, counting from 1 (Jan 1st). + */ +int icaltime_day_of_year(const struct icaltimetype t){ + int is_leap = icaltime_is_leap_year (t.year); - old_tz = set_tz("UTC"); - stm = localtime(&tt); - unset_tz(old_tz); - - return stm->tm_yday+1; - + return days_in_year[is_leap][t.month - 1] + t.day; } +/** @brief Contructor. + * + * Create a new time, given a day of year and a year. + */ /* Jan 1 is day #1, not 0 */ -struct icaltimetype icaltime_from_day_of_year(short doy, short year) +struct icaltimetype icaltime_from_day_of_year(const int _doy, const int _year) { - struct tm stm; - time_t tt; - struct set_tz_save old_tz; - - /* Get the time of january 1 of this year*/ - memset(&stm,0,sizeof(struct tm)); - stm.tm_year = year-1900; - stm.tm_mday = 1; + struct icaltimetype tt = icaltime_null_date(); + int is_leap; + int month; + int doy = _doy; + int year = _year; + + is_leap = icaltime_is_leap_year(year); + + /* Zero and neg numbers represent days of the previous year */ + if(doy <1){ + year--; + is_leap = icaltime_is_leap_year(year); + doy += days_in_year[is_leap][12]; + } else if(doy > days_in_year[is_leap][12]){ + /* Move on to the next year*/ + is_leap = icaltime_is_leap_year(year); + doy -= days_in_year[is_leap][12]; + year++; + } - old_tz = set_tz("UTC"); - tt = mktime(&stm); - unset_tz(old_tz); + tt.year = year; + for (month = 11; month >= 0; month--) { + if (doy > days_in_year[is_leap][month]) { + tt.month = month + 1; + tt.day = doy - days_in_year[is_leap][month]; + break; + } + } - /* Now add in the days */ + return tt; +} - doy--; - tt += doy *60*60*24; +/** @brief Constructor. + * + * Return a null time, which indicates no time has been set. + * This time represents the beginning of the epoch. + */ +struct icaltimetype icaltime_null_time(void) +{ + struct icaltimetype t; + memset(&t,0,sizeof(struct icaltimetype)); - return icaltime_from_timet(tt, 1); + return t; } -struct icaltimetype icaltime_null_time() +/** @brief Constructor. + * + * Return a null date, which indicates no time has been set. + */ +struct icaltimetype icaltime_null_date(void) { struct icaltimetype t; memset(&t,0,sizeof(struct icaltimetype)); + t.is_date = 1; + + /* + * Init to -1 to match what icalyacc.y used to do. + * Does anything depend on this? + */ + t.hour = -1; + t.minute = -1; + t.second = -1; + return t; } -int icaltime_is_valid_time(struct icaltimetype t){ +/** + * Returns false if the time is clearly invalid, but is not null. This + * is usually the result of creating a new time type buy not clearing + * it, or setting one of the flags to an illegal value. + */ +int icaltime_is_valid_time(const struct icaltimetype t){ if(t.is_utc > 1 || t.is_utc < 0 || t.year < 0 || t.year > 3000 || t.is_date > 1 || t.is_date < 0){ return 0; } else { return 1; } } -int icaltime_is_null_time(struct icaltimetype t) +/** @brief Returns true if time is a DATE + */ +int icaltime_is_date(const struct icaltimetype t) { + + return t.is_date; +} + +/** @brief Returns true if time is relative to UTC zone + * + * @todo We should only check the zone + */ +int icaltime_is_utc(const struct icaltimetype t) { + + return t.is_utc; +} + +/** + * Return true if the time is null. + */ +int icaltime_is_null_time(const struct icaltimetype t) { if (t.second +t.minute+t.hour+t.day+t.month+t.year == 0){ return 1; } return 0; } -int icaltime_compare(struct icaltimetype a,struct icaltimetype b) -{ - time_t t1 = icaltime_as_timet(a); - time_t t2 = icaltime_as_timet(b); - - if (t1 > t2) { - return 1; - } else if (t1 < t2) { - return -1; - } else { - return 0; - } +/** + * Return -1, 0, or 1 to indicate that a<b, a==b, or a>b. + * This calls icaltime_compare function after converting them to the utc + * timezone. + */ +int icaltime_compare(const struct icaltimetype a_in, const struct icaltimetype b_in) +{ + int retval = 0; + struct icaltimetype a, b; + + a = icaltime_convert_to_zone(a_in, icaltimezone_get_utc_timezone()); + b = icaltime_convert_to_zone(b_in, icaltimezone_get_utc_timezone()); + + if (a.year > b.year) + retval = 1; + else if (a.year < b.year) + retval = -1; + + else if (a.month > b.month) + retval = 1; + else if (a.month < b.month) + retval = -1; + + else if (a.day > b.day) + retval = 1; + else if (a.day < b.day) + retval = -1; + + /* if both are dates, we are done */ + if (a.is_date && b.is_date) + return retval; + + /* else, if we already found a difference, we are done */ + else if (retval != 0) + return retval; + + /* else, if only one is a date (and we already know the date part is equal), + then the other is greater */ + else if (b.is_date) + retval = 1; + else if (a.is_date) + retval = -1; + + else if (a.hour > b.hour) + retval = 1; + else if (a.hour < b.hour) + retval = -1; + + else if (a.minute > b.minute) + retval = 1; + else if (a.minute < b.minute) + retval = -1; + + else if (a.second > b.second) + retval = 1; + else if (a.second < b.second) + retval = -1; + + return retval; } +/** + * like icaltime_compare, but only use the date parts. + */ + int -icaltime_compare_date_only (struct icaltimetype a, struct icaltimetype b) +icaltime_compare_date_only(const struct icaltimetype a_in, const struct icaltimetype b_in) { - time_t t1; - time_t t2; - - if (a.year == b.year && a.month == b.month && a.day == b.day) - return 0; - - t1 = icaltime_as_timet (a); - t2 = icaltime_as_timet (b); - - if (t1 > t2) - return 1; - else if (t1 < t2) - return -1; - else { - /* not reached */ - assert (0); - return 0; - } -} + int retval; + struct icaltimetype a, b; + + a = icaltime_convert_to_zone(a_in, icaltimezone_get_utc_timezone()); + b = icaltime_convert_to_zone(b_in, icaltimezone_get_utc_timezone()); + + if (a.year > b.year) + retval = 1; + else if (a.year < b.year) + retval = -1; + + else if (a.month > b.month) + retval = 1; + else if (a.month < b.month) + retval = -1; + + else if (a.day > b.day) + retval = 1; + else if (a.day < b.day) + retval = -1; + else + retval = 0; + + return retval; +} /* These are defined in icalduration.c: struct icaltimetype icaltime_add(struct icaltimetype t, struct icaldurationtype d) struct icaldurationtype icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2) */ + + +/** @brief Internal, shouldn't be part of the public API + * + * Adds (or subtracts) a time from a icaltimetype. + * NOTE: This function is exactly the same as icaltimezone_adjust_change() + * except for the type of the first parameter. + */ +void +icaltime_adjust(struct icaltimetype *tt, const int days, const int hours, + const int minutes, const int seconds) { + + int second, minute, hour, day; + int minutes_overflow, hours_overflow, days_overflow, years_overflow; + int days_in_month; + + /* Add on the seconds. */ + second = tt->second + seconds; + tt->second = second % 60; + minutes_overflow = second / 60; + if (tt->second < 0) { + tt->second += 60; + minutes_overflow--; + } + + /* Add on the minutes. */ + minute = tt->minute + minutes + minutes_overflow; + tt->minute = minute % 60; + hours_overflow = minute / 60; + if (tt->minute < 0) { + tt->minute += 60; + hours_overflow--; + } + + /* Add on the hours. */ + hour = tt->hour + hours + hours_overflow; + tt->hour = hour % 24; + days_overflow = hour / 24; + if (tt->hour < 0) { + tt->hour += 24; + days_overflow--; + } + + /* Normalize the month. We do this before handling the day since we may + need to know what month it is to get the number of days in it. + Note that months are 1 to 12, so we have to be a bit careful. */ + if (tt->month >= 13) { + years_overflow = (tt->month - 1) / 12; + tt->year += years_overflow; + tt->month -= years_overflow * 12; + } else if (tt->month <= 0) { + /* 0 to -11 is -1 year out, -12 to -23 is -2 years. */ + years_overflow = (tt->month / 12) - 1; + tt->year += years_overflow; + tt->month -= years_overflow * 12; + } + + /* Add on the days. */ + day = tt->day + days + days_overflow; + if (day > 0) { + for (;;) { + days_in_month = icaltime_days_in_month (tt->month, tt->year); + if (day <= days_in_month) + break; + + tt->month++; + if (tt->month >= 13) { + tt->year++; + tt->month = 1; + } + + day -= days_in_month; + } + } else { + while (day <= 0) { + if (tt->month == 1) { + tt->year--; + tt->month = 12; + } else { + tt->month--; + } + + day += icaltime_days_in_month (tt->month, tt->year); + } + } + tt->day = day; +} + +/** @brief Convert time to a given timezone + * + * Convert a time from its native timezone to a given timezone. + * + * If tt is a date, the returned time is an exact + * copy of the input. If it's a floating time, the returned object + * represents the same time translated to the given timezone. + * Otherwise the time will be converted to the new + * time zone, and its native timezone set to the right timezone. + */ +struct icaltimetype icaltime_convert_to_zone(const struct icaltimetype tt, + icaltimezone *zone) { + + struct icaltimetype ret = tt; + + /* If it's a date do nothing */ + if (tt.is_date) { + return ret; + } + + if (tt.zone == zone) { + return ret; + } + + /* If it's a floating time we don't want to adjust the time */ + if (tt.zone != NULL) { + icaltimezone_convert_time(&ret, tt.zone, zone); + } + + ret.zone = zone; + if (zone == icaltimezone_get_utc_timezone()) { + ret.is_utc = 1; + } else { + ret.is_utc = 0; + } + + return ret; +} + +const icaltimezone * +icaltime_get_timezone(const struct icaltimetype t) { + + return t.zone; +} + +char * +icaltime_get_tzid(const struct icaltimetype t) { + + if (t.zone != NULL) { + return icaltimezone_get_tzid(t.zone); + } else { + return NULL; + } +} + +/** @brief Set the timezone + * + * Force the icaltime to be interpreted relative to another timezone. + * If you need to do timezone conversion, applying offset adjustments, + * then you should use icaltime_convert_to_timezone instead. + */ +struct icaltimetype +icaltime_set_timezone(struct icaltimetype *t, const icaltimezone *zone) { + + /* If it's a date do nothing */ + if (t->is_date) { + return *t; + } + + if (t->zone == zone) { + return *t; + } + + t->zone = zone; + if (zone == icaltimezone_get_utc_timezone()) { + t->is_utc = 1; + } else { + t->is_utc = 0; + } + + return *t; +} + + +/** + * @brief builds an icaltimespan given a start time, end time and busy value. + * + * @param dtstart The beginning time of the span, can be a date-time + * or just a date. + * @param dtend The end time of the span. + * @param is_busy A boolean value, 0/1. + * @return A span using the supplied values. + * + * returned span contains times specified in UTC. + */ + +icaltime_span icaltime_span_new(struct icaltimetype dtstart, + struct icaltimetype dtend, + int is_busy) +{ + icaltime_span span; + + span.is_busy = is_busy; + + span.start = icaltime_as_timet_with_zone(dtstart, + icaltimezone_get_utc_timezone()); + + if (icaltime_is_null_time(dtend)) { + if (!icaltime_is_date(dtstart)) { + /* If dtstart is a DATE-TIME and there is no DTEND nor DURATION + it takes no time */ + span.end = span.start; + return span; + } else { + dtend = dtstart; + } + } + + span.end = icaltime_as_timet_with_zone(dtend, icaltimezone_get_utc_timezone()); + + if (icaltime_is_date(dtstart)) { + /* no time specified, go until the end of the day..*/ + span.end += 60*60*24 - 1; + } + return span; +} + + +/** @brief Returns true if the two spans overlap + * + * @param s1 1st span to test + * @param s2 2nd span to test + * @return boolean value + * + * The result is calculated by testing if the start time of s1 is contained + * by the s2 span, or if the end time of s1 is contained by the s2 span. + * + * Also returns true if the spans are equal. + * + * Note, this will return false if the spans are adjacent. + */ + +int icaltime_span_overlaps(icaltime_span *s1, + icaltime_span *s2) +{ + /* s1->start in s2 */ + if (s1->start > s2->start && s1->start < s2->end) + return 1; + + /* s1->end in s2 */ + if (s1->end > s2->start && s1->end < s2->end) + return 1; + + /* s2->start in s1 */ + if (s2->start > s1->start && s2->start < s1->end) + return 1; + + /* s2->end in s1 */ + if (s2->end > s1->start && s2->end < s1->end) + return 1; + + if (s1->start == s2->start && s1->end == s2->end) + return 1; + + return 0; +} + +/** @brief Returns true if the span is totally within the containing + * span + * + * @param s The span to test for. + * @param container The span to test against. + * @return boolean value. + * + */ + +int icaltime_span_contains(icaltime_span *s, + icaltime_span *container) +{ + + if ((s->start >= container->start && s->start < container->end) && + (s->end <= container->end && s->end > container->start)) + return 1; + + return 0; +} diff --git a/libical/src/libical/icaltime.h b/libical/src/libical/icaltime.h index 0f0379b..ce1696a 100644 --- a/libical/src/libical/icaltime.h +++ b/libical/src/libical/icaltime.h @@ -1,145 +1,273 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icaltime.h 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 ======================================================================*/ +/** @file icaltime.h + * @brief struct icaltimetype is a pseudo-object that abstracts time + * handling. + * + * It can represent either a DATE or a DATE-TIME (floating, UTC or in a + * given timezone), and it keeps track internally of its native timezone. + * + * The typical usage is to call the correct constructor specifying the + * desired timezone. If this is not known until a later time, the + * correct behavior is to specify a NULL timezone and call + * icaltime_convert_to_zone() at a later time. + * + * There are several ways to create a new icaltimetype: + * + * - icaltime_null_time() + * - icaltime_null_date() + * - icaltime_current_time_with_zone() + * - icaltime_today() + * - icaltime_from_timet_with_zone(time_t tm, int is_date, + * icaltimezone *zone) + * - icaltime_from_string_with_zone(const char* str, icaltimezone *zone) + * - icaltime_from_day_of_year(int doy, int year) + * - icaltime_from_week_number(int week_number, int year) + * + * italtimetype objects can be converted to different formats: + * + * - icaltime_as_timet(struct icaltimetype tt) + * - icaltime_as_timet_with_zone(struct icaltimetype tt, + * icaltimezone *zone) + * - icaltime_as_ical_string(struct icaltimetype tt) + * + * Accessor methods include: + * + * - icaltime_get_timezone(struct icaltimetype t) + * - icaltime_get_tzid(struct icaltimetype t) + * - icaltime_set_timezone(struct icaltimetype t, const icaltimezone *zone) + * - icaltime_day_of_year(struct icaltimetype t) + * - icaltime_day_of_week(struct icaltimetype t) + * - icaltime_start_doy_of_week(struct icaltimetype t) + * - icaltime_week_number(struct icaltimetype t) + * + * Query methods include: + * + * - icaltime_is_null_time(struct icaltimetype t) + * - icaltime_is_valid_time(struct icaltimetype t) + * - icaltime_is_date(struct icaltimetype t) + * - icaltime_is_utc(struct icaltimetype t) + * - icaltime_is_floating(struct icaltimetype t) + * + * Modify, compare and utility methods include: + * + * - icaltime_add(struct icaltimetype t, struct icaldurationtype d) + * - icaltime_subtract(struct icaltimetype t1, struct icaltimetype t2) + * - icaltime_compare_with_zone(struct icaltimetype a,struct icaltimetype b) + * - icaltime_compare(struct icaltimetype a,struct icaltimetype b) + * - icaltime_compare_date_only(struct icaltimetype a, + * struct icaltimetype b) + * - icaltime_adjust(struct icaltimetype *tt, int days, int hours, + * int minutes, int seconds); + * - icaltime_normalize(struct icaltimetype t); + * - icaltime_convert_to_zone(const struct icaltimetype tt, + * icaltimezone *zone); + */ + #ifndef ICALTIME_H #define ICALTIME_H #include <time.h> -/* icaltime_span is returned by icalcomponent_get_span() */ +/* An opaque struct representing a timezone. We declare this here to avoid + a circular dependancy. */ +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +typedef struct _icaltimezone icaltimezone; +#endif + +/** icaltime_span is returned by icalcomponent_get_span() */ struct icaltime_span { - time_t start; /* in UTC */ - time_t end; /* in UTC */ - int is_busy; /* 1->busy time, 0-> free time */ + time_t start; /**< in UTC */ + time_t end; /**< in UTC */ + int is_busy; /**< 1->busy time, 0-> free time */ }; +typedef struct icaltime_span icaltime_span; +/* + * FIXME + * + * is_utc is redundant, and might be considered a minor optimization. + * It might be deprecated, so you should use icaltime_is_utc() instead. + */ struct icaltimetype { - int year; - int month; + int year; /**< Actual year, e.g. 2001. */ + int month; /**< 1 (Jan) to 12 (Dec). */ int day; int hour; int minute; int second; - int is_utc; /* 1-> time is in UTC timezone */ + int is_utc; /**< 1-> time is in UTC timezone */ - int is_date; /* 1 -> interpret this as date. */ + int is_date; /**< 1 -> interpret this as date. */ - const char* zone; /*Ptr to Olsen placename. Libical does not own mem*/ + int is_daylight; /**< 1 -> time is in daylight savings time. */ + + const icaltimezone *zone; /**< timezone */ }; -/* Convert seconds past UNIX epoch to a timetype*/ -struct icaltimetype icaltime_from_timet(time_t v, int is_date); +typedef struct icaltimetype icaltimetype; -/* Return the time as seconds past the UNIX epoch */ -time_t icaltime_as_timet(struct icaltimetype); +/** Return a null time, which indicates no time has been set. + This time represent the beginning of the epoch */ +struct icaltimetype icaltime_null_time(void); -/* Return a string represention of the time, in RFC2445 format. The - string is owned by libical */ -char* icaltime_as_ical_string(struct icaltimetype tt); +/** Return a null date */ +struct icaltimetype icaltime_null_date(void); + +/** Returns the current time in the given timezone, as an icaltimetype. */ +struct icaltimetype icaltime_current_time_with_zone(const icaltimezone *zone); + +/** Returns the current day as an icaltimetype, with is_date set. */ +struct icaltimetype icaltime_today(void); -/* Like icaltime_from_timet(), except that the input may be in seconds - past the epoch in floating time. This routine is deprecated */ -struct icaltimetype icaltime_from_int(int v, int is_date, int is_utc); +/** Convert seconds past UNIX epoch to a timetype*/ +struct icaltimetype icaltime_from_timet(const time_t v, const int is_date); -/* Like icaltime_as_timet, but in a floating epoch. This routine is deprecated */ -int icaltime_as_int(struct icaltimetype); +/** Convert seconds past UNIX epoch to a timetype, using timezones. */ +struct icaltimetype icaltime_from_timet_with_zone(const time_t tm, + const int is_date, const icaltimezone *zone); -/* create a time from an ISO format string */ +/** create a time from an ISO format string */ struct icaltimetype icaltime_from_string(const char* str); -/* Routines for handling timezones */ -/* Return the offset of the named zone as seconds. tt is a time - indicating the date for which you want the offset */ -int icaltime_utc_offset(struct icaltimetype tt, const char* tzid); +/** create a time from an ISO format string */ +struct icaltimetype icaltime_from_string_with_zone(const char* str, + const icaltimezone *zone); -/* convert tt, of timezone tzid, into a utc time. Does nothing if the - time is already UTC. */ -struct icaltimetype icaltime_as_utc(struct icaltimetype tt, - const char* tzid); +/** Create a new time, given a day of year and a year. */ +struct icaltimetype icaltime_from_day_of_year(const int doy, + const int year); -/* convert tt, a time in UTC, into a time in timezone tzid */ -struct icaltimetype icaltime_as_zone(struct icaltimetype tt, - const char* tzid); +/** @brief Contructor (TODO). + * Create a new time from a weeknumber and a year. */ +struct icaltimetype icaltime_from_week_number(const int week_number, + const int year); -/* Return a null time, which indicates no time has been set. This time represent the beginning of the epoch */ -struct icaltimetype icaltime_null_time(void); +/** Return the time as seconds past the UNIX epoch */ +time_t icaltime_as_timet(const struct icaltimetype); + +/** Return the time as seconds past the UNIX epoch, using timezones. */ +time_t icaltime_as_timet_with_zone(const struct icaltimetype tt, + const icaltimezone *zone); + +/** Return a string represention of the time, in RFC2445 format. The + string is owned by libical */ +const char* icaltime_as_ical_string(const struct icaltimetype tt); + +/** @brief Return the timezone */ +const icaltimezone *icaltime_get_timezone(const struct icaltimetype t); -/* Return true of the time is null. */ -int icaltime_is_null_time(struct icaltimetype t); +/** @brief Return the tzid, or NULL for a floating time */ +char *icaltime_get_tzid(const struct icaltimetype t); -/* Returns false if the time is clearly invalid, but is not null. This +/** @brief Set the timezone */ +struct icaltimetype icaltime_set_timezone(struct icaltimetype *t, + const icaltimezone *zone); + +/** Return the day of the year of the given time */ +int icaltime_day_of_year(const struct icaltimetype t); + +/** Return the day of the week of the given time. Sunday is 1 */ +int icaltime_day_of_week(const struct icaltimetype t); + +/** Return the day of the year for the Sunday of the week that the + given time is within. */ +int icaltime_start_doy_of_week(const struct icaltimetype t); + +/** Return the week number for the week the given time is within */ +int icaltime_week_number(const struct icaltimetype t); + +/** Return true of the time is null. */ +int icaltime_is_null_time(const struct icaltimetype t); + +/** Returns false if the time is clearly invalid, but is not null. This is usually the result of creating a new time type buy not clearing it, or setting one of the flags to an illegal value. */ -int icaltime_is_valid_time(struct icaltimetype t); +int icaltime_is_valid_time(const struct icaltimetype t); -/* Reset all of the time components to be in their normal ranges. For - instance, given a time with minutes=70, the minutes will be reduces - to 10, and the hour incremented. This allows the caller to do - arithmetic on times without worrying about overflow or - underflow. */ -struct icaltimetype icaltime_normalize(struct icaltimetype t); +/** @brief Returns true if time is of DATE type, false if DATE-TIME */ +int icaltime_is_date(const struct icaltimetype t); -/* Return the day of the year of the given time */ -short icaltime_day_of_year(struct icaltimetype t); +/** @brief Returns true if time is relative to UTC zone */ +int icaltime_is_utc(const struct icaltimetype t); -/* Create a new time, given a day of year and a year. */ -struct icaltimetype icaltime_from_day_of_year(short doy, short year); +/** @brief Returns true if time is a floating time */ +int icaltime_is_floating(const struct icaltimetype t); -/* Return the day of the week of the given time. Sunday is 1 */ -short icaltime_day_of_week(struct icaltimetype t); +/** Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ +int icaltime_compare_with_zone(const struct icaltimetype a, + const struct icaltimetype b); -/* Return the day of the year for the Sunday of the week that the - given time is within. */ -short icaltime_start_doy_of_week(struct icaltimetype t); +/** Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ +int icaltime_compare(const struct icaltimetype a, + const struct icaltimetype b); -/* Return a string with the time represented in the same format as ctime(). THe string is owned by libical */ -char* icaltime_as_ctime(struct icaltimetype); +/** like icaltime_compare, but only use the date parts. */ +int icaltime_compare_date_only(const struct icaltimetype a, + const struct icaltimetype b); -/* Return the week number for the week the given time is within */ -short icaltime_week_number(struct icaltimetype t); +/** Adds or subtracts a number of days, hours, minutes and seconds. */ +void icaltime_adjust(struct icaltimetype *tt, const int days, + const int hours, const int minutes, const int seconds); -/* Create a new time from a weeknumber and a year. */ -struct icaltimetype icaltime_from_week_number(short week_number, short year); +/** Normalize the icaltime, so that all fields are within the normal range. */ +struct icaltimetype icaltime_normalize(const struct icaltimetype t); -/* Return -1, 0, or 1 to indicate that a<b, a==b or a>b */ -int icaltime_compare(struct icaltimetype a,struct icaltimetype b); +/** convert tt, of timezone tzid, into a utc time. Does nothing if the + time is already UTC. */ +struct icaltimetype icaltime_convert_to_zone(const struct icaltimetype tt, + icaltimezone *zone); -/* like icaltime_compare, but only use the date parts. */ -int icaltime_compare_date_only(struct icaltimetype a, struct icaltimetype b); +/** Return the number of days in the given month */ +int icaltime_days_in_month(const int month, const int year); -/* Return the number of days in the given month */ -short icaltime_days_in_month(short month,short year); +/** @brief calculate an icaltimespan given a start and end time. */ +struct icaltime_span icaltime_span_new(struct icaltimetype dtstart, + struct icaltimetype dtend, + int is_busy); -#endif /* !ICALTIME_H */ +/** @brief Returns true if the two spans overlap **/ +int icaltime_span_overlaps(icaltime_span *s1, + icaltime_span *s2); +/** @brief Returns true if the span is totally within the containing + * span + */ +int icaltime_span_contains(icaltime_span *s, + icaltime_span *container); + + +#endif /* !ICALTIME_H */ diff --git a/libical/src/libical/icaltimezone.c b/libical/src/libical/icaltimezone.c new file mode 100644 index 0000000..fdb6b91 --- a/dev/null +++ b/libical/src/libical/icaltimezone.c @@ -0,0 +1,1672 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*====================================================================== + FILE: icaltimezone.c + CREATOR: Damon Chaplin 15 March 2001 + + $Id$ + $Locker$ + + (C) COPYRIGHT 2001, Damon Chaplin + + 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/ + + +======================================================================*/ + +/** @file icaltimezone.c + * @brief implementation of timezone handling routines + **/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "icalproperty.h" +#include "icalarray.h" +#include "icalerror.h" +#include "icalparser.h" +#include "icaltimezone.h" + +#ifdef WIN32 +#define snprintf _snprintf +#define PACKAGE_DATA_DIR "/Projects/libical" +#endif + +/** This is the toplevel directory where the timezone data is installed in. */ +#define ZONEINFO_DIRECTORY "/zoneinfo" + +/** The prefix we use to uniquely identify TZIDs. */ +#define TZID_PREFIX "/softwarestudio.org/" +#define TZID_PREFIX_LEN 20 + +/** This is the filename of the file containing the city names and + coordinates of all the builtin timezones. */ +#define ZONES_TAB_FILENAME "zones.tab" + +/** This is the number of years of extra coverage we do when expanding + the timezone changes. */ +#define ICALTIMEZONE_EXTRA_COVERAGE 5 + +/** This is the maximum year we will expand to. time_t values only go up to + somewhere around 2037. */ +#define ICALTIMEZONE_MAX_YEAR 2035 + +struct _icaltimezone { + char *tzid; + /**< The unique ID of this timezone, + e.g. "/softwarestudio.org/Olson_20010601_1/Africa/Banjul". + This should only be used to identify a VTIMEZONE. It is not + meant to be displayed to the user in any form. */ + + char *location; + /**< The location for the timezone, e.g. "Africa/Accra" for the + Olson database. We look for this in the "LOCATION" or + "X-LIC-LOCATION" properties of the VTIMEZONE component. It + isn't a standard property yet. This will be NULL if no location + is found in the VTIMEZONE. */ + + char *tznames; + /**< This will be set to a combination of the TZNAME properties + from the last STANDARD and DAYLIGHT components in the + VTIMEZONE, e.g. "EST/EDT". If they both use the same TZNAME, + or only one type of component is found, then only one TZNAME + will appear, e.g. "AZOT". If no TZNAME is found this will be + NULL. */ + + double latitude; + double longitude; + /**< The coordinates of the city, in degrees. */ + + icalcomponent *component; + /**< The toplevel VTIMEZONE component loaded from the .ics file for this + timezone. If we need to regenerate the changes data we need this. */ + + icaltimezone *builtin_timezone; + /**< If this is not NULL it points to the builtin icaltimezone + that the above TZID refers to. This icaltimezone should be used + instead when accessing the timezone changes data, so that the + expanded timezone changes data is shared between calendar + components. */ + + int end_year; + /**< This is the last year for which we have expanded the data to. + If we need to calculate a date past this we need to expand the + timezone component data from scratch. */ + + icalarray *changes; + /**< A dynamically-allocated array of time zone changes, sorted by the + time of the change in local time. So we can do fast binary-searches + to convert from local time to UTC. */ +}; + +typedef struct _icaltimezonechange icaltimezonechange; + +struct _icaltimezonechange { + int utc_offset; + /**< The offset to add to UTC to get local time, in seconds. */ + + int prev_utc_offset; + /**< The offset to add to UTC, before this change, in seconds. */ + + int year; /**< Actual year, e.g. 2001. */ + int month; /**< 1 (Jan) to 12 (Dec). */ + int day; + int hour; + int minute; + int second; + /**< The time that the change came into effect, in UTC. + Note that the prev_utc_offset applies to this local time, + since we haven't changed to the new offset yet. */ + + int is_daylight; + /**< Whether this is STANDARD or DAYLIGHT time. */ +}; + + +/** An array of icaltimezones for the builtin timezones. */ +static icalarray *builtin_timezones = NULL; + +/** This is the special UTC timezone, which isn't in builtin_timezones. */ +static icaltimezone utc_timezone = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static char* zone_files_directory = NULL; + +static void icaltimezone_reset (icaltimezone *zone); +static char* icaltimezone_get_location_from_vtimezone (icalcomponent *component); +static char* icaltimezone_get_tznames_from_vtimezone (icalcomponent *component); +static void icaltimezone_expand_changes (icaltimezone *zone, + int end_year); +static void icaltimezone_expand_vtimezone (icalcomponent *comp, + int end_year, + icalarray *changes); +static int icaltimezone_compare_change_fn (const void *elem1, + const void *elem2); + +static int icaltimezone_find_nearby_change (icaltimezone *zone, + icaltimezonechange *change); + +static void icaltimezone_adjust_change (icaltimezonechange *tt, + int days, + int hours, + int minutes, + int seconds); + +static void icaltimezone_init (icaltimezone *zone); + +/** Gets the TZID, LOCATION/X-LIC-LOCATION, and TZNAME properties from the + VTIMEZONE component and places them in the icaltimezone. It returns 1 on + success, or 0 if the TZID can't be found. */ +static int icaltimezone_get_vtimezone_properties (icaltimezone *zone, + icalcomponent *component); + + +static void icaltimezone_load_builtin_timezone (icaltimezone *zone); + +static void icaltimezone_ensure_coverage (icaltimezone *zone, + int end_year); + + +static void icaltimezone_init_builtin_timezones(void); + +static void icaltimezone_parse_zone_tab (void); + +static char* icaltimezone_load_get_line_fn (char *s, + size_t size, + void *data); + +static void format_utc_offset (int utc_offset, + char *buffer); + +static char* get_zone_directory(void); + + +/** Creates a new icaltimezone. */ +icaltimezone* +icaltimezone_new (void) +{ + icaltimezone *zone; + + zone = (icaltimezone*) malloc (sizeof (icaltimezone)); + if (!zone) { + icalerror_set_errno (ICAL_NEWFAILED_ERROR); + return NULL; + } + + icaltimezone_init (zone); + + return zone; +} + + +/** Frees all memory used for the icaltimezone. */ +void +icaltimezone_free (icaltimezone *zone, + int free_struct) +{ + icaltimezone_reset (zone); + if (free_struct) + free (zone); +} + + +/** Resets the icaltimezone to the initial state, freeing most of the fields. */ +static void +icaltimezone_reset (icaltimezone *zone) +{ + if (zone->tzid) + free (zone->tzid); + if (zone->location) + free (zone->location); + if (zone->tznames) + free (zone->tznames); + if (zone->component) + icalcomponent_free (zone->component); + if (zone->changes) + icalarray_free (zone->changes); + + icaltimezone_init (zone); +} + + +/** Initializes an icaltimezone. */ +static void +icaltimezone_init (icaltimezone *zone) +{ + zone->tzid = NULL; + zone->location = NULL; + zone->tznames = NULL; + zone->latitude = 0.0; + zone->longitude = 0.0; + zone->component = NULL; + zone->builtin_timezone = NULL; + zone->end_year = 0; + zone->changes = NULL; +} + + +/** Gets the TZID, LOCATION/X-LIC-LOCATION and TZNAME properties of + the VTIMEZONE component and stores them in the icaltimezone. It + returns 1 on success, or 0 if the TZID can't be found. Note that + it expects the zone to be initialized or reset - it doesn't free + any old values. */ +static int +icaltimezone_get_vtimezone_properties (icaltimezone *zone, + icalcomponent *component) +{ + icalproperty *prop; + const char *tzid; + + prop = icalcomponent_get_first_property (component, ICAL_TZID_PROPERTY); + if (!prop) + return 0; + + /* A VTIMEZONE MUST have a TZID, or a lot of our code won't work. */ + tzid = icalproperty_get_tzid (prop); + if (!tzid) + return 0; + + zone->tzid = strdup (tzid); + zone->component = component; + if ( zone->location != 0 ) free ( zone->location ); + zone->location = icaltimezone_get_location_from_vtimezone (component); + zone->tznames = icaltimezone_get_tznames_from_vtimezone (component); + + return 1; +} + +/** Gets the LOCATION or X-LIC-LOCATION property from a VTIMEZONE. */ +static char* +icaltimezone_get_location_from_vtimezone (icalcomponent *component) +{ + icalproperty *prop; + const char *location; + const char *name; + + prop = icalcomponent_get_first_property (component, + ICAL_LOCATION_PROPERTY); + if (prop) { + location = icalproperty_get_location (prop); + if (location) + return strdup (location); + } + + prop = icalcomponent_get_first_property (component, ICAL_X_PROPERTY); + while (prop) { + name = icalproperty_get_x_name (prop); + if (name && !strcmp (name, "X-LIC-LOCATION")) { + location = icalproperty_get_x (prop); + if (location) + return strdup (location); + } + prop = icalcomponent_get_next_property (component, + ICAL_X_PROPERTY); + } + + return NULL; +} + + +/** Gets the TZNAMEs used for the last STANDARD & DAYLIGHT components + in a VTIMEZONE. If both STANDARD and DAYLIGHT components use the + same TZNAME, it returns that. If they use different TZNAMEs, it + formats them like "EST/EDT". The returned string should be freed by + the caller. */ +static char* +icaltimezone_get_tznames_from_vtimezone (icalcomponent *component) +{ + icalcomponent *comp; + icalcomponent_kind type; + icalproperty *prop; + struct icaltimetype dtstart; + struct icaldatetimeperiodtype rdate; + const char *current_tzname; + const char *standard_tzname = NULL, *daylight_tzname = NULL; + struct icaltimetype standard_max_date, daylight_max_date; + struct icaltimetype current_max_date; + + standard_max_date = icaltime_null_time(); + daylight_max_date = icaltime_null_time(); + + /* Step through the STANDARD & DAYLIGHT subcomponents. */ + comp = icalcomponent_get_first_component (component, ICAL_ANY_COMPONENT); + while (comp) { + type = icalcomponent_isa (comp); + if (type == ICAL_XSTANDARD_COMPONENT + || type == ICAL_XDAYLIGHT_COMPONENT) { + current_max_date = icaltime_null_time (); + current_tzname = NULL; + + /* Step through the properties. We want to find the TZNAME, and + the largest DTSTART or RDATE. */ + prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY); + while (prop) { + switch (icalproperty_isa (prop)) { + case ICAL_TZNAME_PROPERTY: + current_tzname = icalproperty_get_tzname (prop); + break; + + case ICAL_DTSTART_PROPERTY: + dtstart = icalproperty_get_dtstart (prop); + if (icaltime_compare (dtstart, current_max_date) > 0) + current_max_date = dtstart; + + break; + + case ICAL_RDATE_PROPERTY: + rdate = icalproperty_get_rdate (prop); + if (icaltime_compare (rdate.time, current_max_date) > 0) + current_max_date = rdate.time; + + break; + + default: + break; + } + + prop = icalcomponent_get_next_property (comp, + ICAL_ANY_PROPERTY); + } + + if (current_tzname) { + if (type == ICAL_XSTANDARD_COMPONENT) { + if (!standard_tzname + || icaltime_compare (current_max_date, + standard_max_date) > 0) { + standard_max_date = current_max_date; + standard_tzname = current_tzname; + } + } else { + if (!daylight_tzname + || icaltime_compare (current_max_date, + daylight_max_date) > 0) { + daylight_max_date = current_max_date; + daylight_tzname = current_tzname; + } + } + } + } + + comp = icalcomponent_get_next_component (component, + ICAL_ANY_COMPONENT); + } + + /* Outlook (2000) places "Standard Time" and "Daylight Time" in the TZNAME + strings, which is totally useless. So we return NULL in that case. */ + if (standard_tzname && !strcmp (standard_tzname, "Standard Time")) + return NULL; + + /* If both standard and daylight TZNAMEs were found, if they are the same + we return just one, else we format them like "EST/EDT". */ + if (standard_tzname && daylight_tzname) { + unsigned int standard_len, daylight_len; + char *tznames; + + if (!strcmp (standard_tzname, daylight_tzname)) + return strdup (standard_tzname); + + standard_len = strlen (standard_tzname); + daylight_len = strlen (daylight_tzname); + tznames = malloc (standard_len + daylight_len + 2); + strcpy (tznames, standard_tzname); + tznames[standard_len] = '/'; + strcpy (tznames + standard_len + 1, daylight_tzname); + return tznames; + } else { + const char *tznames; + + /* If either of the TZNAMEs was found just return that, else NULL. */ + tznames = standard_tzname ? standard_tzname : daylight_tzname; + return tznames ? strdup (tznames) : NULL; + } +} + + +static void +icaltimezone_ensure_coverage (icaltimezone *zone, + int end_year) +{ + /* When we expand timezone changes we always expand at least up to this + year, plus ICALTIMEZONE_EXTRA_COVERAGE. */ + static int icaltimezone_minimum_expansion_year = -1; + + int changes_end_year; + + if (!zone->component) + icaltimezone_load_builtin_timezone (zone); + + if (icaltimezone_minimum_expansion_year == -1) { + struct icaltimetype today = icaltime_today(); + icaltimezone_minimum_expansion_year = today.year; + } + + changes_end_year = end_year; + if (changes_end_year < icaltimezone_minimum_expansion_year) + changes_end_year = icaltimezone_minimum_expansion_year; + + changes_end_year += ICALTIMEZONE_EXTRA_COVERAGE; + + if (changes_end_year > ICALTIMEZONE_MAX_YEAR) + changes_end_year = ICALTIMEZONE_MAX_YEAR; + + if (!zone->changes || zone->end_year < end_year) + icaltimezone_expand_changes (zone, changes_end_year); +} + + +static void +icaltimezone_expand_changes (icaltimezone *zone, + int end_year) +{ + icalarray *changes; + icalcomponent *comp; + +#if 0 + printf ("\nExpanding changes for: %s to year: %i\n", zone->tzid, end_year); +#endif + + changes = icalarray_new (sizeof (icaltimezonechange), 32); + if (!changes) + return; + + /* Scan the STANDARD and DAYLIGHT subcomponents. */ + comp = icalcomponent_get_first_component (zone->component, + ICAL_ANY_COMPONENT); + while (comp) { + icaltimezone_expand_vtimezone (comp, end_year, changes); + comp = icalcomponent_get_next_component (zone->component, + ICAL_ANY_COMPONENT); + } + + /* Sort the changes. We may have duplicates but I don't think it will + matter. */ + icalarray_sort (changes, icaltimezone_compare_change_fn); + + if (zone->changes) + icalarray_free (zone->changes); + + zone->changes = changes; + zone->end_year = end_year; +} + + +static void +icaltimezone_expand_vtimezone (icalcomponent *comp, + int end_year, + icalarray *changes) +{ + icaltimezonechange change; + icalproperty *prop; + struct icaltimetype dtstart, occ; + struct icalrecurrencetype rrule; + icalrecur_iterator* rrule_iterator; + struct icaldatetimeperiodtype rdate; + int found_dtstart = 0, found_tzoffsetto = 0, found_tzoffsetfrom = 0; + int has_recurrence = 0; + + /* First we check if it is a STANDARD or DAYLIGHT component, and + just return if it isn't. */ + if (icalcomponent_isa (comp) == ICAL_XSTANDARD_COMPONENT) + change.is_daylight = 0; + else if (icalcomponent_isa (comp) == ICAL_XDAYLIGHT_COMPONENT) + change.is_daylight = 1; + else + return; + + /* Step through each of the properties to find the DTSTART, + TZOFFSETFROM and TZOFFSETTO. We can't expand recurrences here + since we need these properties before we can do that. */ + prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY); + while (prop) { + switch (icalproperty_isa (prop)) { + case ICAL_DTSTART_PROPERTY: + dtstart = icalproperty_get_dtstart (prop); + found_dtstart = 1; + break; + case ICAL_TZOFFSETTO_PROPERTY: + change.utc_offset = icalproperty_get_tzoffsetto (prop); + /*printf ("Found TZOFFSETTO: %i\n", change.utc_offset);*/ + found_tzoffsetto = 1; + break; + case ICAL_TZOFFSETFROM_PROPERTY: + change.prev_utc_offset = icalproperty_get_tzoffsetfrom (prop); + /*printf ("Found TZOFFSETFROM: %i\n", change.prev_utc_offset);*/ + found_tzoffsetfrom = 1; + break; + case ICAL_RDATE_PROPERTY: + case ICAL_RRULE_PROPERTY: + has_recurrence = 1; + break; + default: + /* Just ignore any other properties. */ + break; + } + + prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY); + } + + /* If we didn't find a DTSTART, TZOFFSETTO and TZOFFSETFROM we have to + ignore the component. FIXME: Add an error property? */ + if (!found_dtstart || !found_tzoffsetto || !found_tzoffsetfrom) + return; + +#if 0 + printf ("\n Expanding component DTSTART (Y/M/D): %i/%i/%i %i:%02i:%02i\n", + dtstart.year, dtstart.month, dtstart.day, + dtstart.hour, dtstart.minute, dtstart.second); +#endif + + /* If the STANDARD/DAYLIGHT component has no recurrence data, we just add + a single change for the DTSTART. */ + if (!has_recurrence) { + change.year = dtstart.year; + change.month = dtstart.month; + change.day = dtstart.day; + change.hour = dtstart.hour; + change.minute = dtstart.minute; + change.second = dtstart.second; + + /* Convert to UTC. */ + icaltimezone_adjust_change (&change, 0, 0, 0, -change.prev_utc_offset); + +#if 0 + printf (" Appending single DTSTART (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n", + change.year, change.month, change.day, + change.hour, change.minute, change.second); +#endif + + /* Add the change to the array. */ + icalarray_append (changes, &change); + return; + } + + /* The component has recurrence data, so we expand that now. */ + prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY); + while (prop) { +#if 0 + printf ("Expanding property...\n"); +#endif + switch (icalproperty_isa (prop)) { + case ICAL_RDATE_PROPERTY: + rdate = icalproperty_get_rdate (prop); + change.year = rdate.time.year; + change.month = rdate.time.month; + change.day = rdate.time.day; + /* RDATEs with a DATE value inherit the time from + the DTSTART. */ + if (icaltime_is_date(rdate.time)) { + change.hour = dtstart.hour; + change.minute = dtstart.minute; + change.second = dtstart.second; + } else { + change.hour = rdate.time.hour; + change.minute = rdate.time.minute; + change.second = rdate.time.second; + + /* The spec was a bit vague about whether RDATEs were in local + time or UTC so we support both to be safe. So if it is in + UTC we have to add the UTC offset to get a local time. */ + if (!icaltime_is_utc(rdate.time)) + icaltimezone_adjust_change (&change, 0, 0, 0, + -change.prev_utc_offset); + } + +#if 0 + printf (" Appending RDATE element (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n", + change.year, change.month, change.day, + change.hour, change.minute, change.second); +#endif + + icalarray_append (changes, &change); + break; + case ICAL_RRULE_PROPERTY: + rrule = icalproperty_get_rrule (prop); + + /* If the rrule UNTIL value is set and is in UTC, we convert it to + a local time, since the recurrence code has no way to convert + it itself. */ + if (!icaltime_is_null_time (rrule.until) && rrule.until.is_utc) { +#if 0 + printf (" Found RRULE UNTIL in UTC.\n"); +#endif + + /* To convert from UTC to a local time, we use the TZOFFSETFROM + since that is the offset from UTC that will be in effect + when each of the RRULE occurrences happens. */ + icaltime_adjust (&rrule.until, 0, 0, 0, + change.prev_utc_offset); + rrule.until.is_utc = 0; + } + + rrule_iterator = icalrecur_iterator_new (rrule, dtstart); + for (;;) { + occ = icalrecur_iterator_next (rrule_iterator); + if (occ.year > end_year || icaltime_is_null_time (occ)) + break; + + change.year = occ.year; + change.month = occ.month; + change.day = occ.day; + change.hour = occ.hour; + change.minute = occ.minute; + change.second = occ.second; + +#if 0 + printf (" Appending RRULE element (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n", + change.year, change.month, change.day, + change.hour, change.minute, change.second); +#endif + + icaltimezone_adjust_change (&change, 0, 0, 0, + -change.prev_utc_offset); + + icalarray_append (changes, &change); + } + + icalrecur_iterator_free (rrule_iterator); + break; + default: + break; + } + + prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY); + } +} + + +/** A function to compare 2 icaltimezonechange elements, used for qsort(). */ +static int +icaltimezone_compare_change_fn (const void *elem1, + const void *elem2) +{ + const icaltimezonechange *change1, *change2; + int retval; + + change1 = elem1; + change2 = elem2; + + if (change1->year < change2->year) + retval = -1; + else if (change1->year > change2->year) + retval = 1; + + else if (change1->month < change2->month) + retval = -1; + else if (change1->month > change2->month) + retval = 1; + + else if (change1->day < change2->day) + retval = -1; + else if (change1->day > change2->day) + retval = 1; + + else if (change1->hour < change2->hour) + retval = -1; + else if (change1->hour > change2->hour) + retval = 1; + + else if (change1->minute < change2->minute) + retval = -1; + else if (change1->minute > change2->minute) + retval = 1; + + else if (change1->second < change2->second) + retval = -1; + else if (change1->second > change2->second) + retval = 1; + + else + retval = 0; + + return retval; +} + + + +void +icaltimezone_convert_time (struct icaltimetype *tt, + icaltimezone *from_zone, + icaltimezone *to_zone) +{ + int utc_offset, is_daylight; + + /* If the time is a DATE value or both timezones are the same, or we are + converting a floating time, we don't need to do anything. */ + if (icaltime_is_date(*tt) || from_zone == to_zone || from_zone == NULL) + return; + + /* Convert the time to UTC by getting the UTC offset and subtracting it. */ + utc_offset = icaltimezone_get_utc_offset (from_zone, tt, NULL); + icaltime_adjust (tt, 0, 0, 0, -utc_offset); + + /* Now we convert the time to the new timezone by getting the UTC offset + of our UTC time and adding it. */ + utc_offset = icaltimezone_get_utc_offset_of_utc_time (to_zone, tt, + &is_daylight); + tt->is_daylight = is_daylight; + icaltime_adjust (tt, 0, 0, 0, utc_offset); +} + + + + +/** @deprecated This API wasn't updated when we changed icaltimetype to contain its own + timezone. Also, this takes a pointer instead of the struct. */ +/* Calculates the UTC offset of a given local time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int +icaltimezone_get_utc_offset (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight) +{ + icaltimezonechange *zone_change, *prev_zone_change, tt_change, tmp_change; + int change_num, step, utc_offset_change, cmp; + int change_num_to_use; + int want_daylight; + + if (tt == NULL) + return 0; + + if (is_daylight) + *is_daylight = 0; + + /* For local times and UTC return 0. */ + if (zone == NULL || zone == &utc_timezone) + return 0; + + /* Use the builtin icaltimezone if possible. */ + if (zone->builtin_timezone) + zone = zone->builtin_timezone; + + /* Make sure the changes array is expanded up to the given time. */ + icaltimezone_ensure_coverage (zone, tt->year); + + if (!zone->changes || zone->changes->num_elements == 0) + return 0; + + /* Copy the time parts of the icaltimetype to an icaltimezonechange so we + can use our comparison function on it. */ + tt_change.year = tt->year; + tt_change.month = tt->month; + tt_change.day = tt->day; + tt_change.hour = tt->hour; + tt_change.minute = tt->minute; + tt_change.second = tt->second; + + /* This should find a change close to the time, either the change before + it or the change after it. */ + change_num = icaltimezone_find_nearby_change (zone, &tt_change); + + /* Sanity check. */ + icalerror_assert (change_num >= 0, + "Negative timezone change index"); + icalerror_assert (change_num < zone->changes->num_elements, + "Timezone change index out of bounds"); + + /* Now move backwards or forwards to find the timezone change that applies + to tt. It should only have to do 1 or 2 steps. */ + zone_change = icalarray_element_at (zone->changes, change_num); + step = 1; + change_num_to_use = -1; + for (;;) { + /* Copy the change, so we can adjust it. */ + tmp_change = *zone_change; + + /* If the clock is going backward, check if it is in the region of time + that is used twice. If it is, use the change with the daylight + setting which matches tt, or use standard if we don't know. */ + if (tmp_change.utc_offset < tmp_change.prev_utc_offset) { + /* If the time change is at 2:00AM local time and the clock is + going back to 1:00AM we adjust the change to 1:00AM. We may + have the wrong change but we'll figure that out later. */ + icaltimezone_adjust_change (&tmp_change, 0, 0, 0, + tmp_change.utc_offset); + } else { + icaltimezone_adjust_change (&tmp_change, 0, 0, 0, + tmp_change.prev_utc_offset); + } + + cmp = icaltimezone_compare_change_fn (&tt_change, &tmp_change); + + /* If the given time is on or after this change, then this change may + apply, but we continue as a later change may be the right one. + If the given time is before this change, then if we have already + found a change which applies we can use that, else we need to step + backwards. */ + if (cmp >= 0) + change_num_to_use = change_num; + else + step = -1; + + /* If we are stepping backwards through the changes and we have found + a change that applies, then we know this is the change to use so + we exit the loop. */ + if (step == -1 && change_num_to_use != -1) + break; + + change_num += step; + + /* If we go past the start of the changes array, then we have no data + for this time so we return a UTC offset of 0. */ + if (change_num < 0) + return 0; + + if (change_num >= zone->changes->num_elements) + break; + + zone_change = icalarray_element_at (zone->changes, change_num); + } + + /* If we didn't find a change to use, then we have a bug! */ + icalerror_assert (change_num_to_use != -1, + "No applicable timezone change found"); + + /* Now we just need to check if the time is in the overlapped region of + time when clocks go back. */ + zone_change = icalarray_element_at (zone->changes, change_num_to_use); + + utc_offset_change = zone_change->utc_offset - zone_change->prev_utc_offset; + if (utc_offset_change < 0 && change_num_to_use > 0) { + tmp_change = *zone_change; + icaltimezone_adjust_change (&tmp_change, 0, 0, 0, + tmp_change.prev_utc_offset); + + if (icaltimezone_compare_change_fn (&tt_change, &tmp_change) < 0) { + /* The time is in the overlapped region, so we may need to use + either the current zone_change or the previous one. If the + time has the is_daylight field set we use the matching change, + else we use the change with standard time. */ + prev_zone_change = icalarray_element_at (zone->changes, + change_num_to_use - 1); + + /* I was going to add an is_daylight flag to struct icaltimetype, + but iCalendar doesn't let us distinguish between standard and + daylight time anyway, so there's no point. So we just use the + standard time instead. */ + want_daylight = (tt->is_daylight == 1) ? 1 : 0; + +#if 0 + if (zone_change->is_daylight == prev_zone_change->is_daylight) + printf (" **** Same is_daylight setting\n"); +#endif + + if (zone_change->is_daylight != want_daylight + && prev_zone_change->is_daylight == want_daylight) + zone_change = prev_zone_change; + } + } + + /* Now we know exactly which timezone change applies to the time, so + we can return the UTC offset and whether it is a daylight time. */ + if (is_daylight) + *is_daylight = zone_change->is_daylight; + return zone_change->utc_offset; +} + + +/** @deprecated This API wasn't updated when we changed icaltimetype to contain its own + timezone. Also, this takes a pointer instead of the struct. */ +/** Calculates the UTC offset of a given UTC time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int +icaltimezone_get_utc_offset_of_utc_time (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight) +{ + icaltimezonechange *zone_change, tt_change, tmp_change; + int change_num, step, change_num_to_use; + + if (is_daylight) + *is_daylight = 0; + + /* For local times and UTC return 0. */ + if (zone == NULL || zone == &utc_timezone) + return 0; + + /* Use the builtin icaltimezone if possible. */ + if (zone->builtin_timezone) + zone = zone->builtin_timezone; + + /* Make sure the changes array is expanded up to the given time. */ + icaltimezone_ensure_coverage (zone, tt->year); + + if (!zone->changes || zone->changes->num_elements == 0) + return 0; + + /* Copy the time parts of the icaltimetype to an icaltimezonechange so we + can use our comparison function on it. */ + tt_change.year = tt->year; + tt_change.month = tt->month; + tt_change.day = tt->day; + tt_change.hour = tt->hour; + tt_change.minute = tt->minute; + tt_change.second = tt->second; + + /* This should find a change close to the time, either the change before + it or the change after it. */ + change_num = icaltimezone_find_nearby_change (zone, &tt_change); + + /* Sanity check. */ + icalerror_assert (change_num >= 0, + "Negative timezone change index"); + icalerror_assert (change_num < zone->changes->num_elements, + "Timezone change index out of bounds"); + + /* Now move backwards or forwards to find the timezone change that applies + to tt. It should only have to do 1 or 2 steps. */ + zone_change = icalarray_element_at (zone->changes, change_num); + step = 1; + change_num_to_use = -1; + for (;;) { + /* Copy the change and adjust it to UTC. */ + tmp_change = *zone_change; + + /* If the given time is on or after this change, then this change may + apply, but we continue as a later change may be the right one. + If the given time is before this change, then if we have already + found a change which applies we can use that, else we need to step + backwards. */ + if (icaltimezone_compare_change_fn (&tt_change, &tmp_change) >= 0) + change_num_to_use = change_num; + else + step = -1; + + /* If we are stepping backwards through the changes and we have found + a change that applies, then we know this is the change to use so + we exit the loop. */ + if (step == -1 && change_num_to_use != -1) + break; + + change_num += step; + + /* If we go past the start of the changes array, then we have no data + for this time so we return a UTC offset of 0. */ + if (change_num < 0) + return 0; + + if (change_num >= zone->changes->num_elements) + break; + + zone_change = icalarray_element_at (zone->changes, change_num); + } + + /* If we didn't find a change to use, then we have a bug! */ + icalerror_assert (change_num_to_use != -1, + "No applicable timezone change found"); + + /* Now we know exactly which timezone change applies to the time, so + we can return the UTC offset and whether it is a daylight time. */ + zone_change = icalarray_element_at (zone->changes, change_num_to_use); + if (is_daylight) + *is_daylight = zone_change->is_daylight; + + return zone_change->utc_offset; +} + + +/** Returns the index of a timezone change which is close to the time + given in change. */ +static int +icaltimezone_find_nearby_change (icaltimezone *zone, + icaltimezonechange *change) +{ + icaltimezonechange *zone_change; + int lower, upper, middle, cmp; + + /* Do a simple binary search. */ + lower = middle = 0; + upper = zone->changes->num_elements; + + while (lower < upper) { + middle = (lower + upper) / 2; + zone_change = icalarray_element_at (zone->changes, middle); + cmp = icaltimezone_compare_change_fn (change, zone_change); + if (cmp == 0) + break; + else if (cmp < 0) + upper = middle; + else + lower = middle + 1; + } + + return middle; +} + + + + +/** Adds (or subtracts) a time from a icaltimezonechange. NOTE: This + function is exactly the same as icaltime_adjust() except for the + type of the first parameter. */ +static void +icaltimezone_adjust_change (icaltimezonechange *tt, + int days, + int hours, + int minutes, + int seconds) +{ + int second, minute, hour, day; + int minutes_overflow, hours_overflow, days_overflow; + int days_in_month; + + /* Add on the seconds. */ + second = tt->second + seconds; + tt->second = second % 60; + minutes_overflow = second / 60; + if (tt->second < 0) { + tt->second += 60; + minutes_overflow--; + } + + /* Add on the minutes. */ + minute = tt->minute + minutes + minutes_overflow; + tt->minute = minute % 60; + hours_overflow = minute / 60; + if (tt->minute < 0) { + tt->minute += 60; + hours_overflow--; + } + + /* Add on the hours. */ + hour = tt->hour + hours + hours_overflow; + tt->hour = hour % 24; + days_overflow = hour / 24; + if (tt->hour < 0) { + tt->hour += 24; + days_overflow--; + } + + /* Add on the days. */ + day = tt->day + days + days_overflow; + if (day > 0) { + for (;;) { + days_in_month = icaltime_days_in_month (tt->month, tt->year); + if (day <= days_in_month) + break; + + tt->month++; + if (tt->month >= 13) { + tt->year++; + tt->month = 1; + } + + day -= days_in_month; + } + } else { + while (day <= 0) { + if (tt->month == 1) { + tt->year--; + tt->month = 12; + } else { + tt->month--; + } + + day += icaltime_days_in_month (tt->month, tt->year); + } + } + tt->day = day; +} + + +char* +icaltimezone_get_tzid (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return NULL. */ + if (!zone) + return NULL; + + if (!zone->tzid) + icaltimezone_load_builtin_timezone (zone); + + return zone->tzid; +} + + +char* +icaltimezone_get_location (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return NULL. */ + if (!zone) + return NULL; + + /* Note that for builtin timezones this comes from zones.tab so we don't + need to check the timezone is loaded here. */ + return zone->location; +} + + +char* +icaltimezone_get_tznames (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return NULL. */ + if (!zone) + return NULL; + + if (!zone->component) + icaltimezone_load_builtin_timezone (zone); + + return zone->tznames; +} + + +/** Returns the latitude of a builtin timezone. */ +double +icaltimezone_get_latitude (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return 0. */ + if (!zone) + return 0.0; + + /* Note that for builtin timezones this comes from zones.tab so we don't + need to check the timezone is loaded here. */ + return zone->latitude; +} + + +/** Returns the longitude of a builtin timezone. */ +double +icaltimezone_get_longitude (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return 0. */ + if (!zone) + return 0.0; + + /* Note that for builtin timezones this comes from zones.tab so we don't + need to check the timezone is loaded here. */ + return zone->longitude; +} + + +/** Returns the VTIMEZONE component of a timezone. */ +icalcomponent* +icaltimezone_get_component (icaltimezone *zone) +{ + /* If this is a floating time, without a timezone, return NULL. */ + if (!zone) + return NULL; + + if (!zone->component) + icaltimezone_load_builtin_timezone (zone); + + return zone->component; +} + + +/** Sets the VTIMEZONE component of an icaltimezone, initializing the + tzid, location & tzname fields. It returns 1 on success or 0 on + failure, i.e. no TZID was found. */ +int +icaltimezone_set_component (icaltimezone *zone, + icalcomponent *comp) +{ + icaltimezone_reset (zone); + return icaltimezone_get_vtimezone_properties (zone, comp); +} + + +icalarray* +icaltimezone_array_new (void) +{ + return icalarray_new (sizeof (icaltimezone), 16); +} + + +void +icaltimezone_array_append_from_vtimezone (icalarray *timezones, + icalcomponent *child) +{ + icaltimezone zone; + + icaltimezone_init (&zone); + if (icaltimezone_get_vtimezone_properties (&zone, child)) + icalarray_append (timezones, &zone); +} + + +void +icaltimezone_array_free (icalarray *timezones) +{ + icaltimezone *zone; + int i; + + if ( timezones ) + { + for (i = 0; i < timezones->num_elements; i++) { + zone = icalarray_element_at (timezones, i); + icaltimezone_free (zone, 0); + } + + icalarray_free (timezones); + } +} + + +/* + * BUILTIN TIMEZONE HANDLING + */ + + +/** Returns an icalarray of icaltimezone structs, one for each builtin + timezone. This will load and parse the zones.tab file to get the + timezone names and their coordinates. It will not load the + VTIMEZONE data for any timezones. */ +icalarray* +icaltimezone_get_builtin_timezones (void) +{ + if (!builtin_timezones) + icaltimezone_init_builtin_timezones (); + + return builtin_timezones; +} + +/** Release builtin timezone memory */ +void +icaltimezone_free_builtin_timezones(void) +{ + icaltimezone_array_free(builtin_timezones); +} + + +/** Returns a single builtin timezone, given its Olson city name. */ +icaltimezone* +icaltimezone_get_builtin_timezone (const char *location) +{ + icaltimezone *zone; + int lower, upper, middle, cmp; + char *zone_location; + + if (!location || !location[0]) + return NULL; + + if (!strcmp (location, "UTC")) + return &utc_timezone; + + if (!builtin_timezones) + icaltimezone_init_builtin_timezones (); + + /* Do a simple binary search. */ + lower = middle = 0; + upper = builtin_timezones->num_elements; + + while (lower < upper) { + middle = (lower + upper) / 2; + zone = icalarray_element_at (builtin_timezones, middle); + zone_location = icaltimezone_get_location (zone); + cmp = strcmp (location, zone_location); + if (cmp == 0) + return zone; + else if (cmp < 0) + upper = middle; + else + lower = middle + 1; + } + + return NULL; +} + + +/** Returns a single builtin timezone, given its TZID. */ +icaltimezone* +icaltimezone_get_builtin_timezone_from_tzid (const char *tzid) +{ + int num_slashes = 0; + const char *p, *zone_tzid; + icaltimezone *zone; + + if (!tzid || !tzid[0]) + return NULL; + + /* Check that the TZID starts with our unique prefix. */ + if (strncmp (tzid, TZID_PREFIX, TZID_PREFIX_LEN)) + return NULL; + + /* Get the location, which is after the 3rd '/' character. */ + p = tzid; + for (p = tzid; *p; p++) { + if (*p == '/') { + num_slashes++; + if (num_slashes == 3) + break; + } + } + + if (num_slashes != 3) + return NULL; + + p++; + + /* Now we can use the function to get the builtin timezone from the + location string. */ + zone = icaltimezone_get_builtin_timezone (p); + if (!zone) + return NULL; + + /* Check that the builtin TZID matches exactly. We don't want to return + a different version of the VTIMEZONE. */ + zone_tzid = icaltimezone_get_tzid (zone); + if (!strcmp (zone_tzid, tzid)) + return zone; + else + return NULL; +} + + +/** Returns the special UTC timezone. */ +icaltimezone* +icaltimezone_get_utc_timezone (void) +{ + if (!builtin_timezones) + icaltimezone_init_builtin_timezones (); + + return &utc_timezone; +} + + + +/** This initializes the builtin timezone data, i.e. the + builtin_timezones array and the special UTC timezone. It should be + called before any code that uses the timezone functions. */ +static void +icaltimezone_init_builtin_timezones (void) +{ + /* Initialize the special UTC timezone. */ + utc_timezone.tzid = "UTC"; + + icaltimezone_parse_zone_tab (); +} + + +/** This parses the zones.tab file containing the names and locations + of the builtin timezones. It creates the builtin_timezones array + which is an icalarray of icaltimezone structs. It only fills in the + location, latitude and longtude fields; the rest are left + blank. The VTIMEZONE component is loaded later if it is needed. The + timezones in the zones.tab file are sorted by their name, which is + useful for binary searches. */ +static void +icaltimezone_parse_zone_tab (void) +{ + char *filename; + FILE *fp; + char buf[1024]; /* Used to store each line of zones.tab as it is read. */ + char location[1024]; /* Stores the city name when parsing buf. */ + unsigned int filename_len; + int latitude_degrees, latitude_minutes, latitude_seconds; + int longitude_degrees, longitude_minutes, longitude_seconds; + icaltimezone zone; + + icalerror_assert (builtin_timezones == NULL, + "Parsing zones.tab file multiple times"); + + builtin_timezones = icalarray_new (sizeof (icaltimezone), 32); + + filename_len = strlen (get_zone_directory()) + strlen (ZONES_TAB_FILENAME) + + 2; + + filename = (char*) malloc (filename_len); + if (!filename) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + snprintf (filename, filename_len, "%s/%s", get_zone_directory(), + ZONES_TAB_FILENAME); + + fp = fopen (filename, "r"); + free (filename); + if (!fp) { + icalerror_set_errno(ICAL_FILE_ERROR); + return; + } + + while (fgets (buf, sizeof(buf), fp)) { + if (*buf == '#') continue; + + /* The format of each line is: "latitude longitude location". */ + if (sscanf (buf, "%4d%2d%2d %4d%2d%2d %s", + &latitude_degrees, &latitude_minutes, + &latitude_seconds, + &longitude_degrees, &longitude_minutes, + &longitude_seconds, + location) != 7) { + fprintf (stderr, "Invalid timezone description line: %s\n", buf); + continue; + } + + icaltimezone_init (&zone); + zone.location = strdup (location); + + if (latitude_degrees >= 0) + zone.latitude = (double) latitude_degrees + + (double) latitude_minutes / 60 + + (double) latitude_seconds / 3600; + else + zone.latitude = (double) latitude_degrees + - (double) latitude_minutes / 60 + - (double) latitude_seconds / 3600; + + if (longitude_degrees >= 0) + zone.longitude = (double) longitude_degrees + + (double) longitude_minutes / 60 + + (double) longitude_seconds / 3600; + else + zone.longitude = (double) longitude_degrees + - (double) longitude_minutes / 60 + - (double) longitude_seconds / 3600; + + icalarray_append (builtin_timezones, &zone); + +#if 0 + printf ("Found zone: %s %f %f\n", + location, zone.latitude, zone.longitude); +#endif + } + + fclose (fp); +} + + +/** Loads the builtin VTIMEZONE data for the given timezone. */ +static void +icaltimezone_load_builtin_timezone (icaltimezone *zone) +{ + char *filename; + unsigned int filename_len; + FILE *fp; + icalparser *parser; + icalcomponent *comp, *subcomp; + + /* If the location isn't set, it isn't a builtin timezone. */ + if (!zone->location || !zone->location[0]) + return; + + filename_len = strlen (get_zone_directory()) + strlen (zone->location) + 6; + + filename = (char*) malloc (filename_len); + if (!filename) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + snprintf (filename, filename_len, "%s/%s.ics", get_zone_directory(), + zone->location); + + fp = fopen (filename, "r"); + free (filename); + if (!fp) { + icalerror_set_errno(ICAL_FILE_ERROR); + return; + } + + + /* ##### B.# Sun, 11 Nov 2001 04:04:29 +1100 + this is where the MALFORMEDDATA error is being set, after the call to 'icalparser_parse' + fprintf(stderr, "** WARNING ** %s: %d %s\n", __FILE__, __LINE__, icalerror_strerror(icalerrno)); + */ + + parser = icalparser_new (); + icalparser_set_gen_data (parser, fp); + comp = icalparser_parse (parser, icaltimezone_load_get_line_fn); + icalparser_free (parser); + fclose (fp); + + + + /* Find the VTIMEZONE component inside the VCALENDAR. There should be 1. */ + subcomp = icalcomponent_get_first_component (comp, + ICAL_VTIMEZONE_COMPONENT); + if (!subcomp) { + icalerror_set_errno(ICAL_PARSE_ERROR); + return; + } + + icaltimezone_get_vtimezone_properties (zone, subcomp); + + icalcomponent_remove_component(comp,subcomp); + + icalcomponent_free(comp); + +} + + +/** Callback used from icalparser_parse() */ +static char * +icaltimezone_load_get_line_fn (char *s, + size_t size, + void *data) +{ + return fgets (s, size, (FILE*) data); +} + + + + +/* + * DEBUGGING + */ + +/** + * This outputs a list of timezone changes for the given timezone to the + * given file, up to the maximum year given. We compare this output with the + * output from 'vzic --dump-changes' to make sure that we are consistent. + * (vzic is the Olson timezone database to VTIMEZONE converter.) + * + * The output format is: + * + * Zone-Name [tab] Date [tab] Time [tab] UTC-Offset + * + * The Date and Time fields specify the time change in UTC. + * + * The UTC Offset is for local (wall-clock) time. It is the amount of time + * to add to UTC to get local time. + */ +int +icaltimezone_dump_changes (icaltimezone *zone, + int max_year, + FILE *fp) +{ + static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + icaltimezonechange *zone_change; + int change_num; + char buffer[8]; + + /* Make sure the changes array is expanded up to the given time. */ + icaltimezone_ensure_coverage (zone, max_year); + +#if 0 + printf ("Num changes: %i\n", zone->changes->num_elements); +#endif + + change_num = 0; + for (change_num = 0; change_num < zone->changes->num_elements; change_num++) { + zone_change = icalarray_element_at (zone->changes, change_num); + + if (zone_change->year > max_year) + break; + + fprintf (fp, "%s\t%2i %s %04i\t%2i:%02i:%02i", + zone->location, + zone_change->day, months[zone_change->month - 1], + zone_change->year, + zone_change->hour, zone_change->minute, zone_change->second); + + /* Wall Clock Time offset from UTC. */ + format_utc_offset (zone_change->utc_offset, buffer); + fprintf (fp, "\t%s", buffer); + + fprintf (fp, "\n"); + } + return 1; +} + + +/** This formats a UTC offset as "+HHMM" or "+HHMMSS". + buffer should have space for 8 characters. */ +static void +format_utc_offset (int utc_offset, + char *buffer) +{ + char *sign = "+"; + int hours, minutes, seconds; + + if (utc_offset < 0) { + utc_offset = -utc_offset; + sign = "-"; + } + + hours = utc_offset / 3600; + minutes = (utc_offset % 3600) / 60; + seconds = utc_offset % 60; + + /* Sanity check. Standard timezone offsets shouldn't be much more than 12 + hours, and daylight saving shouldn't change it by more than a few hours. + (The maximum offset is 15 hours 56 minutes at present.) */ + if (hours < 0 || hours >= 24 || minutes < 0 || minutes >= 60 + || seconds < 0 || seconds >= 60) { + fprintf (stderr, "Warning: Strange timezone offset: H:%i M:%i S:%i\n", + hours, minutes, seconds); + } + + if (seconds == 0) + sprintf (buffer, "%s%02i%02i", sign, hours, minutes); + else + sprintf (buffer, "%s%02i%02i%02i", sign, hours, minutes, seconds); +} + +static char* get_zone_directory(void) +{ + return zone_files_directory == NULL ? ZONEINFO_DIRECTORY : zone_files_directory; +} + +void set_zone_directory(char *path) +{ + zone_files_directory = malloc(strlen(path)+1); + if ( zone_files_directory != NULL ) + { + strcpy(zone_files_directory,path); + } +} + +void free_zone_directory(void) +{ + if ( zone_files_directory != NULL ) + { + free(zone_files_directory); + } +} diff --git a/libical/src/libical/icaltimezone.h b/libical/src/libical/icaltimezone.h new file mode 100644 index 0000000..08af2c1 --- a/dev/null +++ b/libical/src/libical/icaltimezone.h @@ -0,0 +1,167 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/*====================================================================== + FILE: icaltimezone.h + CREATOR: Damon Chaplin 15 March 2001 + + + $Id$ + $Locker$ + + (C) COPYRIGHT 2001, Damon Chaplin + + 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/ + + +======================================================================*/ +/** + * @file icaltimezone.h + * @brief timezone handling routines + */ + +#ifndef ICALTIMEZONE_H +#define ICALTIMEZONE_H + +#include <stdio.h> /* For FILE* */ +#include "icaltime.h" +#include "icalarray.h" +#include "icalcomponent.h" + + +#ifndef ICALTIMEZONE_DEFINED +#define ICALTIMEZONE_DEFINED +/** @brief An opaque struct representing a timezone. + * We declare this here to avoid a circular dependancy. + */ +typedef struct _icaltimezone icaltimezone; +#endif + +/** + * @par Creating/Destroying individual icaltimezones. + */ + +/** Creates a new icaltimezone. */ +icaltimezone *icaltimezone_new (void); + +/** Frees all memory used for the icaltimezone. Set free_struct to free the + icaltimezone struct as well. */ +void icaltimezone_free (icaltimezone *zone, + int free_struct); + + +/** + * @par Accessing timezones. + */ + +/** Free any builtin timezone information **/ +void icaltimezone_free_builtin_timezones(void); + +/** Returns the array of builtin icaltimezones. */ +icalarray* icaltimezone_get_builtin_timezones (void); + +/** Returns a single builtin timezone, given its Olson city name. */ +icaltimezone* icaltimezone_get_builtin_timezone (const char *location); + +/** Returns a single builtin timezone, given its TZID. */ +icaltimezone* icaltimezone_get_builtin_timezone_from_tzid (const char *tzid); + +/** Returns the UTC timezone. */ +icaltimezone* icaltimezone_get_utc_timezone (void); + +/** Returns the TZID of a timezone. */ +char* icaltimezone_get_tzid (icaltimezone *zone); + +/** Returns the city name of a timezone. */ +char* icaltimezone_get_location (icaltimezone *zone); + +/** Returns the TZNAME properties used in the latest STANDARD and DAYLIGHT + components. If they are the same it will return just one, e.g. "LMT". + If they are different it will format them like "EST/EDT". Note that this + may also return NULL. */ +char* icaltimezone_get_tznames (icaltimezone *zone); + +/** Returns the latitude of a builtin timezone. */ +double icaltimezone_get_latitude (icaltimezone *zone); + +/** Returns the longitude of a builtin timezone. */ +double icaltimezone_get_longitude (icaltimezone *zone); + +/** Returns the VTIMEZONE component of a timezone. */ +icalcomponent* icaltimezone_get_component (icaltimezone *zone); + +/** Sets the VTIMEZONE component of an icaltimezone, initializing the tzid, + location & tzname fields. It returns 1 on success or 0 on failure, i.e. + no TZID was found. */ +int icaltimezone_set_component (icaltimezone *zone, + icalcomponent *comp); + +/** + * @par Converting times between timezones. + */ + +void icaltimezone_convert_time (struct icaltimetype *tt, + icaltimezone *from_zone, + icaltimezone *to_zone); + + +/** + * @par Getting offsets from UTC. + */ + +/** Calculates the UTC offset of a given local time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int icaltimezone_get_utc_offset (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight); + +/** Calculates the UTC offset of a given UTC time in the given + timezone. It is the number of seconds to add to UTC to get local + time. The is_daylight flag is set to 1 if the time is in + daylight-savings time. */ +int icaltimezone_get_utc_offset_of_utc_time (icaltimezone *zone, + struct icaltimetype *tt, + int *is_daylight); + + + +/* + * Handling arrays of timezones. Mainly for internal use. + */ +icalarray* icaltimezone_array_new (void); + +void icaltimezone_array_append_from_vtimezone (icalarray *timezones, + icalcomponent *child); +void icaltimezone_array_free (icalarray *timezones); + + +/* + * @par Handling the default location the timezone files + */ + +/** Set the directory to look for the zonefiles */ +void set_zone_directory(char *path); + +/** Free memory dedicated to the zonefile directory */ +void free_zone_directory(void); + +/* + * @par Debugging Output. + */ + +/** Dumps information about changes in the timezone up to and including + max_year. */ +int icaltimezone_dump_changes (icaltimezone *zone, + int max_year, + FILE *fp); + +#endif /* ICALTIMEZONE_H */ diff --git a/libical/src/libical/icaltypes.c b/libical/src/libical/icaltypes.c index 8c67deb..19719f8 100644 --- a/libical/src/libical/icaltypes.c +++ b/libical/src/libical/icaltypes.c @@ -1,285 +1,191 @@ /* -*- Mode: C -*- ====================================================================== FILE: icaltypes.c CREATOR: eric 16 May 1999 $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 icaltypes.c ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "icaltypes.h" #include "icalerror.h" #include "icalmemory.h" #include <stdlib.h> /* for malloc and abs() */ #include <errno.h> /* for errno */ #include <string.h> /* for icalmemory_strdup */ #include <assert.h> -int snprintf(char *str, size_t n, char const *fmt, ...); +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif #define TEMP_MAX 1024 -void* -icalattachtype_get_data (struct icalattachtype* type); -struct icalattachtype* -icalattachtype_new() +int icaltriggertype_is_null_trigger(struct icaltriggertype tr) { - struct icalattachtype* v; - - if ( ( v = (struct icalattachtype*) - malloc(sizeof(struct icalattachtype))) == 0) { - errno = ENOMEM; - return 0; + if(icaltime_is_null_time(tr.time) && + icaldurationtype_is_null_duration(tr.duration)){ + return 1; } - v->refcount = 1; - - v->binary = 0; - v->owns_binary = 0; - v->base64 = 0; - //fprintf(stderr,"setting base 64 to 0 \n"); - - v->owns_base64 = 0; - - v->url = 0; - - return v; + return 0; } - - -void -icalattachtype_free(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - v->refcount--; - - if (v->refcount <= 0){ - - if (v->base64 != 0 && v->owns_base64 != 0){ - int val = v->base64 ; - if ( val < 255 ) { - fprintf(stderr,"Possible error in attachment processing (%d)\nPocssible solution: Remove attachment from file.\n",val ); - } - free(v->base64); - } - - if (v->binary != 0 && v->owns_binary != 0){ - free(v->binary); - } - - if (v->url != 0){ - free(v->url); - } - - free(v); - } -} - -void icalattachtype_add_reference(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - v->refcount++; -} - -void icalattachtype_set_url(struct icalattachtype* v, char* url) +int icaltriggertype_is_bad_trigger(struct icaltriggertype tr) { - icalerror_check_arg( (v!=0),"v"); - - if (v->url != 0){ - free (v->url); + if(icaldurationtype_is_bad_duration(tr.duration)){ + return 1; } - v->url = icalmemory_strdup(url); - - /* HACK This routine should do something if icalmemory_strdup returns NULL */ - -} - -char* icalattachtype_get_url(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - return v->url; -} - -void icalattachtype_set_base64(struct icalattachtype* v, char* base64, - int owns) -{ - //fprintf(stderr,"1setbase64 %d \n", base64 ); - icalerror_check_arg( (v!=0),"v"); - //fprintf(stderr,"setbase64 %d \n", base64 ); - v->base64 = base64; - v->owns_base64 = !(owns != 0 ); - -} - -char* icalattachtype_get_base64(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - return v->base64; + return 0; } -void icalattachtype_set_binary(struct icalattachtype* v, char* binary, - int owns) +struct icaltriggertype icaltriggertype_from_int(const int reltime) { - icalerror_check_arg( (v!=0),"v"); + struct icaltriggertype tr; - v->binary = binary; - v->owns_binary = !(owns != 0 ); + tr.time = icaltime_null_time(); + tr.duration = icaldurationtype_from_int(reltime); + return tr; } -void* icalattachtype_get_binary(struct icalattachtype* v) -{ - icalerror_check_arg( (v!=0),"v"); - return v->binary; -} - -int icaltriggertype_is_null_trigger(struct icaltriggertype tr) -{ - if(icaltime_is_null_time(tr.time) && - icaldurationtype_is_null_duration(tr.duration)){ - return 1; - } - - return 0; -} - struct icaltriggertype icaltriggertype_from_string(const char* str) { struct icaltriggertype tr, null_tr; icalerrorstate es; icalerrorenum e; tr.time= icaltime_null_time(); tr.duration = icaldurationtype_from_int(0); null_tr = tr; if(str == 0) goto error; - /* Surpress errors so a failure in icaltime_from_string() does not cause an abort */ + /* Suppress errors so a failure in icaltime_from_string() does not cause an abort */ es = icalerror_get_error_state(ICAL_MALFORMEDDATA_ERROR); icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,ICAL_ERROR_NONFATAL); e = icalerrno; icalerror_set_errno(ICAL_NO_ERROR); tr.time = icaltime_from_string(str); if (icaltime_is_null_time(tr.time)){ tr.duration = icaldurationtype_from_string(str); - if(icaldurationtype_as_int(tr.duration) == 0) goto error; + if (icaldurationtype_is_bad_duration(tr.duration)) goto error; } icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); icalerror_set_errno(e); return tr; error: icalerror_set_error_state(ICAL_MALFORMEDDATA_ERROR,es); icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return null_tr; + return tr; } struct icalreqstattype icalreqstattype_from_string(const char* str) { const char *p1,*p2; struct icalreqstattype stat; - int major, minor; + short major=0, minor=0; icalerror_check_arg((str != 0),"str"); stat.code = ICAL_UNKNOWN_STATUS; stat.debug = 0; stat.desc = 0; /* Get the status numbers */ - sscanf(str, "%d.%d",&major, &minor); + sscanf(str, "%hd.%hd",&major, &minor); if (major <= 0 || minor < 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return stat; } stat.code = icalenum_num_to_reqstat(major, minor); if (stat.code == ICAL_UNKNOWN_STATUS){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return stat; } p1 = strchr(str,';'); if (p1 == 0){ /* icalerror_set_errno(ICAL_BADARG_ERROR);*/ return stat; } /* Just ignore the second clause; it will be taken from inside the library */ p2 = strchr(p1+1,';'); if (p2 != 0 && *p2 != 0){ stat.debug = p2+1; } return stat; } const char* icalreqstattype_as_string(struct icalreqstattype stat) { char *temp; temp = (char*)icalmemory_tmp_buffer(TEMP_MAX); icalerror_check_arg_rz((stat.code != ICAL_UNKNOWN_STATUS),"Status"); if (stat.desc == 0){ stat.desc = icalenum_reqstat_desc(stat.code); } if(stat.debug != 0){ snprintf(temp,TEMP_MAX,"%d.%d;%s;%s", icalenum_reqstat_major(stat.code), icalenum_reqstat_minor(stat.code), stat.desc, stat.debug); } else { snprintf(temp,TEMP_MAX,"%d.%d;%s", icalenum_reqstat_major(stat.code), icalenum_reqstat_minor(stat.code), stat.desc); } return temp; } diff --git a/libical/src/libical/icaltypes.h b/libical/src/libical/icaltypes.h index d61b9f3..1e5c5e0 100644 --- a/libical/src/libical/icaltypes.h +++ b/libical/src/libical/icaltypes.h @@ -1,138 +1,107 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icaltypes.h CREATOR: eric 20 March 1999 (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 icaltypes.h ======================================================================*/ #ifndef ICALTYPES_H #define ICALTYPES_H #include <time.h> #include "icalenums.h" #include "icaltime.h" #include "icalduration.h" #include "icalperiod.h" -/* This type type should probably be an opaque type... */ -struct icalattachtype -{ - void* binary; - int owns_binary; - - char* base64; - int owns_base64; - - char* url; - - int refcount; - -}; - -/* converts base64 to binary, fetches url and stores as binary, or - just returns data */ - -struct icalattachtype* icalattachtype_new(void); -void icalattachtype_add_reference(struct icalattachtype* v); -void icalattachtype_free(struct icalattachtype* v); - -void icalattachtype_set_url(struct icalattachtype* v, char* url); -char* icalattachtype_get_url(struct icalattachtype* v); - -void icalattachtype_set_base64(struct icalattachtype* v, char* base64, - int owns); -char* icalattachtype_get_base64(struct icalattachtype* v); - -void icalattachtype_set_binary(struct icalattachtype* v, char* binary, - int owns); -void* icalattachtype_get_binary(struct icalattachtype* v); - struct icalgeotype { float lat; float lon; }; struct icaldatetimeperiodtype { struct icaltimetype time; struct icalperiodtype period; }; struct icaltriggertype { struct icaltimetype time; struct icaldurationtype duration; }; +struct icaltriggertype icaltriggertype_from_int(const int reltime); struct icaltriggertype icaltriggertype_from_string(const char* str); int icaltriggertype_is_null_trigger(struct icaltriggertype tr); +int icaltriggertype_is_bad_trigger(struct icaltriggertype tr); /* struct icalreqstattype. This struct contains two string pointers, but don't try to free either of them. The "desc" string is a pointer to a static table inside the library. Don't try to free it. The "debug" string is a pointer into the string that the called passed into to icalreqstattype_from_string. Don't try to free it either, and don't use it after the original string has been freed. BTW, you would get that original string from *icalproperty_get_requeststatus() or icalvalue_get_text(), when operating on a the value of a request_status property. */ struct icalreqstattype { icalrequeststatus code; const char* desc; const char* debug; }; struct icalreqstattype icalreqstattype_from_string(const char* str); const char* icalreqstattype_as_string(struct icalreqstattype); struct icaltimezonephase { const char* tzname; int is_stdandard; /* 1 = standard tme, 0 = daylight savings time */ struct icaltimetype dtstart; int offsetto; int tzoffsetfrom; const char* comment; struct icaldatetimeperiodtype rdate; const char* rrule; }; struct icaltimezonetype { const char* tzid; struct icaltimetype last_mod; const char* tzurl; /* Array of phases. The end of the array is a phase with tzname == 0 */ struct icaltimezonephase *phases; }; void icaltimezonetype_free(struct icaltimezonetype tzt); #endif /* !ICALTYPES_H */ diff --git a/libical/src/libical/icalvalue.c b/libical/src/libical/icalvalue.c index eb5476e..4c67136 100644 --- a/libical/src/libical/icalvalue.c +++ b/libical/src/libical/icalvalue.c @@ -1,1215 +1,1309 @@ -/* -*- Mode: C -*- */ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vi:set ts=4 sts=4 sw=4 expandtab : */ /*====================================================================== FILE: icalvalue.c CREATOR: eric 02 May 1999 $Id$ (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 icalvalue.c Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include "icalerror.h" #include "icalmemory.h" #include "icalparser.h" #include "icalenums.h" #include "icalvalueimpl.h" #include <stdlib.h> /* for malloc */ #include <stdio.h> /* for sprintf */ #include <string.h> /* For memset, others */ #include <stddef.h> /* For offsetof() macro */ #include <errno.h> #include <time.h> /* for mktime */ #include <stdlib.h> /* for atoi and atof */ #include <limits.h> /* for SHRT_MAX */ -int snprintf(char *str, size_t n, char const *fmt, ...); +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif #if _MAC_OS_ #include "icalmemory_strdup.h" #endif #define TMP_BUF_SIZE 1024 -void print_datetime_to_string(char* str, struct icaltimetype *data); -void print_date_to_string(char* str, struct icaltimetype *data); -void print_time_to_string(char* str, struct icaltimetype *data); -void print_recur_to_string(char* str, struct icaltimetype *data); +void print_datetime_to_string(char* str, const struct icaltimetype *data); +void print_date_to_string(char* str, const struct icaltimetype *data); +void print_time_to_string(char* str, const struct icaltimetype *data); struct icalvalue_impl* icalvalue_new_impl(icalvalue_kind kind){ struct icalvalue_impl* v; + if (!icalvalue_kind_is_valid(kind)) + return NULL; + if ( ( v = (struct icalvalue_impl*) malloc(sizeof(struct icalvalue_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } strcpy(v->id,"val"); v->kind = kind; v->size = 0; v->parent = 0; v->x_value = 0; memset(&(v->data),0,sizeof(v->data)); return v; } icalvalue* icalvalue_new (icalvalue_kind kind) { return (icalvalue*)icalvalue_new_impl(kind); } -icalvalue* icalvalue_new_clone(icalvalue* value){ - +icalvalue* icalvalue_new_clone(const icalvalue* old) { struct icalvalue_impl* new; - struct icalvalue_impl* old = (struct icalvalue_impl*)value; new = icalvalue_new_impl(old->kind); if (new == 0){ return 0; } - strcpy(new->id, old->id); new->kind = old->kind; new->size = old->size; switch (new->kind){ - - /* The contents of the attach value may or may not be owned by the - * library. */ case ICAL_ATTACH_VALUE: case ICAL_BINARY_VALUE: { - /* HACK ugh. I don't feel like impleenting this */ - } + /* Hmm. We just ref the attach value, which may not be the right + * thing to do. We cannot quite copy the data, anyways, since we + * don't know how long it is. + */ + new->data.v_attach = old->data.v_attach; + if (new->data.v_attach) + icalattach_ref (new->data.v_attach); + break; + } + case ICAL_QUERY_VALUE: case ICAL_STRING_VALUE: case ICAL_TEXT_VALUE: case ICAL_CALADDRESS_VALUE: case ICAL_URI_VALUE: { if (old->data.v_string != 0) { new->data.v_string=icalmemory_strdup(old->data.v_string); if ( new->data.v_string == 0 ) { return 0; } } break; } case ICAL_RECUR_VALUE: { if(old->data.v_recur != 0){ new->data.v_recur = malloc(sizeof(struct icalrecurrencetype)); if(new->data.v_recur == 0){ return 0; } memcpy( new->data.v_recur, old->data.v_recur, sizeof(struct icalrecurrencetype)); } break; } + case ICAL_X_VALUE: + { + if (old->x_value != 0) { + new->x_value=icalmemory_strdup(old->x_value); + + if (new->x_value == 0) { + return 0; + } + } + + break; + } + default: { /* all of the other types are stored as values, not pointers, so we can just copy the whole structure. */ new->data = old->data; } } return new; } -char* icalmemory_strdup_and_dequote(const char* str) +static char* icalmemory_strdup_and_dequote(const char* str) { const char* p; char* out = (char*)malloc(sizeof(char) * strlen(str) +1); char* pout; if (out == 0){ return 0; } pout = out; for (p = str; *p!=0; p++){ if( *p == '\\') { p++; switch(*p){ case 0: { *pout = '\0'; break; } case 'n': + case 'N': { *pout = '\n'; break; } - case 'N': + case 't': + case 'T': { - *pout = '\n'; + *pout = '\t'; + break; + } + case 'r': + case 'R': + { + *pout = '\r'; + break; + } + case 'b': + case 'B': + { + *pout = '\b'; + break; + } + case 'f': + case 'F': + { + *pout = '\f'; break; } - case '\\': - case ',': case ';': + case ',': + case '"': + case '\\': { *pout = *p; break; } default: { *pout = ' '; } } } else { *pout = *p; } pout++; } *pout = '\0'; return out; } +/* + * FIXME + * + * This is a bad API, as it forces callers to specify their own X type. + * This function should take care of this by itself. + */ +static icalvalue* icalvalue_new_enum(icalvalue_kind kind, int x_type, const char* str) { - int e = icalproperty_string_to_enum(str); + int e = icalproperty_kind_and_string_to_enum(kind, str); struct icalvalue_impl *value; if(e != 0 && icalproperty_enum_belongs_to_property( icalproperty_value_kind_to_kind(kind),e)) { value = icalvalue_new_impl(kind); value->data.v_enum = e; } else { /* Make it an X value */ value = icalvalue_new_impl(kind); value->data.v_enum = x_type; icalvalue_set_x(value,str); } return value; } icalvalue* icalvalue_new_from_string_with_error(icalvalue_kind kind,const char* str,icalproperty** error) { struct icalvalue_impl *value = 0; - struct icalattachtype *attach = 0; icalerror_check_arg_rz(str!=0,"str"); if (error != 0){ *error = 0; } switch (kind){ case ICAL_ATTACH_VALUE: - attach = icalattachtype_new(); - value = icalvalue_new_attach( attach ); - icalattachtype_free( attach ); - icalattachtype_set_url( value->data.v_attach, str ); - break; - case ICAL_BINARY_VALUE: + { + icalattach *attach; + + attach = icalattach_new_from_url (str); + if (!attach) + break; + + value = icalvalue_new_attach (attach); + icalattach_unref (attach); + break; + } + + case ICAL_BINARY_VALUE: case ICAL_BOOLEAN_VALUE: { /* HACK */ value = 0; if (error != 0){ char temp[TMP_BUF_SIZE]; sprintf(temp,"%s Values are not implemented", - icalparameter_kind_to_string(kind)); + icalvalue_kind_to_string(kind)); *error = icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype( ICAL_XLICERRORTYPE_VALUEPARSEERROR), 0); } break; } case ICAL_TRANSP_VALUE: - value = icalvalue_new_enum(kind, ICAL_TRANSP_X,str); + value = icalvalue_new_enum(kind, (int)ICAL_TRANSP_X,str); break; case ICAL_METHOD_VALUE: - value = icalvalue_new_enum(kind, ICAL_METHOD_X,str); + value = icalvalue_new_enum(kind, (int)ICAL_METHOD_X,str); break; case ICAL_STATUS_VALUE: - value = icalvalue_new_enum(kind, ICAL_STATUS_X,str); + value = icalvalue_new_enum(kind, (int)ICAL_STATUS_X,str); break; case ICAL_ACTION_VALUE: - value = icalvalue_new_enum(kind, ICAL_ACTION_X,str); + value = icalvalue_new_enum(kind, (int)ICAL_ACTION_X,str); break; + + case ICAL_QUERY_VALUE: + value = icalvalue_new_query(str); + break; + case ICAL_CLASS_VALUE: - value = icalvalue_new_enum(kind, ICAL_CLASS_X,str); + value = icalvalue_new_enum(kind, (int)ICAL_CLASS_X,str); break; case ICAL_INTEGER_VALUE: - { value = icalvalue_new_integer(atoi(str)); break; - } case ICAL_FLOAT_VALUE: - { - value = icalvalue_new_float((float )atof(str)); + value = icalvalue_new_float((float)atof(str)); break; - } - + case ICAL_UTCOFFSET_VALUE: { - value = icalparser_parse_value(kind,str,(icalcomponent*)0); + int t,utcoffset, hours, minutes, seconds; + /* treat the UTCOFSET string a a decimal number, disassemble its digits + and reconstruct it as sections */ + t = strtol(str,0,10); + /* add phantom seconds field */ + if(abs(t)<9999){t *= 100; } + hours = (t/10000); + minutes = (t-hours*10000)/100; + seconds = (t-hours*10000-minutes*100); + utcoffset = hours*3600+minutes*60+seconds; + + value = icalvalue_new_utcoffset(utcoffset); + break; } case ICAL_TEXT_VALUE: { char* dequoted_str = icalmemory_strdup_and_dequote(str); value = icalvalue_new_text(dequoted_str); free(dequoted_str); break; } - case ICAL_STRING_VALUE: - { value = icalvalue_new_string(str); break; - } case ICAL_CALADDRESS_VALUE: - { value = icalvalue_new_caladdress(str); break; - } case ICAL_URI_VALUE: - { value = icalvalue_new_uri(str); break; - } - case ICAL_GEO_VALUE: - { value = 0; /* HACK */ if (error != 0){ char temp[TMP_BUF_SIZE]; sprintf(temp,"GEO Values are not implemented"); *error = icalproperty_vanew_xlicerror( - temp, - icalparameter_new_xlicerrortype( - ICAL_XLICERRORTYPE_VALUEPARSEERROR), - 0); + temp, + icalparameter_new_xlicerrortype( + ICAL_XLICERRORTYPE_VALUEPARSEERROR), + 0); } - + /*icalerror_warn("Parsing GEO properties is unimplmeneted");*/ - + break; - } case ICAL_RECUR_VALUE: { struct icalrecurrencetype rt; rt = icalrecurrencetype_from_string(str); if(rt.freq != ICAL_NO_RECURRENCE){ value = icalvalue_new_recur(rt); } break; } case ICAL_DATE_VALUE: case ICAL_DATETIME_VALUE: { struct icaltimetype tt; tt = icaltime_from_string(str); if(!icaltime_is_null_time(tt)){ value = icalvalue_new_impl(kind); value->data.v_time = tt; icalvalue_reset_kind(value); } break; } case ICAL_DATETIMEPERIOD_VALUE: { struct icaltimetype tt; struct icalperiodtype p; tt = icaltime_from_string(str); - p = icalperiodtype_from_string(str); - + if(!icaltime_is_null_time(tt)){ - value = icalvalue_new_datetime(tt); - } else if (!icalperiodtype_is_null_period(p)){ + value = icalvalue_new_datetime(tt); + break; + } + + p = icalperiodtype_from_string(str); + if (!icalperiodtype_is_null_period(p)){ value = icalvalue_new_period(p); } - + break; } case ICAL_DURATION_VALUE: { struct icaldurationtype dur = icaldurationtype_from_string(str); - if(icaldurationtype_is_null_duration(dur)){ - value = 0; - } else { + if (!icaldurationtype_is_bad_duration(dur)) { /* failed to parse */ value = icalvalue_new_duration(dur); } break; } case ICAL_PERIOD_VALUE: { struct icalperiodtype p; p = icalperiodtype_from_string(str); if(!icalperiodtype_is_null_period(p)){ value = icalvalue_new_period(p); } break; } case ICAL_TRIGGER_VALUE: { struct icaltriggertype tr = icaltriggertype_from_string(str); - if (!icaltriggertype_is_null_trigger(tr)){ + if (!icaltriggertype_is_bad_trigger(tr)) { value = icalvalue_new_trigger(tr); } break; } case ICAL_REQUESTSTATUS_VALUE: { struct icalreqstattype rst = icalreqstattype_from_string(str); if(rst.code != ICAL_UNKNOWN_STATUS){ value = icalvalue_new_requeststatus(rst); } break; } + + case ICAL_X_VALUE: + { + char* dequoted_str = icalmemory_strdup_and_dequote(str); + value = icalvalue_new_x(dequoted_str); + free(dequoted_str); + } + break; + default: { - if (error != 0 ){ char temp[TMP_BUF_SIZE]; snprintf(temp,TMP_BUF_SIZE,"Unknown type for \'%s\'",str); *error = icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype( ICAL_XLICERRORTYPE_VALUEPARSEERROR), 0); } icalerror_warn("icalvalue_new_from_string got an unknown value type"); value=0; } } if (error != 0 && *error == 0 && value == 0){ char temp[TMP_BUF_SIZE]; snprintf(temp,TMP_BUF_SIZE,"Failed to parse value: \'%s\'",str); *error = icalproperty_vanew_xlicerror( temp, icalparameter_new_xlicerrortype( ICAL_XLICERRORTYPE_VALUEPARSEERROR), 0); } return value; } icalvalue* icalvalue_new_from_string(icalvalue_kind kind,const char* str) { - return icalvalue_new_from_string_with_error(kind,str,(icalproperty*)0); + return icalvalue_new_from_string_with_error(kind,str,(icalproperty**)0); } void -icalvalue_free (icalvalue* value) +icalvalue_free (icalvalue* v) { - struct icalvalue_impl* v = (struct icalvalue_impl*)value; - - icalerror_check_arg_rv((value != 0),"value"); + icalerror_check_arg_rv((v != 0),"value"); #ifdef ICAL_FREE_ON_LIST_IS_ERROR icalerror_assert( (v->parent ==0),"This value is still attached to a property"); #else if(v->parent !=0){ return; } #endif if(v->x_value != 0){ free(v->x_value); } switch (v->kind){ - case ICAL_ATTACH_VALUE: - icalattachtype_free( v->data.v_attach ); + case ICAL_BINARY_VALUE: + case ICAL_ATTACH_VALUE: { + if (v->data.v_attach) { + icalattach_unref (v->data.v_attach); + v->data.v_attach = NULL; + } + break; - case ICAL_BINARY_VALUE: { - /* HACK ugh. This will be tough to implement */ } case ICAL_TEXT_VALUE: case ICAL_CALADDRESS_VALUE: case ICAL_URI_VALUE: + case ICAL_QUERY_VALUE: { if (v->data.v_string != 0) { free((void*)v->data.v_string); v->data.v_string = 0; } break; } case ICAL_RECUR_VALUE: { if(v->data.v_recur != 0){ free((void*)v->data.v_recur); v->data.v_recur = 0; } break; } default: { /* Nothing to do */ } } v->kind = ICAL_NO_VALUE; v->size = 0; v->parent = 0; memset(&(v->data),0,sizeof(v->data)); v->id[0] = 'X'; free(v); } int -icalvalue_is_valid (icalvalue* value) +icalvalue_is_valid (const icalvalue* value) { - /*struct icalvalue_impl* v = (struct icalvalue_impl*)value;*/ - if(value == 0){ return 0; } return 1; } -char* icalvalue_binary_as_ical_string(icalvalue* value) { +static char* icalvalue_binary_as_ical_string(const icalvalue* value) { const char* data; char* str; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_binary(value); str = (char*)icalmemory_tmp_buffer(60); sprintf(str,"icalvalue_binary_as_ical_string is not implemented yet"); return str; } -#ifndef _WIN32 + #define MAX_INT_DIGITS 12 /* Enough for 2^32 + sign*/ -char* icalvalue_int_as_ical_string(icalvalue* value) { +static char* icalvalue_int_as_ical_string(const icalvalue* value) { int data; char* str = (char*)icalmemory_tmp_buffer(MAX_INT_DIGITS); icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_integer(value); snprintf(str,MAX_INT_DIGITS,"%d",data); return str; } -#else -// snprintf not working on wintendo -#define MAX_INT_DIGITS 32 /* Enough for 2^32 + sign*/ -char* icalvalue_int_as_ical_string(icalvalue* value) { - - int data; - char* str = (char*)icalmemory_tmp_buffer(MAX_INT_DIGITS); - - icalerror_check_arg_rz( (value!=0),"value"); - - data = icalvalue_get_integer(value); - - sprintf(str,"%d",data); - - return str; -} - -#endif -char* icalvalue_utcoffset_as_ical_string(icalvalue* value) +static char* icalvalue_utcoffset_as_ical_string(const icalvalue* value) { int data,h,m,s; char sign; char* str = (char*)icalmemory_tmp_buffer(9); icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_utcoffset(value); if (abs(data) == data){ sign = '+'; } else { sign = '-'; } h = data/3600; m = (data - (h*3600))/ 60; s = (data - (h*3600) - (m*60)); - sprintf(str,"%c%02d%02d%02d",sign,abs(h),abs(m),abs(s)); + if (s > 0) + sprintf(str,"%c%02d%02d%02d",sign,abs(h),abs(m),abs(s)); + else + sprintf(str,"%c%02d%02d",sign,abs(h),abs(m)); return str; } -char* icalvalue_string_as_ical_string(icalvalue* value) { +static char* icalvalue_string_as_ical_string(const icalvalue* value) { const char* data; char* str = 0; icalerror_check_arg_rz( (value!=0),"value"); - - data = ((struct icalvalue_impl*)value)->data.v_string; + data = value->data.v_string; str = (char*)icalmemory_tmp_buffer(strlen(data)+1); strcpy(str,data); return str; } -char* icalvalue_recur_as_ical_string(icalvalue* value) +static char* icalvalue_recur_as_ical_string(const icalvalue* value) { - struct icalvalue_impl *impl = (struct icalvalue_impl*)value; - struct icalrecurrencetype *recur = impl->data.v_recur; + struct icalrecurrencetype *recur = value->data.v_recur; return icalrecurrencetype_as_string(recur); } -char* icalvalue_text_as_ical_string(icalvalue* value) { + /* @todo This is not RFC2445 compliant. + * The RFC only allows: + * TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B / %x5D-7E / NON-US-ASCII + * As such, \t\r\b\f are not allowed, not even escaped + */ +static char* icalvalue_text_as_ical_string(const icalvalue* value) { char *str; char *str_p; char *rtrn; const char *p; size_t buf_sz; - int line_length; - - line_length = 0; - buf_sz = strlen(((struct icalvalue_impl*)value)->data.v_string)+1; + buf_sz = strlen(value->data.v_string)+1; str_p = str = (char*)icalmemory_new_buffer(buf_sz); if (str_p == 0){ return 0; } - for(p=((struct icalvalue_impl*)value)->data.v_string; *p!=0; p++){ + for(p=value->data.v_string; *p!=0; p++){ switch(*p){ case '\n': { icalmemory_append_string(&str,&str_p,&buf_sz,"\\n"); - line_length+=3; break; } case '\t': { icalmemory_append_string(&str,&str_p,&buf_sz,"\\t"); - line_length+=3; break; } case '\r': { icalmemory_append_string(&str,&str_p,&buf_sz,"\\r"); - line_length+=3; break; } case '\b': { icalmemory_append_string(&str,&str_p,&buf_sz,"\\b"); - line_length+=3; break; } case '\f': { icalmemory_append_string(&str,&str_p,&buf_sz,"\\f"); - line_length+=3; break; } case ';': - case ',':{ + case ',': + case '"': + case '\\':{ icalmemory_append_char(&str,&str_p,&buf_sz,'\\'); icalmemory_append_char(&str,&str_p,&buf_sz,*p); - line_length+=3; break; } default: { icalmemory_append_char(&str,&str_p,&buf_sz,*p); - line_length++; } } - - if (line_length > 65 && *p == ' '){ - icalmemory_append_string(&str,&str_p,&buf_sz,"\n "); - line_length=0; - } - - - if (line_length > 75){ - icalmemory_append_string(&str,&str_p,&buf_sz,"\n "); - line_length=0; - } - } /* Assume the last character is not a '\0' and add one. We could check *str_p != 0, but that would be an uninitialized memory read. */ icalmemory_append_char(&str,&str_p,&buf_sz,'\0'); rtrn = icalmemory_tmp_copy(str); icalmemory_free_buffer(str); return rtrn; } -char* icalvalue_attach_as_ical_string(icalvalue* value) { - - struct icalattachtype *a; +static char* +icalvalue_attach_as_ical_string(const icalvalue* value) +{ + icalattach *a; char * str; icalerror_check_arg_rz( (value!=0),"value"); a = icalvalue_get_attach(value); - if (a->binary != 0) { - return icalvalue_binary_as_ical_string(value); - } else if (a->base64 != 0) { - str = (char*)icalmemory_tmp_buffer(strlen(a->base64)+1); - strcpy(str,a->base64); + if (icalattach_get_is_url (a)) { + const char *url; + + url = icalattach_get_url (a); + str = icalmemory_tmp_buffer (strlen (url) + 1); + strcpy (str, url); return str; - } else if (a->url != 0){ - icalvalue *v = icalvalue_new_text( a->url ); - char *icalstring = icalvalue_string_as_ical_string(v); - icalvalue_free( v ); - return icalstring; - } else { - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return 0; - } + } else + return icalvalue_binary_as_ical_string (value); } -char* icalvalue_duration_as_ical_string(icalvalue* value) { +static char* icalvalue_duration_as_ical_string(const icalvalue* value) { struct icaldurationtype data; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_duration(value); return icaldurationtype_as_ical_string(data); } -void print_time_to_string(char* str, struct icaltimetype *data) +void print_time_to_string(char* str, const struct icaltimetype *data) { char temp[20]; - if (data->is_utc == 1){ + if (icaltime_is_utc(*data)){ sprintf(temp,"%02d%02d%02dZ",data->hour,data->minute,data->second); } else { sprintf(temp,"%02d%02d%02d",data->hour,data->minute,data->second); } strcat(str,temp); } -void print_date_to_string(char* str, struct icaltimetype *data) +void print_date_to_string(char* str, const struct icaltimetype *data) { char temp[20]; sprintf(temp,"%04d%02d%02d",data->year,data->month,data->day); strcat(str,temp); } -char* icalvalue_date_as_ical_string(icalvalue* value) { +static char* icalvalue_date_as_ical_string(const icalvalue* value) { struct icaltimetype data; char* str; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_date(value); str = (char*)icalmemory_tmp_buffer(9); str[0] = 0; print_date_to_string(str,&data); return str; } -void print_datetime_to_string(char* str, struct icaltimetype *data) +void print_datetime_to_string(char* str, const struct icaltimetype *data) { print_date_to_string(str,data); strcat(str,"T"); print_time_to_string(str,data); - } -const char* icalvalue_datetime_as_ical_string(icalvalue* value) { +static const char* icalvalue_datetime_as_ical_string(const icalvalue* value) { struct icaltimetype data; char* str; icalvalue_kind kind = icalvalue_isa(value); icalerror_check_arg_rz( (value!=0),"value"); if( !(kind == ICAL_DATE_VALUE || kind == ICAL_DATETIME_VALUE )) { icalerror_set_errno(ICAL_BADARG_ERROR); return 0; } data = icalvalue_get_datetime(value); str = (char*)icalmemory_tmp_buffer(20); str[0] = 0; print_datetime_to_string(str,&data); return str; } -char* icalvalue_float_as_ical_string(icalvalue* value) { +static char* icalvalue_float_as_ical_string(const icalvalue* value) { float data; char* str; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_float(value); str = (char*)icalmemory_tmp_buffer(15); sprintf(str,"%f",data); return str; } -char* icalvalue_geo_as_ical_string(icalvalue* value) { +static char* icalvalue_geo_as_ical_string(const icalvalue* value) { struct icalgeotype data; char* str; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_geo(value); str = (char*)icalmemory_tmp_buffer(25); sprintf(str,"%f;%f",data.lat,data.lon); return str; } -const char* icalvalue_datetimeperiod_as_ical_string(icalvalue* value) { +static const char* icalvalue_datetimeperiod_as_ical_string(const icalvalue* value) { struct icaldatetimeperiodtype dtp = icalvalue_get_datetimeperiod(value); icalerror_check_arg_rz( (value!=0),"value"); if(!icaltime_is_null_time(dtp.time)){ return icaltime_as_ical_string(dtp.time); } else { return icalperiodtype_as_ical_string(dtp.period); } } -const char* icalvalue_period_as_ical_string(icalvalue* value) { +static const char* icalvalue_period_as_ical_string(const icalvalue* value) { struct icalperiodtype data; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_period(value); return icalperiodtype_as_ical_string(data); } -char* icalvalue_trigger_as_ical_string(icalvalue* value) { +static const char* icalvalue_trigger_as_ical_string(const icalvalue* value) { struct icaltriggertype data; icalerror_check_arg_rz( (value!=0),"value"); data = icalvalue_get_trigger(value); if(!icaltime_is_null_time(data.time)){ return icaltime_as_ical_string(data.time); } else { return icaldurationtype_as_ical_string(data.duration); } } const char* -icalvalue_as_ical_string (icalvalue* value) +icalvalue_as_ical_string(const icalvalue* value) { - struct icalvalue_impl* v = (struct icalvalue_impl*)value; - - v=v; - if(value == 0){ return 0; } - switch (v->kind){ + switch (value->kind){ case ICAL_ATTACH_VALUE: return icalvalue_attach_as_ical_string(value); case ICAL_BINARY_VALUE: return icalvalue_binary_as_ical_string(value); case ICAL_BOOLEAN_VALUE: case ICAL_INTEGER_VALUE: return icalvalue_int_as_ical_string(value); case ICAL_UTCOFFSET_VALUE: return icalvalue_utcoffset_as_ical_string(value); case ICAL_TEXT_VALUE: return icalvalue_text_as_ical_string(value); + case ICAL_QUERY_VALUE: + return icalvalue_string_as_ical_string(value); + case ICAL_STRING_VALUE: case ICAL_URI_VALUE: case ICAL_CALADDRESS_VALUE: return icalvalue_string_as_ical_string(value); case ICAL_DATE_VALUE: return icalvalue_date_as_ical_string(value); case ICAL_DATETIME_VALUE: return icalvalue_datetime_as_ical_string(value); case ICAL_DURATION_VALUE: return icalvalue_duration_as_ical_string(value); case ICAL_PERIOD_VALUE: return icalvalue_period_as_ical_string(value); case ICAL_DATETIMEPERIOD_VALUE: return icalvalue_datetimeperiod_as_ical_string(value); case ICAL_FLOAT_VALUE: return icalvalue_float_as_ical_string(value); case ICAL_GEO_VALUE: return icalvalue_geo_as_ical_string(value); case ICAL_RECUR_VALUE: return icalvalue_recur_as_ical_string(value); case ICAL_TRIGGER_VALUE: return icalvalue_trigger_as_ical_string(value); case ICAL_REQUESTSTATUS_VALUE: - return icalreqstattype_as_string(v->data.v_requeststatus); + return icalreqstattype_as_string(value->data.v_requeststatus); case ICAL_ACTION_VALUE: case ICAL_METHOD_VALUE: case ICAL_STATUS_VALUE: case ICAL_TRANSP_VALUE: case ICAL_CLASS_VALUE: - if(v->x_value !=0){ - return icalmemory_tmp_copy(v->x_value); + if(value->x_value !=0){ + return icalmemory_tmp_copy(value->x_value); } - return icalproperty_enum_to_string(v->data.v_enum); + return icalproperty_enum_to_string(value->data.v_enum); case ICAL_X_VALUE: - return icalmemory_tmp_copy(v->x_value); + if (value->x_value != 0) + return icalmemory_tmp_copy(value->x_value); + + /* FALLTHRU */ case ICAL_NO_VALUE: default: { return 0; } } } icalvalue_kind -icalvalue_isa (icalvalue* value) +icalvalue_isa (const icalvalue* value) { - struct icalvalue_impl* v = (struct icalvalue_impl*)value; - if(value == 0){ return ICAL_NO_VALUE; } - return v->kind; + return value->kind; } int icalvalue_isa_value (void* value) { struct icalvalue_impl *impl = (struct icalvalue_impl *)value; icalerror_check_arg_rz( (value!=0), "value"); if (strcmp(impl->id,"val") == 0) { return 1; } else { return 0; } } -int icalvalue_is_time(icalvalue* a) { +static int icalvalue_is_time(const icalvalue* a) { icalvalue_kind kind = icalvalue_isa(a); if(kind == ICAL_DATETIME_VALUE || kind == ICAL_DATE_VALUE ){ return 1; } return 0; } +/* + * In case of error, this function returns 0. This is partly bogus, as 0 is + * not part of the returned enum. + * FIXME We should probably add an error value to the enum. + */ icalparameter_xliccomparetype -icalvalue_compare(icalvalue* a, icalvalue *b) +icalvalue_compare(const icalvalue* a, const icalvalue *b) { - struct icalvalue_impl *impla = (struct icalvalue_impl *)a; - struct icalvalue_impl *implb = (struct icalvalue_impl *)b; icalerror_check_arg_rz( (a!=0), "a"); icalerror_check_arg_rz( (b!=0), "b"); /* Not the same type; they can only be unequal */ if( ! (icalvalue_is_time(a) && icalvalue_is_time(b)) && icalvalue_isa(a) != icalvalue_isa(b)){ return ICAL_XLICCOMPARETYPE_NOTEQUAL; } switch (icalvalue_isa(a)){ case ICAL_ATTACH_VALUE: - case ICAL_BINARY_VALUE: + { + if (icalattach_get_is_url(a->data.v_attach) && + icalattach_get_is_url(b->data.v_attach)) { + if (strcasecmp(icalattach_get_url(a->data.v_attach), + icalattach_get_url(b->data.v_attach)) == 0) + return ICAL_XLICCOMPARETYPE_EQUAL; + else + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } + else { + if (a->data.v_attach == b->data.v_attach) + return ICAL_XLICCOMPARETYPE_EQUAL; + else + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } + } + case ICAL_BINARY_VALUE: + { + if (a->data.v_attach == b->data.v_attach) + return ICAL_XLICCOMPARETYPE_EQUAL; + else + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } case ICAL_BOOLEAN_VALUE: { if (icalvalue_get_boolean(a) == icalvalue_get_boolean(b)){ return ICAL_XLICCOMPARETYPE_EQUAL; } else { return ICAL_XLICCOMPARETYPE_NOTEQUAL; } } case ICAL_FLOAT_VALUE: { - if (impla->data.v_float > implb->data.v_float){ + if (a->data.v_float > b->data.v_float){ return ICAL_XLICCOMPARETYPE_GREATER; - } else if (impla->data.v_float < implb->data.v_float){ + } else if (a->data.v_float < b->data.v_float){ return ICAL_XLICCOMPARETYPE_LESS; } else { return ICAL_XLICCOMPARETYPE_EQUAL; } } case ICAL_INTEGER_VALUE: case ICAL_UTCOFFSET_VALUE: { - if (impla->data.v_int > implb->data.v_int){ + if (a->data.v_int > b->data.v_int){ return ICAL_XLICCOMPARETYPE_GREATER; - } else if (impla->data.v_int < implb->data.v_int){ + } else if (a->data.v_int < b->data.v_int){ return ICAL_XLICCOMPARETYPE_LESS; } else { return ICAL_XLICCOMPARETYPE_EQUAL; } } case ICAL_DURATION_VALUE: { - int a = icaldurationtype_as_int(impla->data.v_duration); - int b = icaldurationtype_as_int(implb->data.v_duration); + int dur_a = icaldurationtype_as_int(a->data.v_duration); + int dur_b = icaldurationtype_as_int(b->data.v_duration); - if (a > b){ + if (dur_a > dur_b){ return ICAL_XLICCOMPARETYPE_GREATER; - } else if (a < b){ + } else if (dur_a < dur_b){ return ICAL_XLICCOMPARETYPE_LESS; } else { return ICAL_XLICCOMPARETYPE_EQUAL; } } case ICAL_TEXT_VALUE: case ICAL_URI_VALUE: case ICAL_CALADDRESS_VALUE: case ICAL_TRIGGER_VALUE: case ICAL_DATE_VALUE: case ICAL_DATETIME_VALUE: case ICAL_DATETIMEPERIOD_VALUE: + case ICAL_QUERY_VALUE: + case ICAL_RECUR_VALUE: { int r; r = strcmp(icalvalue_as_ical_string(a), icalvalue_as_ical_string(b)); if (r > 0) { return ICAL_XLICCOMPARETYPE_GREATER; } else if (r < 0){ return ICAL_XLICCOMPARETYPE_LESS; } else { return ICAL_XLICCOMPARETYPE_EQUAL; } } case ICAL_METHOD_VALUE: { if (icalvalue_get_method(a) == icalvalue_get_method(b)){ return ICAL_XLICCOMPARETYPE_EQUAL; } else { return ICAL_XLICCOMPARETYPE_NOTEQUAL; } } case ICAL_STATUS_VALUE: { if (icalvalue_get_status(a) == icalvalue_get_status(b)){ return ICAL_XLICCOMPARETYPE_EQUAL; } else { return ICAL_XLICCOMPARETYPE_NOTEQUAL; } } + case ICAL_TRANSP_VALUE: + { + if (icalvalue_get_transp(a) == icalvalue_get_transp(b)){ + return ICAL_XLICCOMPARETYPE_EQUAL; + } else { + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } + } + + case ICAL_ACTION_VALUE: + { + if (icalvalue_get_action(a) == icalvalue_get_action(b)){ + return ICAL_XLICCOMPARETYPE_EQUAL; + } else { + return ICAL_XLICCOMPARETYPE_NOTEQUAL; + } + } + case ICAL_PERIOD_VALUE: case ICAL_GEO_VALUE: - case ICAL_RECUR_VALUE: case ICAL_NO_VALUE: default: { icalerror_warn("Comparison not implemented for value type"); - return ICAL_XLICCOMPARETYPE_REGEX+1; /* HACK */ + return 0; } } } -/* Examine the value and possiby chage the kind to agree with the value */ +/** Examine the value and possibly change the kind to agree with the + * value + */ + void icalvalue_reset_kind(icalvalue* value) { - struct icalvalue_impl* impl = (struct icalvalue_impl*)value; - - if( (impl->kind==ICAL_DATETIME_VALUE || impl->kind==ICAL_DATE_VALUE )&& - !icaltime_is_null_time(impl->data.v_time) ) { + if( (value->kind==ICAL_DATETIME_VALUE || value->kind==ICAL_DATE_VALUE )&& + !icaltime_is_null_time(value->data.v_time) ) { - if( impl->data.v_time.is_date == 1){ - impl->kind = ICAL_DATE_VALUE; + if(icaltime_is_date(value->data.v_time)){ + value->kind = ICAL_DATE_VALUE; } else { - impl->kind = ICAL_DATETIME_VALUE; + value->kind = ICAL_DATETIME_VALUE; } } } void icalvalue_set_parent(icalvalue* value, icalproperty* property) { - struct icalvalue_impl* v = (struct icalvalue_impl*)value; - - v->parent = property; - + value->parent = property; } icalproperty* icalvalue_get_parent(icalvalue* value) { - struct icalvalue_impl* v = (struct icalvalue_impl*)value; + return value->parent; +} - return v->parent; -} +int icalvalue_encode_ical_string(const char *szText, char *szEncText, int nMaxBufferLen) +{ + char *ptr; + icalvalue *value = 0; + + if ((szText == 0) || (szEncText == 0)) + return 0; + + value = icalvalue_new_from_string(ICAL_STRING_VALUE, szText); + + if (value == 0) + return 0; + + ptr = icalvalue_text_as_ical_string(value); + if (ptr == 0) + return 0; + + if ((int)strlen(ptr) >= nMaxBufferLen) + { + icalvalue_free (value); + return 0; + } + strcpy(szEncText, ptr); + icalvalue_free ((icalvalue*)value); + + return 1; +} /* The remaining interfaces are 'new', 'set' and 'get' for each of the value types */ - - -/* Everything below this line is machine generated. Do not edit. */ diff --git a/libical/src/libical/icalvalue.h b/libical/src/libical/icalvalue.h index 6983c23..851e723 100644 --- a/libical/src/libical/icalvalue.h +++ b/libical/src/libical/icalvalue.h @@ -1,85 +1,88 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalvalue.h CREATOR: eric 20 March 1999 $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 icalvalue.h ======================================================================*/ #ifndef ICALVALUE_H #define ICALVALUE_H #include <time.h> #include "icalenums.h" #include "icaltypes.h" #include "icalrecur.h" #include "icalduration.h" #include "icalperiod.h" #include "icalderivedproperty.h" /* For icalproperty_method, etc. */ #include "icalderivedparameter.h" #include "icalderivedvalue.h" /* Defined in icalderivedvalue.h */ -/*typedef void icalvalue;*/ +/*typedef struct icalvalue_impl icalvalue;*/ icalvalue* icalvalue_new(icalvalue_kind kind); -icalvalue* icalvalue_new_clone(icalvalue* value); +icalvalue* icalvalue_new_clone(const icalvalue* value); icalvalue* icalvalue_new_from_string(icalvalue_kind kind, const char* str); void icalvalue_free(icalvalue* value); -int icalvalue_is_valid(icalvalue* value); +int icalvalue_is_valid(const icalvalue* value); -const char* icalvalue_as_ical_string(icalvalue* value); +const char* icalvalue_as_ical_string(const icalvalue* value); -icalvalue_kind icalvalue_isa(icalvalue* value); +icalvalue_kind icalvalue_isa(const icalvalue* value); int icalvalue_isa_value(void*); -icalparameter_xliccomparetype icalvalue_compare(icalvalue* a, icalvalue *b); +icalparameter_xliccomparetype icalvalue_compare(const icalvalue* a, const icalvalue *b); /* Special, non autogenerated value accessors */ icalvalue* icalvalue_new_recur (struct icalrecurrencetype v); void icalvalue_set_recur(icalvalue* value, struct icalrecurrencetype v); -struct icalrecurrencetype icalvalue_get_recur(icalvalue* value); +struct icalrecurrencetype icalvalue_get_recur(const icalvalue* value); icalvalue* icalvalue_new_trigger (struct icaltriggertype v); void icalvalue_set_trigger(icalvalue* value, struct icaltriggertype v); -struct icaltriggertype icalvalue_get_trigger(icalvalue* value); +struct icaltriggertype icalvalue_get_trigger(const icalvalue* value); icalvalue* icalvalue_new_datetimeperiod (struct icaldatetimeperiodtype v); void icalvalue_set_datetimeperiod(icalvalue* value, struct icaldatetimeperiodtype v); -struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(icalvalue* value); +struct icaldatetimeperiodtype icalvalue_get_datetimeperiod(const icalvalue* value); /* Convert enumerations */ icalvalue_kind icalvalue_string_to_kind(const char* str); -const char* icalvalue_kind_to_string(icalvalue_kind kind); +const char* icalvalue_kind_to_string(const icalvalue_kind kind); + +/** Check validity of a specific icalvalue_kind **/ +int icalvalue_kind_is_valid(const icalvalue_kind kind); +/** Encode a character string in ical format, esacpe certain characters, etc. */ +int icalvalue_encode_ical_string(const char *szText, char *szEncText, int MaxBufferLen); #endif /*ICALVALUE_H*/ diff --git a/libical/src/libical/icalvalueimpl.h b/libical/src/libical/icalvalueimpl.h index 116535d..d1ba786 100644 --- a/libical/src/libical/icalvalueimpl.h +++ b/libical/src/libical/icalvalueimpl.h @@ -1,93 +1,95 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalvalue.c CREATOR: eric 02 May 1999 $Id$ (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 icalvalue.c Contributions from: Graham Davison (g.m.davison@computer.org) ======================================================================*/ #ifdef HAVE_CONFIG_H #include <config.h> #endif #ifndef ICALVALUEIMPL_H #define ICALVALUEIMPL_H #include "icalenums.h" +#include "icalproperty.h" +#include "icalderivedvalue.h" struct icalvalue_impl { icalvalue_kind kind; /*this is the kind that is visible from the outside*/ char id[5]; int size; icalproperty* parent; - const char* x_value; + char* x_value; union data { - struct icalattachtype *v_attach; + icalattach *v_attach; /* void *v_binary; */ /* use v_attach */ const char *v_string; /*char *v_text;*/ /*char *v_caladdress;*/ /*char *v_uri;*/ float v_float; int v_int; /*int v_boolean;*/ /*int v_integer;*/ struct icaldurationtype v_duration; /*int v_utcoffset;*/ struct icalperiodtype v_period; /*struct icalperiodtype v_datetimeperiod;*/ struct icalgeotype v_geo; /*time_t v_time;*/ struct icaltimetype v_time; /*struct icaltimetype v_date;*/ /*struct icaltimetype v_datetime;*/ /*struct icaltimetype v_datetimedate;*/ struct icalreqstattype v_requeststatus; /* struct icalrecurrencetype was once included directly ( not referenced ) in this union, but it contributes 2000 bytes to every value, so now it is a reference*/ struct icalrecurrencetype *v_recur; struct icaltriggertype v_trigger; int v_enum; /* v_enum takes care of several enumerated types including: icalproperty_method v_method; icalproperty_status v_status; icalproperty_action v_action; icalproperty_class v_class; icalproperty_transp v_transp; */ } data; }; #endif diff --git a/libical/src/libical/icalversion.h b/libical/src/libical/icalversion.h index beae8e0..c4b1d15 100644 --- a/libical/src/libical/icalversion.h +++ b/libical/src/libical/icalversion.h @@ -1,7 +1,7 @@ #ifndef ICAL_VERSION_H #define ICAL_VERSION_H #define ICAL_PACKAGE "libical" -#define ICAL_VERSION "0.23" +#define ICAL_VERSION "0.24" #endif diff --git a/libical/src/libical/libical.pro b/libical/src/libical/libical.pro index 9cc3983..4ef11ef 100644 --- a/libical/src/libical/libical.pro +++ b/libical/src/libical/libical.pro @@ -1,68 +1,68 @@ -include(../../../variables.pri) - -TEMPLATE = lib - -TARGET = ical -DESTDIR = ../../lib - -win32: DEFINES += _WIN32 +###################################################################### +# Automatically generated by qmake (1.07a) Sun Jun 27 22:44:35 2004 +###################################################################### +TEMPLATE = lib +INCLUDEPATH += . CONFIG += staticlib +DESTDIR = ../../lib +TARGET = ical +# Input +HEADERS += astime.h \ + ical.h \ + icalarray.h \ + icalattach.h \ + icalattachimpl.h \ + icalcomponent.h \ + icalderivedparameter.h \ + icalderivedproperty.h \ + icalderivedvalue.h \ + icalduration.h \ + icalenums.h \ + icalerror.h \ + icallangbind.h \ + icalmemory.h \ + icalmime.h \ + icalparameter.h \ + icalparameterimpl.h \ + icalparser.h \ + icalperiod.h \ + icalproperty.h \ + icalrecur.h \ + icalrestriction.h \ + icaltime.h \ + icaltimezone.h \ + icaltypes.h \ + icalvalue.h \ + icalvalueimpl.h \ + icalversion.h \ + pvl.h \ + sspm.h +SOURCES += caldate.c \ + icalarray.c \ + icalattach.c \ + icalcomponent.c \ + icalderivedparameter.c \ + icalderivedproperty.c \ + icalderivedvalue.c \ + icalduration.c \ + icalenums.c \ + icalerror.c \ + icallangbind.c \ + icalmemory.c \ + icalmime.c \ + icalparameter.c \ + icalparser.c \ + icalperiod.c \ + icalproperty.c \ + icalrecur.c \ + icalrestriction.c \ + icaltime.c \ + icaltimezone.c \ + icaltypes.c \ + icalvalue.c \ + pvl.c \ + sspm.c -HEADERS = \ - icalattendee.h \ - icalcomponent.h \ - icalderivedparameter.h \ - icalderivedproperty.h \ - icalderivedvalue.h \ - icalduration.h \ - icalenums.h \ - icalerror.h \ - icallangbind.h \ - icalmemory.h \ - icalmime.h \ - icalparameter.h \ - icalparameterimpl.h \ - icalparser.h \ - icalperiod.h \ - icalproperty.h \ - icalrecur.h \ - icalrestriction.h \ - icaltime.h \ - icaltypes.h \ - icalvalue.h \ - icalvalueimpl.h \ - icalversion.h \ - icalyacc.h \ - pvl.h \ - sspm.h - -SOURCES = icalattendee.c \ - icalcomponent.c \ - icalderivedparameter.c \ - icalderivedproperty.c \ - icalderivedvalue.c \ - icalduration.c \ - icalenums.c \ - icalerror.c \ - icallangbind.c \ - icallexer.c \ - icalmemory.c \ - icalmime.c \ - icalparameter.c \ - icalparser.c \ - icalperiod.c \ - icalproperty.c \ - icalrecur.c \ - icalrestriction.c \ - icaltime.c \ - icaltypes.c \ - icalvalue.c \ - icalyacc.c \ - pvl.c \ - sspm.c \ - vsnprintf.c - -INTERFACES = -INCLUDEPATH += . +# vsnprintf.c diff --git a/libical/src/libical/libicalE.pro b/libical/src/libical/libicalE.pro index 2b9b720..1c79e18 100644 --- a/libical/src/libical/libicalE.pro +++ b/libical/src/libical/libicalE.pro @@ -1,66 +1,70 @@ -TEMPLATE = lib -CONFIG = warn_on staticlib +###################################################################### +# Automatically generated by qmake (1.07a) Sun Jun 27 22:44:35 2004 +###################################################################### -INCLUDEPATH += . +TEMPLATE = lib +INCLUDEPATH += . +CONFIG += staticlib OBJECTS_DIR = obj/$(PLATFORM) MOC_DIR = moc/$(PLATFORM) DESTDIR=../../lib/$(PLATFORM) TARGET = ical -INTERFACES = \ +# Input +HEADERS += astime.h \ + ical.h \ + icalarray.h \ + icalattach.h \ + icalattachimpl.h \ + icalcomponent.h \ + icalderivedparameter.h \ + icalderivedproperty.h \ + icalderivedvalue.h \ + icalduration.h \ + icalenums.h \ + icalerror.h \ + icallangbind.h \ + icalmemory.h \ + icalmime.h \ + icalparameter.h \ + icalparameterimpl.h \ + icalparser.h \ + icalperiod.h \ + icalproperty.h \ + icalrecur.h \ + icalrestriction.h \ + icaltime.h \ + icaltimezone.h \ + icaltypes.h \ + icalvalue.h \ + icalvalueimpl.h \ + icalversion.h \ + pvl.h \ + sspm.h +SOURCES += caldate.c \ + icalarray.c \ + icalattach.c \ + icalcomponent.c \ + icalderivedparameter.c \ + icalderivedproperty.c \ + icalderivedvalue.c \ + icalduration.c \ + icalenums.c \ + icalerror.c \ + icallangbind.c \ + icalmemory.c \ + icalmime.c \ + icalparameter.c \ + icalparser.c \ + icalperiod.c \ + icalproperty.c \ + icalrecur.c \ + icalrestriction.c \ + icaltime.c \ + icaltimezone.c \ + icaltypes.c \ + icalvalue.c \ + pvl.c \ + sspm.c -HEADERS = \ - ical.h \ - icalattendee.h \ - icalcomponent.h \ - icalderivedparameter.h \ - icalderivedproperty.h \ - icalderivedvalue.h \ - icalduration.h \ - icalenums.h \ - icalerror.h \ - icallangbind.h \ - icalmemory.h \ - icalmime.h \ - icalparameter.h \ - icalparameterimpl.h \ - icalparser.h \ - icalperiod.h \ - icalproperty.h \ - icalrecur.h \ - icalrestriction.h \ - icaltime.h \ - icaltypes.h \ - icalvalue.h \ - icalvalueimpl.h \ - icalversion.h \ - icalyacc.h \ - pvl.h \ - sspm.h \ - -SOURCES = \ - icalattendee.c \ - icalcomponent.c \ - icalderivedparameter.c \ - icalderivedproperty.c \ - icalderivedvalue.c \ - icalduration.c \ - icalenums.c \ - icalerror.c \ - icallangbind.c \ - icallexer.c \ - icalmemory.c \ - icalmime.c \ - icalparameter.c \ - icalparser.c \ - icalperiod.c \ - icalproperty.c \ - icalrecur.c \ - icalrestriction.c \ - icaltime.c \ - icaltypes.c \ - icalvalue.c \ - icalyacc.c \ - pvl.c \ - sspm.c \ - vsnprintf.c \ +# vsnprintf.c diff --git a/libical/src/libical/pvl.c b/libical/src/libical/pvl.c index 2a733e8..9c271ce 100644 --- a/libical/src/libical/pvl.c +++ b/libical/src/libical/pvl.c @@ -1,761 +1,584 @@ /*====================================================================== FILE: pvl.c CREATOR: eric November, 1995 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pvl.h" #include <errno.h> #include <assert.h> #include <stdlib.h> - - -/* +/** struct pvl_list_t The list structure. This is the hanlde for the entire list This type is also private. Use pvl_list instead */ typedef struct pvl_list_t { - int MAGIC; /* Magic Identifier */ - struct pvl_elem_t *head; /* Head of list */ - struct pvl_elem_t *tail; /* Tail of list */ - int count; /* Number of items in the list */ - struct pvl_elem_t *p; /* Pointer used for iterators */ + int MAGIC; /**< Magic Identifier */ + struct pvl_elem_t *head; /**< Head of list */ + struct pvl_elem_t *tail; /**< Tail of list */ + int count; /**< Number of items in the list */ + struct pvl_elem_t *p; /**< Pointer used for iterators */ } pvl_list_t; -/* This global is incremented for each call to pvl_new_element(); it gives each - * list a unique identifer */ +/** + * This global is incremented for each call to pvl_new_element(); it gives each + * list a unique identifer + */ int pvl_elem_count = 0; int pvl_list_count = 0; -/*---------------------------------------------------------------------- - Function: pvl_list pvl_newlist() - - Purpose: - - Creates a new list, clears the pointers and assigns a magic number - - Returns: - - Pointer to the new list - 0 if there is no available memory. - *----------------------------------------------------------------------*/ +/** + * @brief Creates a new list, clears the pointers and assigns a magic number + * + * @return Pointer to the new list, 0 if there is no available memory. + */ pvl_list pvl_newlist() { struct pvl_list_t *L; if ( ( L = (struct pvl_list_t*)malloc(sizeof(struct pvl_list_t))) == 0) { errno = ENOMEM; return 0; } L->MAGIC = pvl_list_count; pvl_list_count++; L->head = 0; L->tail = 0; L->count = 0; L->p = 0; return L; } void pvl_free(pvl_list l) { struct pvl_list_t *L = (struct pvl_list_t *)l; pvl_clear(l); free(L); } -/*---------------------------------------------------------------------- - Function: pvl_new_element(void *d, struct pvl_elem_t *next,struct pvl_elem_t *prior) - - Purpose: - Creates a new list element, assigns a magic number, and assigns - the next and previous pointers. - - Passing in the next and previous points may seem odd, but it allos the user - to set them while keeping the internal data hidden. In nearly all cases, - the user is the pvl library itself. - - Parameters: - - d The data item to be stored in the list - next Pointer value to assign to the member "next" - prior Pointer value to assign to the member "prior" - - Returns: - - A pointer to the new element. - 0 if there is no memory available. - - *----------------------------------------------------------------------*/ +/** + * @brief Creates a new list element, assigns a magic number, and assigns + * the next and previous pointers. + * + * Passing in the next and previous points may seem odd, but it allos the user + * to set them while keeping the internal data hidden. In nearly all cases, + * the user is the pvl library itself. + * + * @param d The data item to be stored in the list + * @param next Pointer value to assign to the member "next" + * @param prior Pointer value to assign to the member "prior" + * + * @return A pointer to the new element, 0 if there is no memory available. + */ pvl_elem -pvl_new_element(void *d, pvl_elem next,pvl_elem prior) +pvl_new_element(void *d, pvl_elem next, pvl_elem prior) { struct pvl_elem_t *E; if ( ( E = (struct pvl_elem_t*)malloc(sizeof(struct pvl_elem_t))) == 0) { errno = ENOMEM; return 0; } E->MAGIC = pvl_elem_count++; E->d = d; E->next = next; E->prior = prior; return (pvl_elem)E; } -/*---------------------------------------------------------------------- - Function: pvl_unshift(pvl_list l,void *d) - - Purpose: - - Add a new element to the from of the list - - Parameters: - - l The list to add the item to - d Pointer to the item to add - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Add a new element to the from of the list + * + * @param L The list to add the item to + * @param d Pointer to the item to add + */ void -pvl_unshift(pvl_list l,void *d) +pvl_unshift(pvl_list L,void *d) { - struct pvl_list_t *L = (struct pvl_list_t *)l; struct pvl_elem_t *E = pvl_new_element(d,L->head,0); if (E->next != 0) { /* Link the head node to it */ E->next->prior = E; } /* move the head */ L->head = E; /* maybe move the tail */ if (L->tail == 0) { L->tail = E; } L->count++; } -/*---------------------------------------------------------------------- - Function: pvl_shift(pvl_list l) - - Purpose: - - Remove an element from the front of the list - - Parameters: - - l The list to operate on - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Remove an element from the front of the list + * + * @param L The list to operate on + * + * @return the entry on the front of the list + */ void* -pvl_shift(pvl_list l) +pvl_shift(pvl_list L) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - if (L->head == 0) { return 0; } - return pvl_remove(l,(void*)L->head); + return pvl_remove(L,(void*)L->head); } -/*---------------------------------------------------------------------- - Function: void pvl_push(pvl_list l,void *d) - - Purpose: - - Add a new item to the tail of the list - - Paramters: - - l The list to operate on - d Pointer to the item to add - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Add a new item to the tail of the list + * + * @param L The list to operate on + * @param d Pointer to the item to add + * + */ void -pvl_push(pvl_list l,void *d) +pvl_push(pvl_list L,void *d) { - struct pvl_list_t *L = (struct pvl_list_t *)l; struct pvl_elem_t *E = pvl_new_element(d,0,L->tail); /* These are done in pvl_new_element E->next = 0; E->prior = L->tail; */ if (L->tail != 0) { L->tail->next = E; } if (L->head == 0) { L->head = E; } L->tail = E; L->count++; } -/*---------------------------------------------------------------------- - Function: void* pvl_pop(pvl_list l) - - Purpose: - - Remove an element from the tail of the list - - Paramters: - - l The list to operate on - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Remove an element from the tail of the list + * + * @param L The list to operate on + */ void* -pvl_pop(pvl_list l) +pvl_pop(pvl_list L) { - - struct pvl_list_t *L = (struct pvl_list_t *)l; - if ( L->tail == 0) { return 0; } - return pvl_remove(l,(void*) L->tail);; + return pvl_remove(L,(void*) L->tail);; } -/*---------------------------------------------------------------------- - Function: void pvl_insert_ordered(pvl_list l,pvl_comparef f,void *d) - - Purpose: - - Add a new item to a list that is ordered by a comparison function. - This routine assumes that the list is properly ordered. - - l The list to operate on - f Pointer to a comparison function - d Pointer to data to pass to the comparison function - - Returns: - - void - - *----------------------------------------------------------------------*/ +/** + * Add a new item to a list that is ordered by a comparison function. + * This routine assumes that the list is properly ordered. + * + * @param L The list to operate on + * @param f Pointer to a comparison function + * @param d Pointer to data to pass to the comparison function + */ void -pvl_insert_ordered(pvl_list l,pvl_comparef f,void *d) +pvl_insert_ordered(pvl_list L,pvl_comparef f,void *d) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - struct pvl_elem_t *P; L->count++; /* Empty list, add to head */ if(L->head == 0) { - pvl_unshift(l,d); + pvl_unshift(L,d); return; } /* smaller than head, add to head */ if ( ((*f)(d,L->head->d)) <= 0) { - pvl_unshift(l,d); + pvl_unshift(L,d); return; } /* larger than tail, add to tail */ if ( (*f)(d,L->tail->d) >= 0) { - pvl_push(l,d); + pvl_push(L,d); return; } /* Search for the first element that is smaller, and add before it */ for (P=L->head; P != 0; P = P->next) { if ( (*f)(P->d,d) >= 0) { - pvl_insert_before(l,P,d); + pvl_insert_before(L,P,d); return; } } /* badness, choke */ - +#ifndef lint assert(0); - +#endif } -/*---------------------------------------------------------------------- - Function: void pvl_insert_after(pvl_list l,pvl_elem p,void *d) - - Purpose: - - Add a new item after the referenced element. - - Parameters: - - l The list to operate on - p The list element to add the item after - d Pointer to the item to add. - - Returns: - - void - - *----------------------------------------------------------------------*/ +/** + * @brief Add a new item after the referenced element. + * @param L The list to operate on + * @param P The list element to add the item after + * @param d Pointer to the item to add. + */ void -pvl_insert_after(pvl_list l,pvl_elem p,void *d) +pvl_insert_after(pvl_list L,pvl_elem P,void *d) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - struct pvl_elem_t *P = (struct pvl_elem_t *)p; struct pvl_elem_t *E = 0; L->count++; if (P == 0) { - pvl_unshift(l,d); + pvl_unshift(L,d); return; } if ( P == L->tail) { E = pvl_new_element(d,0,P); L->tail = E; E->prior->next = E; } else { E = pvl_new_element(d,P->next,P); E->next->prior = E; E->prior->next = E; } } -/*---------------------------------------------------------------------- - Function: void pvl_insert_before(pvl_list l,pvl_elem p,void *d) - - Purpose: - - Add an item after a referenced item - - Parameters: - - l The list to operate on - p The list element to add the item before - d Pointer to the data to be added. - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Add an item after a referenced item + * + * @param L The list to operate on + * @param P The list element to add the item before + * @param d Pointer to the data to be added. + */ void -pvl_insert_before(pvl_list l,pvl_elem p,void *d) +pvl_insert_before(pvl_list L,pvl_elem P,void *d) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - struct pvl_elem_t *P = (struct pvl_elem_t *)p; struct pvl_elem_t *E = 0; L->count++; if (P == 0) { - pvl_unshift(l,d); + pvl_unshift(L,d); return; } if ( P == L->head) { E = pvl_new_element(d,P,0); E->next->prior = E; L->head = E; } else { E = pvl_new_element(d,P,P->prior); E->prior->next = E; E->next->prior = E; } } -/*---------------------------------------------------------------------- - Function: void pvl_remove(pvl_list l,pvl_elem e) - - Purpose: - - Remove the referenced item from the list - - This routine will free the element, but not the data item that the - element contains. - - Parameters: - - l The list to operate on - e The element to remove. - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Remove the referenced item from the list. + * + * This routine will free the element, but not the data item that the + * element contains. + * + * @param L The list to operate on + * @param E The element to remove. + */ void* -pvl_remove(pvl_list l,pvl_elem e) +pvl_remove(pvl_list L,pvl_elem E) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - struct pvl_elem_t *E = (struct pvl_elem_t *)e; void* data; if (E == L->head) { if (E->next != 0) { E->next->prior = 0; L->head = E->next; } else { /* E Also points to tail -> only one element in list */ L->tail = 0; L->head = 0; } } else if (E == L->tail) { if (E->prior != 0) { E->prior->next = 0; L->tail = E->prior; } else { /* E points to the head, so it was the last element */ /* This case should be taken care of in the previous clause */ L->head = 0; L->tail = 0; } } else { E->prior->next = E->next; E->next->prior = E->prior; } L->count--; data = E->d; E->prior = 0; E->next = 0; E->d = 0; free(E); return data; } -/*---------------------------------------------------------------------- - Function: pvl_elem pvl_find(pvl_list l,pvl_findf f,void* v) - - Purpose: - - Return a pointer to data that satisfies a function - - This routine will interate through the entire list and call the - find function for each item. It will break and return a pointer to the - data that causes the find function to return 1. - - Parameters: - - l The list to operate on - f Pointer to the find function - v Pointer to constant data to pass into the function - - Returns: - - Pointer to the element that the find function found. - - *----------------------------------------------------------------------*/ +/** + * @brief Return a pointer to data that satisfies a function. + * + * This routine will interate through the entire list and call the + * find function for each item. It will break and return a pointer to the + * data that causes the find function to return 1. + * + * @param l The list to operate on + * @param f Pointer to the find function + * @param v Pointer to constant data to pass into the function + * + * @return Pointer to the element that the find function found. + */ pvl_elem pvl_find(pvl_list l,pvl_findf f,void* v) { pvl_elem e; for (e=pvl_head(l); e!= 0; e = pvl_next(e)) { if ( (*f)(((struct pvl_elem_t *)e)->d,v) == 1) { /* Save this elem for a call to find_next */ ((struct pvl_list_t *)l)->p = e; return e; } } return 0; } -/*---------------------------------------------------------------------- - Function: void* pvl_find_next(pvl_list l,pvl_findf f,void* v) - - Purpose: - - Like pvl_find(), but continues the search where the last find() or - find_next() left off - Parameters: - - l The list to operate on - f Pointer to the find function - v Pointer to constant data to pass into the function - - Returns: - - Pointer to the element that the find function found. - - *----------------------------------------------------------------------*/ +/** + * @brief Like pvl_find(), but continues the search where the last find() or + * find_next() left off. + * + * @param l The list to operate on + * @param f Pointer to the find function + * @param v Pointer to constant data to pass into the function + * + * @return Pointer to the element that the find function found. + */ pvl_elem pvl_find_next(pvl_list l,pvl_findf f,void* v) { pvl_elem e; for (e=pvl_head(l); e!= 0; e = pvl_next(e)) { if ( (*f)(((struct pvl_elem_t *)e)->d,v) == 1) { /* Save this elem for a call to find_next */ ((struct pvl_list_t *)l)->p = e; return e; } } return 0; } -/*---------------------------------------------------------------------- - Function: void pvl_clear(pvl_list l) - - Purpose: - - Remove the all the elements in the list. The does not free the data items - the elements hold. - - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Remove the all the elements in the list. The does not free + * the data items the elements hold. + */ void pvl_clear(pvl_list l) { pvl_elem e = pvl_head(l); pvl_elem next; if (e == 0) { return; } while(e != 0) { next = pvl_next(e); pvl_remove(l,e); e = next; } } -/*---------------------------------------------------------------------- - Function: int pvl_count(pvl_list l) - - Purpose: - - Returns the number of items in the list. - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Returns the number of items in the list. + */ int -pvl_count(pvl_list l) +pvl_count(pvl_list L) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - return L->count; } -/*---------------------------------------------------------------------- - Function: pvl_elem pvl_next(pvl_elem e) - - Purpose: - Returns a pointer to the given element - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Returns a pointer to the given element + */ pvl_elem -pvl_next(pvl_elem e) +pvl_next(pvl_elem E) { - struct pvl_elem_t *E = (struct pvl_elem_t *)e; - if (E == 0){ return 0; } return (pvl_elem)E->next; } -/*---------------------------------------------------------------------- - Function: pvl_elem pvl_prior(pvl_elem e) - Purpose: - - Returns a pointer to the element previous to the element given. - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Returns a pointer to the element previous to the element given. + */ pvl_elem -pvl_prior(pvl_elem e) +pvl_prior(pvl_elem E) { - struct pvl_elem_t *E = (struct pvl_elem_t *)e; - return (pvl_elem)E->prior; } -/*---------------------------------------------------------------------- - Function: pvl_elem pvl_head(pvl_list l ) - - Purpose: - - Returns a pointer to the first item in the list. - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Returns a pointer to the first item in the list. + */ + pvl_elem -pvl_head(pvl_list l ) +pvl_head(pvl_list L ) { - struct pvl_list_t *L = (struct pvl_list_t *)l; - return (pvl_elem)L->head; } -/*---------------------------------------------------------------------- - Function: pvl_elem pvl_tail(pvl_list l) - - Purpose: - - Returns a pointer to the last item in the list. - - Returns: - *----------------------------------------------------------------------*/ +/** + * @brief Returns a pointer to the last item in the list. + */ pvl_elem -pvl_tail(pvl_list l) +pvl_tail(pvl_list L) { - struct pvl_list_t *L = (struct pvl_list_t *)l; return (pvl_elem)L->tail; } -/*---------------------------------------------------------------------- - Function: - - - Purpose: - - - Returns: - *----------------------------------------------------------------------*/ - #ifndef PVL_USE_MACROS void* -pvl_data(pvl_elem e) +pvl_data(pvl_elem E) { - struct pvl_elem_t *E = (struct pvl_elem_t *)e; - - if ( e == 0){ + if ( E == 0){ return 0; } return E->d; } #endif -/*---------------------------------------------------------------------- - Function: void pvl_apply(pvl_list l,pvl_applyf f, void *v) - - Purpose: - - Call a function for every item in the list. - - Paramters: - - l The list to operate on - f Pointer to the function to call - v Data to pass to the function on every iteration - - Returns: - - void - *----------------------------------------------------------------------*/ +/** + * @brief Call a function for every item in the list. + * + * @param l The list to operate on + * @param f Pointer to the function to call + * @param v Data to pass to the function on every iteration + */ void pvl_apply(pvl_list l,pvl_applyf f, void *v) { pvl_elem e; for (e=pvl_head(l); e!= 0; e = pvl_next(e)) { (*f)(((struct pvl_elem_t *)e)->d,v); } } diff --git a/libical/src/libical/pvl.h b/libical/src/libical/pvl.h index 14a15a1..92ec546 100644 --- a/libical/src/libical/pvl.h +++ b/libical/src/libical/pvl.h @@ -1,94 +1,97 @@ /*====================================================================== FILE: pvl.h CREATOR: eric November, 1995 (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #ifndef __PVL_H__ #define __PVL_H__ -typedef void* pvl_list; -typedef void* pvl_elem; +typedef struct pvl_list_t* pvl_list; +typedef struct pvl_elem_t* pvl_elem; -/* - struct pvl_elem_t +/** + * This type is private. Always use pvl_elem instead. The struct would + * not even appear in this header except to make code in the USE_MACROS + * blocks work + */ - This type is private. Always use pvl_elem instead. The struct would - not even appear in this header except to make code in the USE_MACROS - blocks work - - */ typedef struct pvl_elem_t { - int MAGIC; /* Magic Identifier */ - void *d; /* Pointer to data user is storing */ - struct pvl_elem_t *next; /* Next element */ - struct pvl_elem_t *prior; /* prior element */ + int MAGIC; /**< Magic Identifier */ + void *d; /**< Pointer to data user is storing */ + struct pvl_elem_t *next; /**< Next element */ + struct pvl_elem_t *prior; /**< Prior element */ } pvl_elem_t; -/* This global is incremented for each call to pvl_new_element(); it gives each - * list a unique identifer */ +/** + * This global is incremented for each call to pvl_new_element(); it gives each + * list a unique identifer + */ extern int pvl_elem_count; extern int pvl_list_count; /* Create new lists or elements */ pvl_elem pvl_new_element(void* d, pvl_elem next,pvl_elem prior); pvl_list pvl_newlist(void); void pvl_free(pvl_list); /* Add, remove, or get the head of the list */ void pvl_unshift(pvl_list l,void *d); void* pvl_shift(pvl_list l); pvl_elem pvl_head(pvl_list); /* Add, remove or get the tail of the list */ void pvl_push(pvl_list l,void *d); void* pvl_pop(pvl_list l); pvl_elem pvl_tail(pvl_list); /* Insert elements in random places */ typedef int (*pvl_comparef)(void* a, void* b); /* a, b are of the data type*/ void pvl_insert_ordered(pvl_list l,pvl_comparef f,void *d); void pvl_insert_after(pvl_list l,pvl_elem e,void *d); void pvl_insert_before(pvl_list l,pvl_elem e,void *d); /* Remove an element, or clear the entire list */ void* pvl_remove(pvl_list,pvl_elem); /* Remove element, return data */ void pvl_clear(pvl_list); /* Remove all elements, de-allocate all data */ int pvl_count(pvl_list); /* Navagate the list */ pvl_elem pvl_next(pvl_elem e); pvl_elem pvl_prior(pvl_elem e); /* get the data in the list */ #ifndef PVL_USE_MACROS void* pvl_data(pvl_elem); #else #define pvl_data(x) x==0 ? 0 : ((struct pvl_elem_t *)x)->d; #endif /* Find an element for which a function returns true */ typedef int (*pvl_findf)(void* a, void* b); /*a is list elem, b is other data*/ pvl_elem pvl_find(pvl_list l,pvl_findf f,void* v); pvl_elem pvl_find_next(pvl_list l,pvl_findf f,void* v); -/* Pass each element in the list to a function */ -typedef void (*pvl_applyf)(void* a, void* b); /*a is list elem, b is other data*/ +/** + * Pass each element in the list to a function + * a is list elem, b is other data + */ +typedef void (*pvl_applyf)(void* a, void* b); void pvl_apply(pvl_list l,pvl_applyf f, void *v); #endif /* __PVL_H__ */ diff --git a/libical/src/libical/sspm.c b/libical/src/libical/sspm.c index 2df581b..17f12ee 100644 --- a/libical/src/libical/sspm.c +++ b/libical/src/libical/sspm.c @@ -1,1161 +1,1158 @@ /* -*- Mode: C -*- ====================================================================== FILE: sspm.c Parse Mime CREATOR: eric 25 June 2000 $Id$ $Locker$ The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. 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 Initial Developer of the Original Code is Eric Busboom (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org ======================================================================*/ #include <stdio.h> #include <string.h> #include "sspm.h" #include <assert.h> #include <ctype.h> /* for tolower */ #include <stdlib.h> /* for malloc, free */ #include <string.h> /* for strcasecmp */ -// Eugen C. <eug@thekompany.com> -#ifdef _WIN32 -#define strcasecmp _stricmp -#endif -// Eugen C. <eug@thekompany.com> - -int snprintf(char *str, size_t n, char const *fmt, ...); - #ifdef DMALLOC #include "dmalloc.h" #endif +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif + #define TMP_BUF_SIZE 1024 enum mime_state { UNKNOWN_STATE, IN_HEADER, END_OF_HEADER, IN_BODY, OPENING_PART, END_OF_PART, TERMINAL_END_OF_PART, END_OF_INPUT }; struct mime_impl{ struct sspm_part *parts; size_t max_parts; int part_no; int level; struct sspm_action_map *actions; char* (*get_string)(char *s, size_t size, void* data); void* get_string_data; char temp[TMP_BUF_SIZE]; enum mime_state state; }; void sspm_free_header(struct sspm_header *header); void* sspm_make_multipart_part(struct mime_impl *impl,struct sspm_header *header); void sspm_read_header(struct mime_impl *impl,struct sspm_header *header); char* sspm_strdup(char* str){ char* s; s = strdup(str); return s; } -struct major_content_type_map +static struct major_content_type_map { enum sspm_major_type type; char* str; } major_content_type_map[] = { {SSPM_MULTIPART_MAJOR_TYPE,"multipart" }, {SSPM_TEXT_MAJOR_TYPE,"text" }, {SSPM_TEXT_MAJOR_TYPE,"text" }, {SSPM_IMAGE_MAJOR_TYPE,"image" }, {SSPM_AUDIO_MAJOR_TYPE,"audio" }, {SSPM_VIDEO_MAJOR_TYPE,"video" }, {SSPM_APPLICATION_MAJOR_TYPE,"application" }, {SSPM_MULTIPART_MAJOR_TYPE,"multipart" }, {SSPM_MESSAGE_MAJOR_TYPE,"message" }, {SSPM_UNKNOWN_MAJOR_TYPE,"" }, }; -struct minor_content_type_map +static struct minor_content_type_map { enum sspm_minor_type type; char* str; } minor_content_type_map[] = { {SSPM_ANY_MINOR_TYPE,"*" }, {SSPM_PLAIN_MINOR_TYPE,"plain" }, {SSPM_RFC822_MINOR_TYPE,"rfc822" }, {SSPM_DIGEST_MINOR_TYPE,"digest" }, {SSPM_CALENDAR_MINOR_TYPE,"calendar" }, {SSPM_MIXED_MINOR_TYPE,"mixed" }, {SSPM_RELATED_MINOR_TYPE,"related" }, {SSPM_ALTERNATIVE_MINOR_TYPE,"alternative" }, {SSPM_PARALLEL_MINOR_TYPE, "parallel" }, {SSPM_UNKNOWN_MINOR_TYPE,"" } }; struct encoding_map { enum sspm_encoding encoding; char* str; } sspm_encoding_map[] = { {SSPM_NO_ENCODING,""}, {SSPM_QUOTED_PRINTABLE_ENCODING,"quoted-printable"}, {SSPM_8BIT_ENCODING,"8bit"}, {SSPM_7BIT_ENCODING,"7bit"}, {SSPM_BINARY_ENCODING,"binary"}, {SSPM_BASE64_ENCODING,"base64"}, {SSPM_UNKNOWN_ENCODING,""} }; char* sspm_get_parameter(char* line, char* parameter) { char *p,*s,*q; static char name[1024]; /* Find where the parameter name is in the line */ p = strstr(line,parameter); if( p == 0){ return 0; } /* skip over the parameter name, the '=' and any blank spaces */ p+=strlen(parameter); while(*p==' ' || *p == '='){ p++; } /*now find the next semicolon*/ s = strchr(p,';'); /* Strip of leading quote */ q = strchr(p,'\"'); if(q !=0){ p = q+1; } if(s != 0){ strncpy(name,p,(size_t)s-(size_t)p); } else { strcpy(name,p); } /* Strip off trailing quote, if it exists */ q = strrchr(name,'\"'); if (q != 0){ *q='\0'; } return name; } char* sspm_property_name(char* line) { static char name[1024]; char *c = strchr(line,':'); if(c != 0){ strncpy(name,line,(size_t)c-(size_t)line); name[(size_t)c-(size_t)line] = '\0'; return name; } else { return 0; } } char* sspm_value(char* line) { static char value[1024]; char *c,*s, *p; /* Find the first colon and the next semicolon */ c = strchr(line,':'); s = strchr(c,';'); /* Skip the colon */ c++; if (s == 0){ s = c+strlen(line); } for(p=value; c != s; c++){ if(*c!=' ' && *c!='\n'){ *(p++) = *c; } } *p='\0'; return value; } -char *mime_headers[] = { +static char *mime_headers[] = { "Content-Type", "Content-Transfer-Encoding", "Content-Disposition", "Content-Id", "Mime-Version", 0 }; void* sspm_default_new_part() { return 0; } void sspm_default_add_line(void *part, struct sspm_header *header, char* line, size_t size) { } void* sspm_default_end_part(void* part) { return 0; } void sspm_default_free_part(void *part) { } struct sspm_action_map sspm_action_map[] = { {SSPM_UNKNOWN_MAJOR_TYPE,SSPM_UNKNOWN_MINOR_TYPE,sspm_default_new_part,sspm_default_add_line,sspm_default_end_part,sspm_default_free_part}, }; int sspm_is_mime_header(char *line) { char *name = sspm_property_name(line); int i; if(name == 0){ return 0; } for(i = 0; mime_headers[i] != 0; i++){ if(strcasecmp(name, mime_headers[i]) == 0) return 1; } return 0; } int sspm_is_mail_header(char* line) { char *name = sspm_property_name(line); if (name != 0){ return 1; } return 0; } int sspm_is_blank(char* line) { char *p; char c =0; for(p=line; *p!=0; p++){ if( ! (*p == ' '|| *p == '\t' || *p=='\n') ){ c++; } } if (c==0){ return 1; } return 0; } int sspm_is_continuation_line(char* line) { if (line[0] == ' '|| line[0] == '\t' ) { return 1; } return 0; } int sspm_is_mime_boundary(char *line) { if( line[0] == '-' && line[1] == '-') { return 1; } return 0; } int sspm_is_mime_terminating_boundary(char *line) { if (sspm_is_mime_boundary(line) && strstr(line,"--\n")){ return 1; } return 0; } enum line_type { EMPTY, BLANK, MIME_HEADER, MAIL_HEADER, HEADER_CONTINUATION, BOUNDARY, TERMINATING_BOUNDARY, UNKNOWN_TYPE }; -enum line_type get_line_type(char* line){ +static enum line_type get_line_type(char* line){ if (line == 0){ return EMPTY; } else if(sspm_is_blank(line)){ return BLANK; } else if (sspm_is_mime_header(line)){ return MIME_HEADER; } else if (sspm_is_mail_header(line)){ return MAIL_HEADER; } else if (sspm_is_continuation_line(line)){ return HEADER_CONTINUATION; } else if (sspm_is_mime_terminating_boundary(line)){ return TERMINATING_BOUNDARY; } else if (sspm_is_mime_boundary(line)) { return BOUNDARY; } else { return UNKNOWN_TYPE; } } -struct sspm_action_map get_action(struct mime_impl *impl, +static struct sspm_action_map get_action(struct mime_impl *impl, enum sspm_major_type major, enum sspm_minor_type minor) { int i; /* Read caller suppled action map */ if (impl->actions != 0){ for(i=0; impl->actions[i].major != SSPM_UNKNOWN_MAJOR_TYPE; i++){ if((major == impl->actions[i].major && minor == impl->actions[i].minor) || (major == impl->actions[i].major && minor == SSPM_ANY_MINOR_TYPE)){ return impl->actions[i]; } } } /* Else, read default action map */ for(i=0; sspm_action_map[i].major != SSPM_UNKNOWN_MAJOR_TYPE; i++){ if((major == sspm_action_map[i].major && minor == sspm_action_map[i].minor) || (major == sspm_action_map[i].major && minor == SSPM_ANY_MINOR_TYPE)){ break; } } return sspm_action_map[i]; } char* sspm_lowercase(char* str) { char* p = 0; char* new = sspm_strdup(str); if(str ==0){ return 0; } for(p = new; *p!=0; p++){ *p = tolower(*p); } return new; } enum sspm_major_type sspm_find_major_content_type(char* type) { int i; char* ltype = sspm_lowercase(type); for (i=0; major_content_type_map[i].type != SSPM_UNKNOWN_MINOR_TYPE; i++){ if(strncmp(ltype, major_content_type_map[i].str, strlen(major_content_type_map[i].str))==0){ free(ltype); return major_content_type_map[i].type; } } free(ltype); return major_content_type_map[i].type; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ } enum sspm_minor_type sspm_find_minor_content_type(char* type) { int i; char* ltype = sspm_lowercase(type); char *p = strchr(ltype,'/'); if (p==0){ return SSPM_UNKNOWN_MINOR_TYPE; } p++; /* Skip the '/' */ for (i=0; minor_content_type_map[i].type != SSPM_UNKNOWN_MINOR_TYPE; i++){ if(strncmp(p, minor_content_type_map[i].str, strlen(minor_content_type_map[i].str))==0){ free(ltype); return minor_content_type_map[i].type; } } free(ltype); return minor_content_type_map[i].type; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ } char* sspm_major_type_string(enum sspm_major_type type) { int i; for (i=0; major_content_type_map[i].type != SSPM_UNKNOWN_MINOR_TYPE; i++){ if(type == major_content_type_map[i].type){ return major_content_type_map[i].str; } } return major_content_type_map[i].str; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ } char* sspm_minor_type_string(enum sspm_minor_type type) { int i; for (i=0; minor_content_type_map[i].type != SSPM_UNKNOWN_MINOR_TYPE; i++){ if(type == minor_content_type_map[i].type){ return minor_content_type_map[i].str; } } return minor_content_type_map[i].str; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ } char* sspm_encoding_string(enum sspm_encoding type) { int i; for (i=0; sspm_encoding_map[i].encoding != SSPM_UNKNOWN_ENCODING; i++){ if(type == sspm_encoding_map[i].encoding){ return sspm_encoding_map[i].str; } } return sspm_encoding_map[i].str; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ } /* Interpret a header line and add its data to the header structure. */ void sspm_build_header(struct sspm_header *header, char* line) { char *prop; char *val; val = sspm_strdup(sspm_value(line)); prop = sspm_strdup(sspm_property_name(line)); if(strcmp(prop,"Content-Type") == 0){ /* Create a new mime_header, fill in content-type and possibly boundary */ char* boundary= sspm_get_parameter(line,"boundary"); header->def = 0; header->major = sspm_find_major_content_type(val); header->minor = sspm_find_minor_content_type(val); if(header->minor == SSPM_UNKNOWN_MINOR_TYPE){ char *p = strchr(val,'/'); if (p != 0){ p++; /* Skip the '/' */ header->minor_text = sspm_strdup(p); } else { /* Error, malformed content type */ header->minor_text = sspm_strdup("unknown"); } } if (boundary != 0){ header->boundary = sspm_strdup(boundary); } } else if(strcmp(prop,"Content-Transfer-Encoding")==0){ char* encoding = sspm_value(line); char* lencoding = sspm_lowercase(encoding); if(strcmp(lencoding,"base64")==0){ header->encoding = SSPM_BASE64_ENCODING; } else if(strcmp(lencoding,"quoted-printable")==0){ header->encoding = SSPM_QUOTED_PRINTABLE_ENCODING; } else if(strcmp(lencoding,"binary")==0){ header->encoding = SSPM_BINARY_ENCODING; } else if(strcmp(lencoding,"7bit")==0){ header->encoding = SSPM_7BIT_ENCODING; } else if(strcmp(lencoding,"8bit")==0){ header->encoding = SSPM_8BIT_ENCODING; } else { header->encoding = SSPM_UNKNOWN_ENCODING; } free(lencoding); header->def = 0; } else if(strcmp(prop,"Content-Id")==0){ char* cid = sspm_value(line); header->content_id = sspm_strdup(cid); header->def = 0; } free(val); free(prop); } char* sspm_get_next_line(struct mime_impl *impl) { char* s; s = impl->get_string(impl->temp,TMP_BUF_SIZE,impl->get_string_data); if(s == 0){ impl->state = END_OF_INPUT; } return s; } void sspm_store_part(struct mime_impl *impl, struct sspm_header header, int level, void *part, size_t size) { impl->parts[impl->part_no].header = header; impl->parts[impl->part_no].level = level; impl->parts[impl->part_no].data = part; impl->parts[impl->part_no].data_size = size; impl->part_no++; } void sspm_set_error(struct sspm_header* header, enum sspm_error error, char* message) { header->error = error; if(header->error_text!=0){ free(header->error_text); } header->def = 0; if(message != 0){ header->error_text = sspm_strdup(message); } else { header->error_text = 0; } } void* sspm_make_part(struct mime_impl *impl, struct sspm_header *header, struct sspm_header *parent_header, void **end_part, size_t *size) { /* For a single part type, read to the boundary, if there is a boundary. Otherwise, read until the end of input. This routine assumes that the caller has read the header and has left the input at the first blank line */ char *line; void *part; int end = 0; struct sspm_action_map action = get_action( impl, header->major, header->minor); *size = 0; part =action.new_part(); impl->state = IN_BODY; while(end == 0 && (line = sspm_get_next_line(impl)) != 0){ if(sspm_is_mime_boundary(line)){ /* If there is a boundary, then this must be a multipart part, so there must be a parent_header. */ if(parent_header == 0){ char* boundary; end = 1; *end_part = 0; sspm_set_error(header,SSPM_UNEXPECTED_BOUNDARY_ERROR,line); /* Read until the paired terminating boundary */ if((boundary = (char*)malloc(strlen(line)+5)) == 0){ fprintf(stderr,"Out of memory"); abort(); } strcpy(boundary,line); strcat(boundary,"--"); while((line = sspm_get_next_line(impl)) != 0){ /*printf("Error: %s\n",line);*/ if(strcmp(boundary,line)==0){ break; } } free(boundary); break; } if(strncmp((line+2),parent_header->boundary, sizeof(parent_header->boundary)) == 0){ *end_part = action.end_part(part); if(sspm_is_mime_boundary(line)){ impl->state = END_OF_PART; } else if ( sspm_is_mime_terminating_boundary(line)){ impl->state = TERMINAL_END_OF_PART; } end = 1; } else { /* Error, this is not the correct terminating boundary*/ /* read and discard until we get the right boundary. */ char* boundary; char msg[256]; snprintf(msg,256, "Expected: %s--. Got: %s", parent_header->boundary,line); sspm_set_error(parent_header, SSPM_WRONG_BOUNDARY_ERROR,msg); /* Read until the paired terminating boundary */ if((boundary = (char*)malloc(strlen(line)+5)) == 0){ fprintf(stderr,"Out of memory"); abort(); } strcpy(boundary,line); strcat(boundary,"--"); while((line = sspm_get_next_line(impl)) != 0){ if(strcmp(boundary,line)==0){ break; } } free(boundary); } } else { char* data=0; char* rtrn=0; *size = strlen(line); data = (char*)malloc(*size+2); assert(data != 0); if (header->encoding == SSPM_BASE64_ENCODING){ rtrn = decode_base64(data,line,size); } else if(header->encoding == SSPM_QUOTED_PRINTABLE_ENCODING){ rtrn = decode_quoted_printable(data,line,size); } if(rtrn == 0){ strcpy(data,line); } /* add a end-of-string after the data, just in case binary data from decode64 gets passed to a tring handling routine in add_line */ data[*size+1]='\0'; action.add_line(part,header,data,*size); free(data); } } if (end == 0){ /* End the part if the input is exhausted */ *end_part = action.end_part(part); } return end_part; } void* sspm_make_multipart_subpart(struct mime_impl *impl, struct sspm_header *parent_header) { struct sspm_header header; char *line; void* part; size_t size; if(parent_header->boundary == 0){ /* Error. Multipart headers must have a boundary*/ sspm_set_error(parent_header,SSPM_NO_BOUNDARY_ERROR,0); /* read all of the reamining lines */ while((line = sspm_get_next_line(impl)) != 0){ } return 0; } /* Step 1: Read the opening boundary */ if(get_line_type(impl->temp) != BOUNDARY){ while((line=sspm_get_next_line(impl)) != 0 ){ if(sspm_is_mime_boundary(line)){ assert(parent_header != 0); /* Check if it is the right boundary */ if(!sspm_is_mime_terminating_boundary(line) && strncmp((line+2),parent_header->boundary, sizeof(parent_header->boundary)) == 0){ /* The +2 in strncmp skips over the leading "--" */ break; } else { /* Got the wrong boundary, so read and discard until we get the right boundary. */ char* boundary; char msg[256]; snprintf(msg,256, "Expected: %s. Got: %s", parent_header->boundary,line); sspm_set_error(parent_header, SSPM_WRONG_BOUNDARY_ERROR,msg); /* Read until the paired terminating boundary */ if((boundary = (char*)malloc(strlen(line)+5)) == 0){ fprintf(stderr,"Out of memory"); abort(); } strcpy(boundary,line); strcat(boundary,"--"); while((line = sspm_get_next_line(impl)) != 0){ if(strcmp(boundary,line)==0){ break; } } free(boundary); return 0; } } } } /* Step 2: Get the part header */ sspm_read_header(impl,&header); /* If the header is still listed as default, there was probably an error */ if(header.def == 1 && header.error != SSPM_NO_ERROR){ sspm_set_error(&header,SSPM_NO_HEADER_ERROR,0); return 0; } if(header.error!= SSPM_NO_ERROR){ sspm_store_part(impl,header,impl->level,0,0); return 0; } /* Step 3: read the body */ if(header.major == SSPM_MULTIPART_MAJOR_TYPE){ struct sspm_header *child_header; child_header = &(impl->parts[impl->part_no].header); /* Store the multipart part */ sspm_store_part(impl,header,impl->level,0,0); /* now get all of the sub-parts */ part = sspm_make_multipart_part(impl,child_header); if(get_line_type(impl->temp) != TERMINATING_BOUNDARY){ sspm_set_error(child_header,SSPM_NO_BOUNDARY_ERROR,impl->temp); return 0; } sspm_get_next_line(impl); /* Step past the terminating boundary */ } else { sspm_make_part(impl, &header,parent_header,&part,&size); memset(&(impl->parts[impl->part_no]), 0, sizeof(struct sspm_part)); sspm_store_part(impl,header,impl->level,part,size); } return part; } void* sspm_make_multipart_part(struct mime_impl *impl,struct sspm_header *header) { void *part=0; /* Now descend a level into each of the children of this part */ impl->level++; /* Now we are working on the CHILD */ memset(&(impl->parts[impl->part_no]), 0, sizeof(struct sspm_part)); do{ part = sspm_make_multipart_subpart(impl,header); if (part==0){ /* Clean up the part in progress */ impl->parts[impl->part_no].header.major = SSPM_NO_MAJOR_TYPE; impl->parts[impl->part_no].header.minor = SSPM_NO_MINOR_TYPE; } } while (get_line_type(impl->temp) != TERMINATING_BOUNDARY && impl->state != END_OF_INPUT); impl->level--; return 0; } void sspm_read_header(struct mime_impl *impl,struct sspm_header *header) { #define BUF_SIZE 1024 #define MAX_HEADER_LINES 25 char *buf; char header_lines[MAX_HEADER_LINES][BUF_SIZE]; /* HACK, hard limits */ int current_line = -1; int end = 0; memset(header_lines,0,sizeof(header_lines)); memset(header,0,sizeof(struct sspm_header)); /* Set up default header */ header->def = 1; header->major = SSPM_TEXT_MAJOR_TYPE; header->minor = SSPM_PLAIN_MINOR_TYPE; header->error = SSPM_NO_ERROR; header->error_text = 0; /* Read all of the lines into memory */ while(end==0&& (buf=sspm_get_next_line(impl)) != 0){ enum line_type line_type = get_line_type(buf); switch(line_type){ case BLANK: { end = 1; impl->state = END_OF_HEADER; break; } case MAIL_HEADER: case MIME_HEADER: { impl->state = IN_HEADER; current_line++; assert(strlen(buf) < BUF_SIZE); strcpy(header_lines[current_line],buf); break; } case HEADER_CONTINUATION: { char* last_line, *end; char *buf_start; if(current_line < 0){ /* This is not really a continuation line, since we have not see any header line yet */ sspm_set_error(header,SSPM_MALFORMED_HEADER_ERROR,buf); return; } last_line = header_lines[current_line]; end = (char*) ( (size_t)strlen(last_line)+ (size_t)last_line); impl->state = IN_HEADER; /* skip over the spaces in buf start, and remove the new line at the end of the lat line */ if (last_line[strlen(last_line)-1] == '\n'){ last_line[strlen(last_line)-1] = '\0'; } buf_start = buf; while(*buf_start == ' ' ||*buf_start == '\t' ){ buf_start++; } assert( strlen(buf_start) + strlen(last_line) < BUF_SIZE); strcat(last_line,buf_start); break; } default: { sspm_set_error(header,SSPM_MALFORMED_HEADER_ERROR,buf); return; } } } for(current_line = 0; current_line < MAX_HEADER_LINES && header_lines[current_line][0] != 0; current_line++){ sspm_build_header(header,header_lines[current_line]); } } /* Root routine for parsing mime entries*/ int sspm_parse_mime(struct sspm_part *parts, size_t max_parts, struct sspm_action_map *actions, char* (*get_string)(char *s, size_t size, void* data), void *get_string_data, struct sspm_header *first_header ) { struct mime_impl impl; struct sspm_header header; void *part; int i; /* Initialize all of the data */ memset(&impl,0,sizeof(struct mime_impl)); memset(&header,0,sizeof(struct sspm_header)); for(i = 0; i<(int)max_parts; i++){ parts[i].header.major = SSPM_NO_MAJOR_TYPE; parts[i].header.minor = SSPM_NO_MINOR_TYPE; } impl.parts = parts; impl.max_parts = max_parts; impl.part_no = 0; impl.actions = actions; impl.get_string = get_string; impl.get_string_data = get_string_data; /* Read the header of the message. This will be the email header, unless first_header is specified. But ( HACK) that var is not currently being used */ sspm_read_header(&impl,&header); if(header.major == SSPM_MULTIPART_MAJOR_TYPE){ struct sspm_header *child_header; child_header = &(impl.parts[impl.part_no].header); sspm_store_part(&impl,header,impl.level,0,0); part = sspm_make_multipart_part(&impl,child_header); } else { void *part; size_t size; sspm_make_part(&impl, &header, 0,&part,&size); memset(&(impl.parts[impl.part_no]), 0, sizeof(struct sspm_part)); sspm_store_part(&impl,header,impl.level,part,size); } return 0; } void sspm_free_parts(struct sspm_part *parts, size_t max_parts) { int i; for(i = 0; i<(int)max_parts && parts[i].header.major != SSPM_NO_MAJOR_TYPE; i++){ sspm_free_header(&(parts[i].header)); } } void sspm_free_header(struct sspm_header *header) { if(header->boundary!=0){ free(header->boundary); } if(header->minor_text!=0){ free(header->minor_text); } if(header->charset!=0){ free(header->charset); } if(header->filename!=0){ free(header->filename); } if(header->content_id!=0){ free(header->content_id); } if(header->error_text!=0){ free(header->error_text); } } /*********************************************************************** The remaining code is beased on code from the mimelite distribution, which has the following notice: | Authorship: | Copyright (c) 1994 Gisle Hannemyr. | Permission is granted to hack, make and distribute copies of this | program as long as this copyright notice is not removed. | Flames, bug reports, comments and improvements to: | snail: Gisle Hannemyr, Brageveien 3A, 0452 Oslo, Norway | email: Inet: gisle@oslonett.no The code is heavily modified by Eric Busboom. ***********************************************************************/ char *decode_quoted_printable(char *dest, char *src, size_t *size) { int cc; size_t i=0; while (*src != 0 && i < *size) { if (*src == '=') { src++; if (!*src) { break; } /* remove soft line breaks*/ if ((*src == '\n') || (*src == '\r')){ src++; if ((*src == '\n') || (*src == '\r')){ src++; } continue; } cc = isdigit(*src) ? (*src - '0') : (*src - 55); cc *= 0x10; src++; if (!*src) { break; } cc += isdigit(*src) ? (*src - '0') : (*src - 55); *dest = cc; } else { *dest = *src; } dest++; src++; i++; diff --git a/libical/src/libical/vsnprintf.c b/libical/src/libical/vsnprintf.c index 88a8c63..982920b 100644 --- a/libical/src/libical/vsnprintf.c +++ b/libical/src/libical/vsnprintf.c @@ -1,180 +1,172 @@ -#ifdef __osf__ +#ifndef WIN32 +#include "config.h" +#endif +#ifndef HAVE_SNPRINTF /* * Revision 12: http://theos.com/~deraadt/snprintf.c * * Copyright (c) 1997 Theo de Raadt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <sys/types.h> -#include <stdio.h> - -#include <unistd.h> +#ifndef WIN32 #include <sys/param.h> #include <sys/mman.h> +#include <unistd.h> +#endif +#include <sys/types.h> #include <signal.h> - +#include <stdio.h> #include <string.h> #if __STDC__ #include <stdarg.h> #include <stdlib.h> #else #include <varargs.h> #endif #include <setjmp.h> #ifndef roundup #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) #endif static int pgsize; static char *curobj; static sigjmp_buf bail; #define EXTRABYTES 2 /* XXX: why 2? you don't want to know */ static char * msetup(str, n) char *str; size_t n; { char *e; if (n == 0) return NULL; if (pgsize == 0) pgsize = getpagesize(); curobj = (char *)malloc(n + EXTRABYTES + pgsize * 2); if (curobj == NULL) return NULL; e = curobj + n + EXTRABYTES; e = (char *)roundup((unsigned long)e, pgsize); if (mprotect(e, pgsize, PROT_NONE) == -1) { free(curobj); curobj = NULL; return NULL; } e = e - n - EXTRABYTES; *e = '\0'; return (e); } static void mcatch(int i) { siglongjmp(bail, 1); } static void mcleanup(str, n, p) char *str; size_t n; char *p; { strncpy(str, p, n-1); str[n-1] = '\0'; if (mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, PROT_READ|PROT_WRITE|PROT_EXEC) == -1) mprotect((caddr_t)(p + n + EXTRABYTES), pgsize, PROT_READ|PROT_WRITE); free(curobj); } int #if __STDC__ vsnprintf(char *str, size_t n, char const *fmt, va_list ap) #else vsnprintf(str, n, fmt, ap) char *str; size_t n; char *fmt; char *ap; #endif { struct sigaction osa, nsa; char *p; int ret = n + 1; /* if we bail, indicated we overflowed */ memset(&nsa, 0, sizeof nsa); nsa.sa_handler = mcatch; sigemptyset(&nsa.sa_mask); p = msetup(str, n); if (p == NULL) { *str = '\0'; return 0; } if (sigsetjmp(bail, 1) == 0) { if (sigaction(SIGSEGV, &nsa, &osa) == -1) { mcleanup(str, n, p); return (0); } ret = vsprintf(p, fmt, ap); } mcleanup(str, n, p); (void) sigaction(SIGSEGV, &osa, NULL); return (ret); } int #if __STDC__ snprintf(char *str, size_t n, char const *fmt, ...) #else snprintf(str, n, fmt, va_alist) char *str; size_t n; char *fmt; va_dcl #endif { va_list ap; #if __STDC__ va_start(ap, fmt); #else va_start(ap); #endif return (vsnprintf(str, n, fmt, ap)); va_end(ap); } -#elif defined ( _WIN32 ) - -#include <stdio.h> -#include <stdarg.h> - -int snprintf(char *str, size_t n, char const *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - - return _snprintf(str, n, fmt, ap); -} #else + /* ANSI C forbids an empty source file... */ static void vsnprintf_dummy_func() { vsnprintf_dummy_func(); } #endif diff --git a/libical/src/libicalss/icalcalendar.c b/libical/src/libicalss/icalcalendar.c new file mode 100644 index 0000000..1f24f88 --- a/dev/null +++ b/libical/src/libicalss/icalcalendar.c @@ -0,0 +1,263 @@ +/*====================================================================== + FILE: icalcalendar.c + CREATOR: eric 23 December 1999 + + $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/ + + ======================================================================*/ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include "icalcalendar.h" +#include "icalset.h" +#include "icalfileset.h" +#include "icaldirset.h" +#include <limits.h> +#include <sys/stat.h> /* For mkdir, stat */ +#include <sys/types.h> /* For mkdir */ +#include <fcntl.h> /* For mkdir */ + +#ifndef WIN32 +#include <unistd.h> /* For mkdir, stat */ +#endif + +#ifndef PATH_MAX +#define PATH_MAX 512 +#endif + + +#include <stdlib.h> /* for malloc */ +#include <string.h> /* for strcat */ +#include <errno.h> + +#define BOOKED_DIR "booked" +#define INCOMING_FILE "incoming.ics" +#define PROP_FILE "properties.ics" +#define FBLIST_FILE "freebusy.ics" + +struct icalcalendar_impl +{ + char* dir; + icalset* freebusy; + icalset* properties; + icalset* booked; + icalset* incoming; +}; + +struct icalcalendar_impl* icalcalendar_new_impl(void) +{ + struct icalcalendar_impl* impl; + + if ( ( impl = (struct icalcalendar_impl*) + malloc(sizeof(struct icalcalendar_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + return impl; +} + + +icalerrorenum icalcalendar_create(struct icalcalendar_impl* impl) +{ + char path[PATH_MAX]; + struct stat sbuf; + int r; + + icalerror_check_arg_re((impl != 0),"impl",ICAL_BADARG_ERROR); + + path[0] = '\0'; + strcpy(path,impl->dir); + strcat(path,"/"); + strcat(path,BOOKED_DIR); + + r = stat(path,&sbuf); + + if( r != 0 && errno == ENOENT){ + + if(mkdir(path,0777)!=0){ + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } + } + + return ICAL_NO_ERROR; +} + +icalcalendar* icalcalendar_new(char* dir) +{ + struct icalcalendar_impl* impl; + + icalerror_check_arg_rz((dir != 0),"dir"); + + impl = icalcalendar_new_impl(); + + if (impl == 0){ + return 0; + } + + impl->dir = (char*)strdup(dir); + impl->freebusy = 0; + impl->properties = 0; + impl->booked = 0; + impl->incoming = 0; + + if (icalcalendar_create(impl) != ICAL_NO_ERROR){ + free(impl); + return 0; + } + + return impl; +} + +void icalcalendar_free(icalcalendar* impl) +{ + if (impl->dir !=0){ + free(impl->dir); + } + + if (impl->freebusy !=0){ + icalset_free(impl->booked); + } + + if (impl->properties !=0){ + icalset_free(impl->properties); + } + + if (impl->booked !=0){ + icalset_free(impl->booked); + } + + if (impl->incoming !=0){ + icalset_free(impl->incoming); + } + + impl->dir = 0; + impl->freebusy = 0; + impl->properties = 0; + impl->booked = 0; + impl->incoming = 0; + + + free(impl); +} + + +int icalcalendar_lock(icalcalendar* impl) +{ + icalerror_check_arg_rz((impl != 0),"impl"); + return 0; +} + +int icalcalendar_unlock(icalcalendar* impl) +{ + icalerror_check_arg_rz((impl != 0),"impl"); + return 0; +} + +int icalcalendar_islocked(icalcalendar* impl) +{ + icalerror_check_arg_rz((impl != 0),"impl"); + return 0; +} + +int icalcalendar_ownlock(icalcalendar* impl) +{ + icalerror_check_arg_rz((impl != 0),"impl"); + return 0; +} + +icalset* icalcalendar_get_booked(icalcalendar* impl) +{ + char dir[PATH_MAX]; + + icalerror_check_arg_rz((impl != 0),"impl"); + + dir[0] = '\0'; + strcpy(dir,impl->dir); + strcat(dir,"/"); + strcat(dir,BOOKED_DIR); + + if (impl->booked == 0){ + icalerror_clear_errno(); + impl->booked = icaldirset_new(dir); + assert(icalerrno == ICAL_NO_ERROR); + } + + return impl->booked; + +} + +icalset* icalcalendar_get_incoming(icalcalendar* impl) +{ + char path[PATH_MAX]; + icalerror_check_arg_rz((impl != 0),"impl"); + + path[0] = '\0'; + strcpy(path,impl->dir); + strcat(path,"/"); + strcat(path,INCOMING_FILE); + + if (impl->properties == 0){ + impl->properties = icalfileset_new(path); + } + + return impl->properties; +} + +icalset* icalcalendar_get_properties(icalcalendar* impl) +{ + char path[PATH_MAX]; + icalerror_check_arg_rz((impl != 0),"impl"); + + path[0] = '\0'; + strcpy(path,impl->dir); + strcat(path,"/"); + strcat(path,PROP_FILE); + + if (impl->properties == 0){ + impl->properties = icalfileset_new(path); + } + + return impl->properties; +} + +icalset* icalcalendar_get_freebusy(icalcalendar* impl) +{ + char path[PATH_MAX]; + icalerror_check_arg_rz((impl != 0),"impl"); + + path[0] = '\0'; + strcpy(path,impl->dir); + strcat(path,"/"); + strcat(path,FBLIST_FILE); + + + if (impl->freebusy == 0){ + impl->freebusy = icalfileset_new(path); + } + + return impl->freebusy; +} + + + + diff --git a/libical/src/libicalss/icalcalendar.h b/libical/src/libicalss/icalcalendar.h index f07457c..2a0c151 100644 --- a/libical/src/libicalss/icalcalendar.h +++ b/libical/src/libicalss/icalcalendar.h @@ -1,67 +1,67 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalcalendar.h CREATOR: eric 23 December 1999 $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 ======================================================================*/ #ifndef ICALCALENDAR_H #define ICALCALENDAR_H #include "ical.h" #include "icalset.h" /* icalcalendar * Routines for storing calendar data in a file system. The calendar * has two icaldirsets, one for incoming components and one for booked * components. It also has interfaces to access the free/busy list * and a list of calendar properties */ -typedef void icalcalendar; +typedef struct icalcalendar_impl icalcalendar; icalcalendar* icalcalendar_new(char* dir); void icalcalendar_free(icalcalendar* calendar); int icalcalendar_lock(icalcalendar* calendar); int icalcalendar_unlock(icalcalendar* calendar); int icalcalendar_islocked(icalcalendar* calendar); int icalcalendar_ownlock(icalcalendar* calendar); icalset* icalcalendar_get_booked(icalcalendar* calendar); icalset* icalcalendar_get_incoming(icalcalendar* calendar); icalset* icalcalendar_get_properties(icalcalendar* calendar); icalset* icalcalendar_get_freebusy(icalcalendar* calendar); #endif /* !ICALCALENDAR_H */ diff --git a/libical/src/libicalss/icalclassify.c b/libical/src/libicalss/icalclassify.c index c029309..61ddbd3 100644 --- a/libical/src/libicalss/icalclassify.c +++ b/libical/src/libicalss/icalclassify.c @@ -1,792 +1,754 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalclassify.c CREATOR: ebusboom 23 aug 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/ ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "icalerror.h" #include "ical.h" #include "icalclassify.h" #include "icalmemory.h" + #include <ctype.h> /* For tolower() */ #include <string.h> /* for index() */ #include <stdlib.h> /* for malloc and free */ struct icalclassify_parts { icalcomponent *c; icalcomponent_kind inner_kind; icalproperty_method method; char* organizer; icalparameter_partstat reply_partstat; char* reply_attendee; char* uid; int sequence; struct icaltimetype dtstamp; struct icaltimetype recurrence_id; }; char* icalclassify_lowercase(const char* str) { char* p = 0; char* new = icalmemory_strdup(str); if(str ==0){ return 0; } for(p = new; *p!=0; p++){ *p = tolower(*p); } return new; } /* Return a set of components that intersect in time with comp. For component X and Y to intersect: X.DTSTART < Y.DTEND && X.DTEND > Y.DTSTART */ icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp) { icalcomponent *return_set; icalcomponent *c; struct icaltime_span span,compspan; icalerror_clear_errno(); compspan = icalcomponent_get_span(comp); if(icalerrno != ICAL_NO_ERROR){ return 0; } return_set = icalcomponent_new(ICAL_XROOT_COMPONENT); for(c = icalset_get_first_component(set); c != 0; c = icalset_get_next_component(set)){ icalerror_clear_errno(); span = icalcomponent_get_span(c); if(icalerrno != ICAL_NO_ERROR){ continue; } if (compspan.start < span.end && compspan.end > span.start){ icalcomponent *clone = icalcomponent_new_clone(c); icalcomponent_add_component(return_set,clone); } } if(icalcomponent_count_components(return_set,ICAL_ANY_COMPONENT) !=0){ return return_set; } else { icalcomponent_free(return_set); return 0; } } icalproperty* icalclassify_find_attendee(icalcomponent *c, const char* attendee) { icalproperty *p; icalcomponent* inner; char* lattendee; char* upn; if(attendee == 0){ return 0; } lattendee = icalclassify_lowercase(attendee); upn = strchr(lattendee,':'); if (upn== 0){ upn = lattendee; } else { upn++; /* skip the ";"*/ } inner = icalcomponent_get_first_real_component(c); for(p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY); p != 0; p = icalcomponent_get_next_property(inner,ICAL_ATTENDEE_PROPERTY)) { - const char* this_attendee + char* this_attendee = icalclassify_lowercase(icalproperty_get_attendee(p)); char* this_upn = strchr(this_attendee,':'); if(this_upn == 0){ continue; } else { this_upn++; } if(strcmp(this_upn,upn)==0){ + free(lattendee); + free(this_attendee); return p; } + free(this_attendee); } + free(lattendee); return 0; } void icalssutil_free_parts(struct icalclassify_parts *parts) { if(parts == 0){ return; } if(parts->organizer != 0){ free(parts->organizer); } if(parts->uid != 0){ free(parts->uid); } if(parts->reply_attendee){ free(parts->reply_attendee); } } void icalssutil_get_parts(icalcomponent* c, struct icalclassify_parts* parts) { icalproperty *p; icalcomponent *inner; memset(parts,0,sizeof(struct icalclassify_parts)); parts->method = ICAL_METHOD_NONE; parts->sequence = 0; parts->reply_partstat = ICAL_PARTSTAT_NONE; if(c == 0){ return; } parts->c = c; p = icalcomponent_get_first_property(c,ICAL_METHOD_PROPERTY); if(p!=0){ parts->method = icalproperty_get_method(p); } inner = icalcomponent_get_first_real_component(c); parts->inner_kind = icalcomponent_isa(inner); p = icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY); if(p!=0){ parts->organizer = strdup(icalproperty_get_organizer(p)); } p = icalcomponent_get_first_property(inner,ICAL_SEQUENCE_PROPERTY); if(p!=0){ parts->sequence = icalproperty_get_sequence(p); } p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); if(p!=0){ parts->uid = strdup(icalproperty_get_uid(p)); } p = icalcomponent_get_first_property(inner,ICAL_RECURRENCEID_PROPERTY); if(p!=0){ parts->recurrence_id = icalproperty_get_recurrenceid(p); } p = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); if(p!=0){ parts->dtstamp = icalproperty_get_dtstamp(p); } if(parts->method==ICAL_METHOD_REPLY){ icalparameter *param; p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY); if(p!=0){ param = icalproperty_get_first_parameter(p,ICAL_PARTSTAT_PARAMETER); if(param != 0){ parts->reply_partstat = icalparameter_get_partstat(param); } parts->reply_attendee = strdup(icalproperty_get_attendee(p)); } } } int icalssutil_is_rescheduled(icalcomponent* a,icalcomponent* b) { icalproperty *p1,*p2; icalcomponent *i1,*i2; int i; icalproperty_kind kind_array[] = { ICAL_DTSTART_PROPERTY, ICAL_DTEND_PROPERTY, ICAL_DURATION_PROPERTY, ICAL_DUE_PROPERTY, ICAL_RRULE_PROPERTY, ICAL_RDATE_PROPERTY, ICAL_EXRULE_PROPERTY, ICAL_EXDATE_PROPERTY, ICAL_NO_PROPERTY }; i1 = icalcomponent_get_first_real_component(a); i2 = icalcomponent_get_first_real_component(b); for(i =0; kind_array[i] != ICAL_NO_PROPERTY; i++){ p1 = icalcomponent_get_first_property(i1,kind_array[i]); p2 = icalcomponent_get_first_property(i2,kind_array[i]); - if( (p1!=0)^(p1!=0) ){ + if( (p1!=0)^(p2!=0) ){ /* Return true if the property exists in one component and not the other */ return 1; } if(p1 && strcmp(icalproperty_as_ical_string(p1), icalproperty_as_ical_string(p2)) != 0){ return 1; } } return 0; } #define icalclassify_pre \ int rtrn =0; #define icalclassify_post \ return rtrn; int icalclassify_publish_new(struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre; if(comp->method == ICAL_METHOD_PUBLISH && match == 0 && comp->inner_kind != ICAL_VFREEBUSY_COMPONENT){ rtrn = 1; } icalclassify_post; } int icalclassify_publish_update(struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre; if(comp->method == ICAL_METHOD_PUBLISH && match !=0 && comp->inner_kind != ICAL_VFREEBUSY_COMPONENT){ rtrn = 1; } icalclassify_post; } int icalclassify_publish_freebusy(struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre; if(comp->method == ICAL_METHOD_PUBLISH && comp->inner_kind == ICAL_VFREEBUSY_COMPONENT){ rtrn = 1; } icalclassify_post; } int icalclassify_request_new(struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { /* Method is REQUEST, and there is no match */ icalclassify_pre if(match->c==0 && comp->method == ICAL_METHOD_REQUEST){ rtrn = 1; } icalclassify_post } int icalclassify_request_update( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { /* REQUEST method, Higher SEQUENCE than match, and all time-related properties are unchanged */ icalclassify_pre if (match != 0 && comp->sequence >= match->sequence && !icalssutil_is_rescheduled(comp->c,match->c)){ rtrn = 1; } icalclassify_post } int icalclassify_request_reschedule( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { /* REQUEST method, Higher SEQUENCE than match, and one or more time-related properties are changed */ icalclassify_pre if (match->c != 0 && comp->sequence > match->sequence && icalssutil_is_rescheduled(comp->c,match->c)){ rtrn = 1; } icalclassify_post } int icalclassify_request_delegate( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalproperty* attendee; icalparameter* param; icalclassify_pre; attendee = icalclassify_find_attendee(comp->c,user); if(attendee == 0){ return 0; } param = icalproperty_get_first_parameter(attendee,ICAL_DELEGATEDFROM_PARAMETER); if (param != 0){ rtrn = 1; } icalclassify_post } int icalclassify_request_new_organizer( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { /* Organizer has changed between match and component */ icalclassify_pre icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); icalclassify_post } int icalclassify_request_status( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); icalclassify_post } int icalclassify_request_forward( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); icalclassify_post } int icalclassify_request_freebusy( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); icalclassify_post } int icalclassify_reply_accept( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalproperty* attendee; icalclassify_pre; attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); if(attendee != 0&& comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED){ rtrn = 1; } icalclassify_post } int icalclassify_reply_decline( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalproperty* attendee; icalclassify_pre; attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); if( attendee != 0 && comp->reply_partstat == ICAL_PARTSTAT_DECLINED){ rtrn = 1; } icalclassify_post } int icalclassify_reply_delegate( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalproperty* attendee; icalclassify_pre; attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); if( attendee != 0 && comp->reply_partstat == ICAL_PARTSTAT_DELEGATED){ rtrn = 1; } icalclassify_post } int icalclassify_reply_crasher_accept( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalproperty* attendee; icalclassify_pre; attendee= icalclassify_find_attendee(match->c,comp->reply_attendee); if(attendee == 0 && comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED){ rtrn = 1; } icalclassify_post } int icalclassify_reply_crasher_decline( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { - icalparameter_partstat partstat; icalproperty* attendee; icalclassify_pre; attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); if(attendee == 0 && comp->reply_partstat == ICAL_PARTSTAT_DECLINED){ rtrn = 1; } icalclassify_post } int icalclassify_add_instance( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_ADD){ rtrn = 1; } icalclassify_post } int icalclassify_cancel_event( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_CANCEL){ rtrn = 1; } icalclassify_post } int icalclassify_cancel_instance( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_CANCEL){ rtrn = 1; } icalclassify_post } int icalclassify_cancel_all( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_CANCEL){ rtrn = 1; } icalclassify_post } int icalclassify_refesh( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_REFRESH){ rtrn = 1; } icalclassify_post } int icalclassify_counter( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_COUNTER){ rtrn = 1; } icalclassify_post } int icalclassify_delinecounter( struct icalclassify_parts *comp, struct icalclassify_parts *match, const char* user) { icalclassify_pre if(comp->method == ICAL_METHOD_DECLINECOUNTER){ rtrn = 1; } icalclassify_post } struct icalclassify_map { icalproperty_method method; int (*fn)(struct icalclassify_parts *comp,struct icalclassify_parts *match, const char* user); - ical_class class; + icalproperty_xlicclass class; } icalclassify_map[] = -{ {ICAL_METHOD_PUBLISH,icalclassify_publish_new,ICAL_PUBLISH_NEW_CLASS}, - {ICAL_METHOD_PUBLISH,icalclassify_publish_update,ICAL_PUBLISH_UPDATE_CLASS}, - {ICAL_METHOD_PUBLISH,icalclassify_publish_freebusy,ICAL_PUBLISH_FREEBUSY_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_delegate,ICAL_REQUEST_DELEGATE_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_new,ICAL_REQUEST_NEW_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_update,ICAL_REQUEST_UPDATE_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_reschedule,ICAL_REQUEST_RESCHEDULE_CLASS}, - - {ICAL_METHOD_REQUEST,icalclassify_request_new_organizer,ICAL_REQUEST_NEW_ORGANIZER_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_forward,ICAL_REQUEST_FORWARD_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_status,ICAL_REQUEST_STATUS_CLASS}, - {ICAL_METHOD_REQUEST,icalclassify_request_freebusy,ICAL_REQUEST_FREEBUSY_CLASS}, - - {ICAL_METHOD_REPLY,icalclassify_reply_accept,ICAL_REPLY_ACCEPT_CLASS}, - {ICAL_METHOD_REPLY,icalclassify_reply_decline,ICAL_REPLY_DECLINE_CLASS}, - {ICAL_METHOD_REPLY,icalclassify_reply_delegate,ICAL_REPLY_DELEGATE_CLASS}, - {ICAL_METHOD_REPLY,icalclassify_reply_crasher_accept,ICAL_REPLY_CRASHER_ACCEPT_CLASS}, - {ICAL_METHOD_REPLY,icalclassify_reply_crasher_decline,ICAL_REPLY_CRASHER_DECLINE_CLASS}, - - {ICAL_METHOD_ADD,icalclassify_add_instance,ICAL_ADD_INSTANCE_CLASS}, - - {ICAL_METHOD_CANCEL,icalclassify_cancel_event,ICAL_CANCEL_EVENT_CLASS}, - {ICAL_METHOD_CANCEL,icalclassify_cancel_instance,ICAL_CANCEL_INSTANCE_CLASS}, - {ICAL_METHOD_CANCEL,icalclassify_cancel_all,ICAL_CANCEL_ALL_CLASS}, - - {ICAL_METHOD_REFRESH,icalclassify_refesh,ICAL_REFRESH_CLASS}, - {ICAL_METHOD_COUNTER,icalclassify_counter,ICAL_COUNTER_CLASS}, - {ICAL_METHOD_DECLINECOUNTER,icalclassify_delinecounter,ICAL_DECLINECOUNTER_CLASS}, - {ICAL_METHOD_NONE,0,ICAL_NO_CLASS} +{ {ICAL_METHOD_PUBLISH,icalclassify_publish_new,ICAL_XLICCLASS_PUBLISHNEW}, + {ICAL_METHOD_PUBLISH,icalclassify_publish_update,ICAL_XLICCLASS_PUBLISHUPDATE}, + {ICAL_METHOD_PUBLISH,icalclassify_publish_freebusy,ICAL_XLICCLASS_PUBLISHFREEBUSY}, + {ICAL_METHOD_REQUEST,icalclassify_request_delegate,ICAL_XLICCLASS_REQUESTDELEGATE}, + {ICAL_METHOD_REQUEST,icalclassify_request_new,ICAL_XLICCLASS_REQUESTNEW}, + {ICAL_METHOD_REQUEST,icalclassify_request_update,ICAL_XLICCLASS_REQUESTUPDATE}, + {ICAL_METHOD_REQUEST,icalclassify_request_reschedule,ICAL_XLICCLASS_REQUESTRESCHEDULE}, + + {ICAL_METHOD_REQUEST,icalclassify_request_new_organizer,ICAL_XLICCLASS_REQUESTNEWORGANIZER}, + {ICAL_METHOD_REQUEST,icalclassify_request_forward,ICAL_XLICCLASS_REQUESTFORWARD}, + {ICAL_METHOD_REQUEST,icalclassify_request_status,ICAL_XLICCLASS_REQUESTSTATUS}, + {ICAL_METHOD_REQUEST,icalclassify_request_freebusy,ICAL_XLICCLASS_REQUESTFREEBUSY}, + + {ICAL_METHOD_REPLY,icalclassify_reply_accept,ICAL_XLICCLASS_REPLYACCEPT}, + {ICAL_METHOD_REPLY,icalclassify_reply_decline,ICAL_XLICCLASS_REPLYDECLINE}, + {ICAL_METHOD_REPLY,icalclassify_reply_delegate,ICAL_XLICCLASS_REPLYDELEGATE}, + {ICAL_METHOD_REPLY,icalclassify_reply_crasher_accept,ICAL_XLICCLASS_REPLYCRASHERACCEPT}, + {ICAL_METHOD_REPLY,icalclassify_reply_crasher_decline,ICAL_XLICCLASS_REPLYCRASHERDECLINE}, + + {ICAL_METHOD_ADD,icalclassify_add_instance,ICAL_XLICCLASS_ADDINSTANCE}, + + {ICAL_METHOD_CANCEL,icalclassify_cancel_event,ICAL_XLICCLASS_CANCELEVENT}, + {ICAL_METHOD_CANCEL,icalclassify_cancel_instance,ICAL_XLICCLASS_CANCELINSTANCE}, + {ICAL_METHOD_CANCEL,icalclassify_cancel_all,ICAL_XLICCLASS_CANCELALL}, + + {ICAL_METHOD_REFRESH,icalclassify_refesh,ICAL_XLICCLASS_REFRESH}, + {ICAL_METHOD_COUNTER,icalclassify_counter,ICAL_XLICCLASS_COUNTER}, + {ICAL_METHOD_DECLINECOUNTER,icalclassify_delinecounter,ICAL_XLICCLASS_DECLINECOUNTER}, + {ICAL_METHOD_NONE,0,ICAL_XLICCLASS_NONE} }; -ical_class icalclassify(icalcomponent* c,icalcomponent* match, +icalproperty_xlicclass icalclassify(icalcomponent* c,icalcomponent* match, const char* user) { icalcomponent *inner; icalproperty *p; icalproperty_method method; - ical_class class = ICAL_UNKNOWN_CLASS; + icalproperty_xlicclass class = ICAL_XLICCLASS_UNKNOWN; int i; struct icalclassify_parts comp_parts; struct icalclassify_parts match_parts; inner = icalcomponent_get_first_real_component(c); if (inner == 0) { - return ICAL_NO_CLASS; + return ICAL_XLICCLASS_NONE; } icalssutil_get_parts(c,&comp_parts); icalssutil_get_parts(match,&match_parts); /* Determine if the incoming component is obsoleted by the match */ if(match != 0 && ( comp_parts.method == ICAL_METHOD_REQUEST )){ assert ( ! ((comp_parts.dtstamp.is_utc==1)^ (match_parts.dtstamp.is_utc==1))); if( comp_parts.sequence<match_parts.sequence && icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)>0) { /* comp has a smaller sequence and a later DTSTAMP */ - return ICAL_MISSEQUENCED_CLASS; + class = ICAL_XLICCLASS_MISSEQUENCED; + goto CLEANUP; } if( (comp_parts.sequence<match_parts.sequence ) /*&&icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)<=0*/ || ( comp_parts.sequence == match_parts.sequence && icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)<=0)){ - return ICAL_OBSOLETE_CLASS; + class = ICAL_XLICCLASS_OBSOLETE; + goto CLEANUP; } } p = icalcomponent_get_first_property(c,ICAL_METHOD_PROPERTY); if (p == 0) { - return ICAL_UNKNOWN_CLASS; + class = ICAL_XLICCLASS_UNKNOWN; + goto CLEANUP; } method = icalproperty_get_method(p); for (i =0; icalclassify_map[i].method != ICAL_METHOD_NONE; i++){ if(icalclassify_map[i].method == method){ if( (*(icalclassify_map[i].fn))(&comp_parts,&match_parts,user)==1){ class = icalclassify_map[i].class; break; } } } +CLEANUP: icalssutil_free_parts(&comp_parts); icalssutil_free_parts(&match_parts); return class; } -struct class_map { - ical_class class; - char *str; -} class_map[] = { - {ICAL_NO_CLASS,"No class"}, - {ICAL_PUBLISH_NEW_CLASS,"New Publish"}, - {ICAL_PUBLISH_UPDATE_CLASS,"Publish Update"}, - {ICAL_PUBLISH_FREEBUSY_CLASS,"Publish freebusy"}, - {ICAL_REQUEST_NEW_CLASS,"New request"}, - {ICAL_REQUEST_UPDATE_CLASS,"Update"}, - {ICAL_REQUEST_RESCHEDULE_CLASS,"Reschedule"}, - {ICAL_REQUEST_DELEGATE_CLASS,"Delegate request"}, - {ICAL_REQUEST_NEW_ORGANIZER_CLASS,"New Organizer"}, - {ICAL_REQUEST_FORWARD_CLASS,"Forward"}, - {ICAL_REQUEST_STATUS_CLASS,"Status request"}, - {ICAL_REPLY_ACCEPT_CLASS,"Accept reply"}, - {ICAL_REPLY_DECLINE_CLASS,"Decline reply"}, - {ICAL_REPLY_DELEGATE_CLASS,"Delegation reply"}, - {ICAL_REPLY_CRASHER_ACCEPT_CLASS,"Crasher's accept reply"}, - {ICAL_REPLY_CRASHER_DECLINE_CLASS,"Crasher's decline reply"}, - {ICAL_ADD_INSTANCE_CLASS,"Add instance"}, - {ICAL_CANCEL_EVENT_CLASS,"Cancel event"}, - {ICAL_CANCEL_INSTANCE_CLASS,"Cancel instance"}, - {ICAL_CANCEL_ALL_CLASS,"Cancel all instances"}, - {ICAL_REFRESH_CLASS,"Refresh"}, - {ICAL_COUNTER_CLASS,"Counter"}, - {ICAL_DECLINECOUNTER_CLASS,"Decline counter"}, - {ICAL_MALFORMED_CLASS,"Malformed"}, - {ICAL_OBSOLETE_CLASS,"Obsolete"}, - {ICAL_MISSEQUENCED_CLASS,"Missequenced"}, - {ICAL_UNKNOWN_CLASS,"Unknown"} -}; - -char* icalclassify_class_to_string(ical_class class) -{ - int i; - - for (i = 0;class_map[i].class != ICAL_UNKNOWN_CLASS;i++){ - if (class_map[i].class == class){ - return class_map[i].str; - } - } - - return "Unknown"; -} diff --git a/libical/src/libicalss/icalclassify.h b/libical/src/libicalss/icalclassify.h index 81188b3..aceabc0 100644 --- a/libical/src/libicalss/icalclassify.h +++ b/libical/src/libicalss/icalclassify.h @@ -1,77 +1,45 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalclassify.h CREATOR: eric 21 Aug 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/ =========================================================================*/ #ifndef ICALCLASSIFY_H #define ICALCLASSIFY_H #include "ical.h" #include "icalset.h" - -typedef enum icalclass { - ICAL_NO_CLASS, - ICAL_PUBLISH_NEW_CLASS, - ICAL_PUBLISH_UPDATE_CLASS, - ICAL_PUBLISH_FREEBUSY_CLASS, - ICAL_REQUEST_NEW_CLASS, - ICAL_REQUEST_UPDATE_CLASS, - ICAL_REQUEST_RESCHEDULE_CLASS, - ICAL_REQUEST_DELEGATE_CLASS, - ICAL_REQUEST_NEW_ORGANIZER_CLASS, - ICAL_REQUEST_FORWARD_CLASS, - ICAL_REQUEST_STATUS_CLASS, - ICAL_REQUEST_FREEBUSY_CLASS, - ICAL_REPLY_ACCEPT_CLASS, - ICAL_REPLY_DECLINE_CLASS, - ICAL_REPLY_DELEGATE_CLASS, - ICAL_REPLY_CRASHER_ACCEPT_CLASS, - ICAL_REPLY_CRASHER_DECLINE_CLASS, - ICAL_ADD_INSTANCE_CLASS, - ICAL_CANCEL_EVENT_CLASS, - ICAL_CANCEL_INSTANCE_CLASS, - ICAL_CANCEL_ALL_CLASS, - ICAL_REFRESH_CLASS, - ICAL_COUNTER_CLASS, - ICAL_DECLINECOUNTER_CLASS, - ICAL_MALFORMED_CLASS, - ICAL_OBSOLETE_CLASS, /* 21 */ - ICAL_MISSEQUENCED_CLASS, /* 22 */ - ICAL_UNKNOWN_CLASS /* 23 */ -} ical_class; - -ical_class icalclassify(icalcomponent* c,icalcomponent* match, +icalproperty_xlicclass icalclassify(icalcomponent* c,icalcomponent* match, const char* user); icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp); -char* icalclassify_class_to_string(ical_class iclass); +char* icalclassify_class_to_string(icalproperty_xlicclass c); #endif /* ICALCLASSIFY_H*/ diff --git a/libical/src/libicalss/icalcluster.c b/libical/src/libicalss/icalcluster.c new file mode 100644 index 0000000..6d11078 --- a/dev/null +++ b/libical/src/libicalss/icalcluster.c @@ -0,0 +1,245 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalcluster.c + CREATOR: acampi 13 March 2002 + + $Id$ + $Locker$ + + (C) COPYRIGHT 2002, 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 + + + ======================================================================*/ + + +/** + * + * icalcluster is an utility class design to manage clusters of + * icalcomponents on behalf of an implementation of icalset. This is + * done in order to split out common behavior different classes might + * need. + * The definition of what exactly a cluster will contain depends on the + * icalset subclass. At the basic level, an icluster is just a tuple, + * with anything as key and an icalcomponent as value. + */ + + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <string.h> + +#if 0 +#include <errno.h> +#include <sys/stat.h> /* for stat */ +#ifndef WIN32 +#include <unistd.h> /* for stat, getpid */ +#else +#include <io.h> +#include <share.h> +#endif +#include <fcntl.h> /* for fcntl */ +#endif + +#include "icalcluster.h" +#include "icalclusterimpl.h" +#include "icalgauge.h" + +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif + + +icalcluster * icalcluster_new_impl(void) { + + struct icalcluster_impl* impl; + + if ((impl = (struct icalcluster_impl*)malloc( + sizeof(struct icalcluster_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + memset(impl, 0, sizeof(struct icalcluster_impl)); + strcpy(impl->id,ICALCLUSTER_ID); + + return impl; +} + +/** + * Create a cluster with a key/value pair. + * + * @todo Always do a deep copy. + */ + +icalcluster * icalcluster_new(const char* key, icalcomponent *data) { + struct icalcluster_impl *impl = icalcluster_new_impl(); + assert(impl->data == 0); + + impl->key = strdup(key); + impl->changed = 0; + impl->data = 0; + + if (data != NULL) { + if (icalcomponent_isa(data) != ICAL_XROOT_COMPONENT) { + impl->data = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(impl->data, data); + } else { + impl->data = icalcomponent_new_clone(data); + } + } else { + impl->data = icalcomponent_new(ICAL_XROOT_COMPONENT); + } + + return impl; +} + +/** + * Deep clone an icalcluster to a new one + */ + +icalcluster *icalcluster_new_clone(const icalcluster *data) { + struct icalcluster_impl *old = (struct icalcluster_impl *)data; + struct icalcluster_impl *impl = icalcluster_new_impl(); + + impl->key = strdup(old->key); + impl->data = icalcomponent_new_clone(old->data); + impl->changed = 0; + + return impl; +} + + +void icalcluster_free(icalcluster *impl) { + icalerror_check_arg_rv((impl!=0),"cluster"); + + if (impl->key != 0){ + free(impl->key); + impl->key = 0; + } + + if (impl->data != 0){ + icalcomponent_free(impl->data); + impl->data = 0; + } + + free(impl); +} + + +const char *icalcluster_key(icalcluster *impl) { + icalerror_check_arg_rz((impl!=0),"cluster"); + + return impl->key; +} + + +int icalcluster_is_changed(icalcluster *impl) { + icalerror_check_arg_rz((impl!=0),"cluster"); + + return impl->changed; +} + + +void icalcluster_mark(icalcluster *impl) { + icalerror_check_arg_rv((impl!=0),"cluster"); + + impl->changed = 1; +} + + +void icalcluster_commit(icalcluster *impl) { + icalerror_check_arg_rv((impl!=0),"cluster"); + + impl->changed = 0; +} + + +icalcomponent *icalcluster_get_component(icalcluster *impl) { + + icalerror_check_arg_rz((impl!=0),"cluster"); + + if (icalcomponent_isa(impl->data) != ICAL_XROOT_COMPONENT) { + icalerror_warn("The top component is not an XROOT"); + fprintf(stderr, "%s\n", icalcomponent_as_ical_string(impl->data)); + abort(); + } + + return impl->data; +} + + +icalerrorenum icalcluster_add_component(icalcluster *impl, icalcomponent* child) { + + icalerror_check_arg_re((impl!=0),"cluster", ICAL_BADARG_ERROR); + icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); + + icalcomponent_add_component(impl->data, child); + icalcluster_mark(impl); + + return ICAL_NO_ERROR; +} + + +icalerrorenum icalcluster_remove_component(icalcluster *impl, icalcomponent* child) { + + icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); + + icalcomponent_remove_component(impl->data,child); + icalcluster_mark(impl); + + return ICAL_NO_ERROR; +} + + +int icalcluster_count_components(icalcluster *impl, icalcomponent_kind kind) { + + icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); + + return icalcomponent_count_components(impl->data, kind); +} + + +/** Iterate through components **/ +icalcomponent *icalcluster_get_current_component(icalcluster* impl) { + + icalerror_check_arg_rz((impl!=0),"cluster"); + + return icalcomponent_get_current_component(impl->data); +} + + +icalcomponent *icalcluster_get_first_component(icalcluster* impl) { + + icalerror_check_arg_rz((impl!=0),"cluster"); + + return icalcomponent_get_first_component(impl->data, + ICAL_ANY_COMPONENT); +} + + +icalcomponent *icalcluster_get_next_component(icalcluster* impl) { + + icalerror_check_arg_rz((impl!=0),"cluster"); + + return icalcomponent_get_next_component(impl->data, + ICAL_ANY_COMPONENT); +} diff --git a/libical/src/libicalss/icalcluster.h b/libical/src/libicalss/icalcluster.h new file mode 100644 index 0000000..f4eb041 --- a/dev/null +++ b/libical/src/libicalss/icalcluster.h @@ -0,0 +1,61 @@ +/* -*- Mode: C -*- */ +/*====================================================================== + FILE: icalcluster.h + CREATOR: eric 23 December 1999 + + + $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 + + +======================================================================*/ + +#ifndef ICALCLUSTER_H +#define ICALCLUSTER_H + +#include "ical.h" +#include "icalset.h" + +typedef struct icalcluster_impl icalcluster; + +icalcluster* icalcluster_new(const char *key, icalcomponent *data); +icalcluster* icalcluster_new_clone(const icalcluster *cluster); + +void icalcluster_free(icalcluster *cluster); + +const char* icalcluster_key(icalcluster *cluster); +int icalcluster_is_changed(icalcluster *cluster); +void icalcluster_mark(icalcluster *cluster); +void icalcluster_commit(icalcluster *cluster); + +icalcomponent* icalcluster_get_component(icalcluster* cluster); +int icalcluster_count_components(icalcluster *cluster, icalcomponent_kind kind); +icalerrorenum icalcluster_add_component(icalcluster* cluster, + icalcomponent* child); +icalerrorenum icalcluster_remove_component(icalcluster* cluster, + icalcomponent* child); + +icalcomponent* icalcluster_get_current_component(icalcluster* cluster); +icalcomponent* icalcluster_get_first_component(icalcluster* cluster); +icalcomponent* icalcluster_get_next_component(icalcluster* cluster); + +#endif /* !ICALCLUSTER_H */ + + + diff --git a/libical/src/libicalss/icalclusterimpl.h b/libical/src/libicalss/icalclusterimpl.h new file mode 100644 index 0000000..ef80e1a --- a/dev/null +++ b/libical/src/libicalss/icalclusterimpl.h @@ -0,0 +1,45 @@ +/* -*- Mode: C -*- + ====================================================================== + FILE: icalfilesetimpl.h + CREATOR: eric 23 December 1999 + + $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 + +/* This definition is in its own file so it can be kept out of the + main header file, but used by "friend classes" like icaldirset*/ + +#define ICALCLUSTER_ID "clus" + +struct icalcluster_impl { + + char id[5]; /* clus */ + + char *key; + icalcomponent *data; + int changed; +}; diff --git a/libical/src/libicalss/icaldirset.c b/libical/src/libicalss/icaldirset.c index b6cb673..4a20fe1 100644 --- a/libical/src/libicalss/icaldirset.c +++ b/libical/src/libicalss/icaldirset.c @@ -1,777 +1,805 @@ /* -*- Mode: C -*- ====================================================================== FILE: icaldirset.c CREATOR: eric 28 November 1999 $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 ======================================================================*/ -/* +/** + @file icaldirset.c - icaldirset manages a database of ical components and offers + @brief icaldirset manages a database of ical components and offers interfaces for reading, writting and searching for components. icaldirset groups components in to clusters based on their DTSTAMP time -- all components that start in the same month are grouped together in a single file. All files in a sotre are kept in a single directory. - The primary interfaces are icaldirset_first and icaldirset_next. These - routine iterate through all of the components in the store, subject - to the current gauge. A gauge is an icalcomponent that is tested - against other componets for a match. If a gauge has been set with - icaldirset_select, icaldirset_first and icaldirset_next will only - return componentes that match the gauge. + The primary interfaces are icaldirset__get_first_component and + icaldirset_get_next_component. These routine iterate through all of + the components in the store, subject to the current gauge. A gauge + is an icalcomponent that is tested against other componets for a + match. If a gauge has been set with icaldirset_select, + icaldirset_first and icaldirset_next will only return componentes + that match the gauge. The Store generated UIDs for all objects that are stored if they do not already have a UID. The UID is the name of the cluster (month & year as MMYYYY) plus a unique serial number. The serial number is stored as a property of the cluster. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#include "icalerror.h" #include "ical.h" #include "icaldirset.h" -#include "pvl.h" -#include "icalparser.h" #include "icaldirset.h" #include "icalfileset.h" #include "icalfilesetimpl.h" +#include "icalcluster.h" #include "icalgauge.h" #include <limits.h> /* For PATH_MAX */ -#include <errno.h> -#include <sys/types.h> /* for opendir() */ -#include <sys/stat.h> /* for stat */ - -int snprintf(char *str, size_t n, char const *fmt, ...); - -// Eugen C. <eug@thekompany.com> -#include <defines.h> -#ifndef _QTWIN_ +#ifndef WIN32 #include <dirent.h> /* for opendir() */ -#include <unistd.h> +#include <unistd.h> /* for stat, getpid */ #include <sys/utsname.h> /* for uname */ +#else +#include <io.h> +#include <process.h> #endif -// Eugen C. <eug@thekompany.com> - +#include <errno.h> +#include <sys/types.h> /* for opendir() */ +#include <sys/stat.h> /* for stat */ #include <time.h> /* for clock() */ #include <stdlib.h> /* for rand(), srand() */ #include <string.h> /* for strdup */ #include "icaldirsetimpl.h" -struct icaldirset_impl* icaldirset_new_impl() -{ - struct icaldirset_impl* impl; +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp - if ( ( impl = (struct icaldirset_impl*) - malloc(sizeof(struct icaldirset_impl))) == 0) { - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } +#define _S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) + +#define S_ISDIR(mode) _S_ISTYPE((mode), _S_IFDIR) +#define S_ISREG(mode) _S_ISTYPE((mode), _S_IFREG) +#endif - strcpy(impl->id,ICALDIRSET_ID); +/** Default options used when NULL is passed to icalset_new() **/ +icaldirset_options icaldirset_options_default = {O_RDWR|O_CREAT}; - return impl; -} -const char* icaldirset_path(icaldirset* cluster) +const char* icaldirset_path(icalset* set) { - struct icaldirset_impl *impl = icaldirset_new_impl(); - - return impl->dir; + icaldirset *dset = (icaldirset*)set; + return dset->dir; } -void icaldirset_mark(icaldirset* store) + +void icaldirset_mark(icalset* set) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; + icaldirset *dset = (icaldirset*)set; - icalfileset_mark(impl->cluster); + icalcluster_mark(dset->cluster); } -icalerrorenum icaldirset_commit(icaldirset* store) +icalerrorenum icaldirset_commit(icalset* set) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; + icaldirset *dset = (icaldirset*)set; + icalset *fileset; + icalfileset_options options = icalfileset_options_default; - return icalfileset_commit(impl->cluster); + options.cluster = dset->cluster; + fileset = icalset_new(ICAL_FILE_SET, icalcluster_key(dset->cluster), &options); + + fileset->commit(fileset); + fileset->free(fileset); + + return ICAL_NO_ERROR; } void icaldirset_lock(const char* dir) { } void icaldirset_unlock(const char* dir) { } /* Load the contents of the store directory into the store's internal directory list*/ -icalerrorenum icaldirset_read_directory(struct icaldirset_impl* impl) +icalerrorenum icaldirset_read_directory(icaldirset *dset) { -#ifndef _QTWIN_ + char *str; +#ifndef WIN32 struct dirent *de; DIR* dp; - char *str; - dp = opendir(impl->dir); + dp = opendir(dset->dir); - if ( dp == 0) { + if (dp == 0) { icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } /* clear contents of directory list */ - while((str = pvl_pop(impl->directory))){ + while((str = pvl_pop(dset->directory))){ free(str); } /* load all of the cluster names in the directory list */ for(de = readdir(dp); de != 0; de = readdir(dp)){ /* Remove known directory names '.' and '..'*/ if (strcmp(de->d_name,".") == 0 || strcmp(de->d_name,"..") == 0 ){ continue; } - pvl_push(impl->directory, (void*)strdup(de->d_name)); + pvl_push(dset->directory, (void*)strdup(de->d_name)); } closedir(dp); - - return ICAL_NO_ERROR; #else - icalerror_set_errno(ICAL_FILE_ERROR); - return ICAL_FILE_ERROR; + struct _finddata_t c_file; + long hFile; + + /* Find first .c file in current directory */ + if( (hFile = _findfirst( "*", &c_file )) == -1L ) { + icalerror_set_errno(ICAL_FILE_ERROR); + return ICAL_FILE_ERROR; + } else { + while((str = pvl_pop(dset->directory))){ + free(str); + } + + /* load all of the cluster names in the directory list */ + do { + /* Remove known directory names '.' and '..'*/ + if (strcmp(c_file.name,".") == 0 || + strcmp(c_file.name,"..") == 0 ){ + continue; + } + + pvl_push(dset->directory, (void*)strdup(c_file.name)); + } + while ( _findnext( hFile, &c_file ) == 0 ); + + _findclose( hFile ); + } + #endif + + return ICAL_NO_ERROR; } -icaldirset* icaldirset_new(const char* dir) + +icalset* icaldirset_init(icalset* set, const char* dir, void* options_in) { - struct icaldirset_impl *impl = icaldirset_new_impl(); + icaldirset *dset = (icaldirset*)set; + icaldirset_options *options = options_in; struct stat sbuf; - if (impl == 0){ - return 0; - } - icalerror_check_arg_rz( (dir!=0), "dir"); + icalerror_check_arg_rz( (set!=0), "set"); if (stat(dir,&sbuf) != 0){ icalerror_set_errno(ICAL_FILE_ERROR); return 0; } -#ifndef _QTWIN_ /* dir is not the name of a direectory*/ if (!S_ISDIR(sbuf.st_mode)){ icalerror_set_errno(ICAL_USAGE_ERROR); return 0; } -#endif icaldirset_lock(dir); - impl = icaldirset_new_impl(); + dset->dir = (char*)strdup(dir); + dset->options = *options; + dset->directory = pvl_newlist(); + dset->directory_iterator = 0; + dset->gauge = 0; + dset->first_component = 0; + dset->cluster = 0; + + return set; +} + +icalset* icaldirset_new(const char* dir) +{ + return icalset_new(ICAL_DIR_SET, dir, &icaldirset_options_default); +} - if (impl ==0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } - impl->directory = pvl_newlist(); - impl->directory_iterator = 0; - impl->dir = (char*)strdup(dir); - impl->gauge = 0; - impl->first_component = 0; - impl->cluster = 0; +icalset* icaldirset_new_reader(const char* dir) +{ + icaldirset_options reader_options = icaldirset_options_default; - icaldirset_read_directory(impl); + reader_options.flags = O_RDONLY; - return (icaldirset*) impl; + return icalset_new(ICAL_DIR_SET, dir, &reader_options); } -void icaldirset_free(icaldirset* s) + +icalset* icaldirset_new_writer(const char* dir) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)s; + icaldirset_options writer_options = icaldirset_options_default; + + writer_options.flags = O_RDWR|O_CREAT; + + return icalset_new(ICAL_DIR_SET, dir, &writer_options); +} + + +void icaldirset_free(icalset* s) +{ + icaldirset *dset = (icaldirset*)s; char* str; - icaldirset_unlock(impl->dir); + icaldirset_unlock(dset->dir); - if(impl->dir !=0){ - free(impl->dir); + if(dset->dir !=0){ + free(dset->dir); + dset->dir = 0; } - if(impl->gauge !=0){ - icalcomponent_free(impl->gauge); + if(dset->gauge !=0){ + icalgauge_free(dset->gauge); + dset->gauge = 0; } - if(impl->cluster !=0){ - icalfileset_free(impl->cluster); + if(dset->cluster !=0){ + icalcluster_free(dset->cluster); } - while(impl->directory !=0 && (str=pvl_pop(impl->directory)) != 0){ + while(dset->directory !=0 && (str=pvl_pop(dset->directory)) != 0){ free(str); } - if(impl->directory != 0){ - pvl_free(impl->directory); + if(dset->directory != 0){ + pvl_free(dset->directory); + dset->directory = 0; } - impl->directory = 0; - impl->directory_iterator = 0; - impl->dir = 0; - impl->gauge = 0; - impl->first_component = 0; - - free(impl); - + dset->directory_iterator = 0; + dset->first_component = 0; } + /* icaldirset_next_uid_number updates a serial number in the Store directory in a file called SEQUENCE */ -int icaldirset_next_uid_number(icaldirset* store) +int icaldirset_next_uid_number(icaldirset* dset) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; char sequence = 0; char temp[128]; char filename[ICAL_PATH_MAX]; char *r; FILE *f; struct stat sbuf; - icalerror_check_arg_rz( (store!=0), "store"); + icalerror_check_arg_rz( (dset!=0), "dset"); - sprintf(filename,"%s/%s",impl->dir,"SEQUENCE"); + sprintf(filename,"%s/%s",dset->dir,"SEQUENCE"); /* Create the file if it does not exist.*/ -#ifndef _QTWIN_ if (stat(filename,&sbuf) == -1 || !S_ISREG(sbuf.st_mode)){ -#else - if (stat(filename,&sbuf) == -1){ -#endif f = fopen(filename,"w"); if (f != 0){ fprintf(f,"0"); fclose(f); } else { icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number"); return 0; } - } if ( (f = fopen(filename,"r+")) != 0){ rewind(f); r = fgets(temp,128,f); if (r == 0){ sequence = 1; } else { sequence = atoi(temp)+1; } rewind(f); fprintf(f,"%d",sequence); fclose(f); return sequence; } else { icalerror_warn("Can't create SEQUENCE file in icaldirset_next_uid_number"); return 0; } - } -icalerrorenum icaldirset_next_cluster(icaldirset* store) +icalerrorenum icaldirset_next_cluster(icaldirset* dset) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; char path[ICAL_PATH_MAX]; - if (impl->directory_iterator == 0){ + if (dset->directory_iterator == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return ICAL_INTERNAL_ERROR; } - impl->directory_iterator = pvl_next(impl->directory_iterator); + dset->directory_iterator = pvl_next(dset->directory_iterator); - if (impl->directory_iterator == 0){ + if (dset->directory_iterator == 0){ /* There are no more clusters */ - if(impl->cluster != 0){ - icalfileset_free(impl->cluster); - impl->cluster = 0; + if(dset->cluster != 0){ + icalcluster_free(dset->cluster); + dset->cluster = 0; } return ICAL_NO_ERROR; } - sprintf(path,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); + sprintf(path,"%s/%s", dset->dir,(char*)pvl_data(dset->directory_iterator)); - icalfileset_free(impl->cluster); - - impl->cluster = icalfileset_new(path); + icalcluster_free(dset->cluster); + dset->cluster = icalfileset_produce_icalcluster(path); return icalerrno; } -void icaldirset_add_uid(icaldirset* store, icaldirset* comp) +static void icaldirset_add_uid(icalcomponent* comp) { -#ifndef _QTWIN_ - char uidstring[ICAL_PATH_MAX]; icalproperty *uid; +#ifndef WIN32 struct utsname unamebuf; +#endif - icalerror_check_arg_rv( (store!=0), "store"); icalerror_check_arg_rv( (comp!=0), "comp"); uid = icalcomponent_get_first_property(comp,ICAL_UID_PROPERTY); if (uid == 0) { +#ifndef WIN32 uname(&unamebuf); sprintf(uidstring,"%d-%s",(int)getpid(),unamebuf.nodename); +#else + sprintf(uidstring,"%d-%s",(int)getpid(),"WINDOWS"); /* FIX: There must be an easy get the system name */ +#endif uid = icalproperty_new_uid(uidstring); icalcomponent_add_property(comp,uid); } else { - strcpy(uidstring,icalproperty_get_uid(uid)); } - -#endif } -/* This assumes that the top level component is a VCALENDAR, and there +/** + This assumes that the top level component is a VCALENDAR, and there is an inner component of type VEVENT, VTODO or VJOURNAL. The inner - component must have a DTAMP property */ + component must have a DSTAMP property +*/ -icalerrorenum icaldirset_add_component(icaldirset* store, icaldirset* comp) +icalerrorenum icaldirset_add_component(icalset* set, icalcomponent* comp) { - struct icaldirset_impl *impl; char clustername[ICAL_PATH_MAX]; - icalproperty *dt; + icalproperty *dt = 0; icalvalue *v; struct icaltimetype tm; icalerrorenum error = ICAL_NO_ERROR; icalcomponent *inner; + icaldirset *dset = (icaldirset*) set; - impl = (struct icaldirset_impl*)store; - icalerror_check_arg_rz( (store!=0), "store"); + icalerror_check_arg_rz( (dset!=0), "dset"); icalerror_check_arg_rz( (comp!=0), "comp"); - errno = 0; - - icaldirset_add_uid(store,comp); + icaldirset_add_uid(comp); /* Determine which cluster this object belongs in. This is a HACK */ for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); inner != 0; inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ dt = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); - if (dt != 0){ + if (dt != 0) break; } - } - - if (dt == 0){ + if (dt == 0) { for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); inner != 0; inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); - if (dt != 0){ + if (dt != 0) break; } } - } - if (dt == 0){ - - icalerror_warn("The component does not have a DTSTAMP or DTSTART property, so it cannot be added to the store"); icalerror_set_errno(ICAL_BADARG_ERROR); return ICAL_BADARG_ERROR; } v = icalproperty_get_value(dt); - tm = icalvalue_get_datetime(v); - snprintf(clustername,ICAL_PATH_MAX,"%s/%04d%02d",impl->dir,tm.year,tm.month); + snprintf(clustername,ICAL_PATH_MAX,"%s/%04d%02d",dset->dir, tm.year, tm.month); /* Load the cluster and insert the object */ - - if(impl->cluster != 0 && - strcmp(clustername,icalfileset_path(impl->cluster)) != 0 ){ - icalfileset_free(impl->cluster); - impl->cluster = 0; + if(dset->cluster != 0 && + strcmp(clustername,icalcluster_key(dset->cluster)) != 0 ){ + icalcluster_free(dset->cluster); + dset->cluster = 0; } - if (impl->cluster == 0){ - impl->cluster = icalfileset_new(clustername); + if (dset->cluster == 0){ + dset->cluster = icalfileset_produce_icalcluster(clustername); - if (impl->cluster == 0){ + if (dset->cluster == 0){ error = icalerrno; } } if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); return error; } /* Add the component to the cluster */ - - icalfileset_add_component(impl->cluster,comp); + icalcluster_add_component(dset->cluster,comp); - icalfileset_mark(impl->cluster); + /* icalcluster_mark(impl->cluster); */ return ICAL_NO_ERROR; } -/* Remove a component in the current cluster. HACK. This routine is a +/** + Remove a component in the current cluster. HACK. This routine is a "friend" of icalfileset, and breaks its encapsulation. It was either do it this way, or add several layers of interfaces that had - no other use. */ -icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp) -{ - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; - - struct icalfileset_impl *filesetimpl = - (struct icalfileset_impl*)impl->cluster; + no other use. + */ - icalcomponent *filecomp = filesetimpl->cluster; +icalerrorenum icaldirset_remove_component(icalset* set, icalcomponent* comp) +{ + icaldirset *dset = (icaldirset*)set; + icalcomponent *filecomp = icalcluster_get_component(dset->cluster); icalcompiter i; int found = 0; - icalerror_check_arg_re((store!=0),"store",ICAL_BADARG_ERROR); + icalerror_check_arg_re((set!=0),"set",ICAL_BADARG_ERROR); icalerror_check_arg_re((comp!=0),"comp",ICAL_BADARG_ERROR); - icalerror_check_arg_re((impl->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR); + icalerror_check_arg_re((dset->cluster!=0),"Cluster pointer",ICAL_USAGE_ERROR); for(i = icalcomponent_begin_component(filecomp,ICAL_ANY_COMPONENT); icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ icalcomponent *this = icalcompiter_deref(&i); if (this == comp){ found = 1; break; } } if (found != 1){ icalerror_warn("icaldirset_remove_component: component is not part of current cluster"); icalerror_set_errno(ICAL_USAGE_ERROR); return ICAL_USAGE_ERROR; } - icalfileset_remove_component(impl->cluster,comp); + icalcluster_remove_component(dset->cluster,comp); - icalfileset_mark(impl->cluster); + /* icalcluster_mark(impl->cluster); */ /* If the removal emptied the fileset, get the next fileset */ - if( icalfileset_count_components(impl->cluster,ICAL_ANY_COMPONENT)==0){ - - icalerrorenum error = icaldirset_next_cluster(store); + if( icalcluster_count_components(dset->cluster,ICAL_ANY_COMPONENT)==0){ + icalerrorenum error = icaldirset_next_cluster(dset); - if(impl->cluster != 0 && error == ICAL_NO_ERROR){ - icalfileset_get_first_component(impl->cluster); + if(dset->cluster != 0 && error == ICAL_NO_ERROR){ + icalcluster_get_first_component(dset->cluster); } else { /* HACK. Not strictly correct for impl->cluster==0 */ return error; } } else { /* Do nothing */ } return ICAL_NO_ERROR; } -int icaldirset_count_components(icaldirset* store, +int icaldirset_count_components(icalset* store, icalcomponent_kind kind) { /* HACK, not implemented */ - assert(0); return 0; } -icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c) +icalcomponent* icaldirset_fetch_match(icalset* set, icalcomponent *c) { fprintf(stderr," icaldirset_fetch_match is not implemented\n"); assert(0); + return 0; } -icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid) +icalcomponent* icaldirset_fetch(icalset* set, const char* uid) { - icalcomponent *gauge; - icalcomponent *old_gauge; + icaldirset *dset = (icaldirset*)set; + icalgauge *gauge; + icalgauge *old_gauge; icalcomponent *c; - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; + char sql[256]; - icalerror_check_arg_rz( (store!=0), "store"); + icalerror_check_arg_rz( (set!=0), "set"); icalerror_check_arg_rz( (uid!=0), "uid"); - gauge = - icalcomponent_vanew( - ICAL_VCALENDAR_COMPONENT, - icalcomponent_vanew( - ICAL_VEVENT_COMPONENT, - icalproperty_vanew_uid( - uid, - icalparameter_new_xliccomparetype( - ICAL_XLICCOMPARETYPE_EQUAL), - 0), - 0), - 0); + snprintf(sql, 256, "SELECT * FROM VEVENT WHERE UID = \"%s\"", uid); + + gauge = icalgauge_new_from_sql(sql, 0); - old_gauge = impl->gauge; - impl->gauge = gauge; + old_gauge = dset->gauge; + dset->gauge = gauge; - c= icaldirset_get_first_component(store); + c= icaldirset_get_first_component(set); - impl->gauge = old_gauge; + dset->gauge = old_gauge; - icalcomponent_free(gauge); + icalgauge_free(gauge); return c; } -int icaldirset_has_uid(icaldirset* store, const char* uid) +int icaldirset_has_uid(icalset* set, const char* uid) { icalcomponent *c; - icalerror_check_arg_rz( (store!=0), "store"); + icalerror_check_arg_rz( (set!=0), "set"); icalerror_check_arg_rz( (uid!=0), "uid"); /* HACK. This is a temporary implementation. _has_uid should use a database, and _fetch should use _has_uid, not the other way around */ - c = icaldirset_fetch(store,uid); + c = icaldirset_fetch(set,uid); return c!=0; } -icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge) - { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; +icalerrorenum icaldirset_select(icalset* set, icalgauge* gauge) +{ + icaldirset *dset = (icaldirset*)set; - icalerror_check_arg_re( (store!=0), "store",ICAL_BADARG_ERROR); + icalerror_check_arg_re( (set!=0), "set",ICAL_BADARG_ERROR); icalerror_check_arg_re( (gauge!=0), "gauge",ICAL_BADARG_ERROR); - if (!icalcomponent_is_valid(gauge)){ - return ICAL_BADARG_ERROR; - } - - impl->gauge = gauge; + dset->gauge = gauge; return ICAL_NO_ERROR; } -icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *old, +icalerrorenum icaldirset_modify(icalset* set, + icalcomponent *old, icalcomponent *new) { assert(0); return ICAL_NO_ERROR; /* HACK, not implemented */ } -void icaldirset_clear(icaldirset* store) +void icaldirset_clear(icalset* set) { assert(0); return; /* HACK, not implemented */ } -icalcomponent* icaldirset_get_current_component(icaldirset* store) +icalcomponent* icaldirset_get_current_component(icalset* set) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; + icaldirset *dset = (icaldirset*)set; - if(impl->cluster == 0){ - icaldirset_get_first_component(store); + if (dset->cluster == 0){ + icaldirset_get_first_component(set); + } + if(dset->cluster == 0){ + return 0; } - return icalfileset_get_current_component(impl->cluster); - + return icalcluster_get_current_component(dset->cluster); } -icalcomponent* icaldirset_get_first_component(icaldirset* store) +icalcomponent* icaldirset_get_first_component(icalset* set) { - struct icaldirset_impl *impl = (struct icaldirset_impl*)store; + icaldirset *dset = (icaldirset*)set; + icalerrorenum error; char path[ICAL_PATH_MAX]; - error = icaldirset_read_directory(impl); + error = icaldirset_read_directory(dset); if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); return 0; } - impl->directory_iterator = pvl_head(impl->directory); + dset->directory_iterator = pvl_head(dset->directory); - if (impl->directory_iterator == 0){ + if (dset->directory_iterator == 0){ icalerror_set_errno(error); return 0; } - snprintf(path,ICAL_PATH_MAX,"%s/%s",impl->dir,(char*)pvl_data(impl->directory_iterator)); + snprintf(path,ICAL_PATH_MAX,"%s/%s", + dset->dir, + (char*)pvl_data(dset->directory_iterator)); /* If the next cluster we need is different than the current cluster, delete the current one and get a new one */ - if(impl->cluster != 0 && strcmp(path,icalfileset_path(impl->cluster)) != 0 ){ - icalfileset_free(impl->cluster); - impl->cluster = 0; + if(dset->cluster != 0 && strcmp(path,icalcluster_key(dset->cluster)) != 0 ){ + icalcluster_free(dset->cluster); + dset->cluster = 0; } - if (impl->cluster == 0){ - impl->cluster = icalfileset_new(path); + if (dset->cluster == 0){ + dset->cluster = icalfileset_produce_icalcluster(path); - if (impl->cluster == 0){ + if (dset->cluster == 0){ error = icalerrno; } } if (error != ICAL_NO_ERROR){ icalerror_set_errno(error); return 0; } - impl->first_component = 1; + dset->first_component = 1; - return icaldirset_get_next_component(store); + return icaldirset_get_next_component(set); } -icalcomponent* icaldirset_get_next_component(icaldirset* store) + +icalcomponent* icaldirset_get_next_component(icalset* set) { - struct icaldirset_impl *impl; + icaldirset *dset = (icaldirset*)set; icalcomponent *c; icalerrorenum error; - icalerror_check_arg_rz( (store!=0), "store"); - - impl = (struct icaldirset_impl*)store; + icalerror_check_arg_rz( (set!=0), "set"); - if(impl->cluster == 0){ + if(dset->cluster == 0){ icalerror_warn("icaldirset_get_next_component called with a NULL cluster (Caller must call icaldirset_get_first_component first"); icalerror_set_errno(ICAL_USAGE_ERROR); return 0; } /* Set the component iterator for the following for loop */ - if (impl->first_component == 1){ - icalfileset_get_first_component(impl->cluster); - impl->first_component = 0; + if (dset->first_component == 1){ + icalcluster_get_first_component(dset->cluster); + dset->first_component = 0; } else { - icalfileset_get_next_component(impl->cluster); + icalcluster_get_next_component(dset->cluster); } - while(1){ /* Iterate through all of the objects in the cluster*/ - for( c = icalfileset_get_current_component(impl->cluster); + for( c = icalcluster_get_current_component(dset->cluster); c != 0; - c = icalfileset_get_next_component(impl->cluster)){ + c = icalcluster_get_next_component(dset->cluster)){ /* If there is a gauge defined and the component does not pass the gauge, skip the rest of the loop */ -#if 0 /* HACK */ - if (impl->gauge != 0 && icalgauge_test(c,impl->gauge) == 0){ + if (dset->gauge != 0 && icalgauge_compare(dset->gauge,c) == 0){ continue; } -#else - assert(0); /* icalgauge_test needs to be fixed */ -#endif + /* Either there is no gauge, or the component passed the gauge, so return it*/ return c; } /* Fell through the loop, so the component we want is not in this cluster. Load a new cluster and try again.*/ - error = icaldirset_next_cluster(store); + error = icaldirset_next_cluster(dset); - if(impl->cluster == 0 || error != ICAL_NO_ERROR){ + if(dset->cluster == 0 || error != ICAL_NO_ERROR){ /* No more clusters */ return 0; } else { - c = icalfileset_get_first_component(impl->cluster); + c = icalcluster_get_first_component(dset->cluster); return c; } } return 0; /* Should never get here */ } - +icalsetiter icaldirset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge) +{ + icalsetiter itr = icalsetiter_null; + icaldirset *fset = (icaldirset*) set; + icalerror_check_arg_re((fset!=0), "set", icalsetiter_null); + itr.iter.kind = kind; + itr.gauge = gauge; + /* TO BE IMPLEMENTED */ + return icalsetiter_null; +} - +icalcomponent* icaldirsetiter_to_next(icalset* set, icalsetiter* i) +{ + /* TO BE IMPLEMENTED */ + return NULL; +} + +icalcomponent* icaldirsetiter_to_prior(icalset* set, icalsetiter* i) +{ + /* TO BE IMPLEMENTED */ + return NULL; +} diff --git a/libical/src/libicalss/icaldirset.h b/libical/src/libicalss/icaldirset.h index 7d205ec..a2d577d 100644 --- a/libical/src/libicalss/icaldirset.h +++ b/libical/src/libicalss/icaldirset.h @@ -1,82 +1,98 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icaldirset.h CREATOR: eric 28 November 1999 $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 ======================================================================*/ #ifndef ICALDIRSET_H #define ICALDIRSET_H #include "ical.h" +#include "icalset.h" +#include "icalcluster.h" +#include "icalgauge.h" /* icaldirset Routines for storing, fetching, and searching for ical * objects in a database */ -typedef void icaldirset; +typedef struct icaldirset_impl icaldirset; +icalset* icaldirset_new(const char* path); -icaldirset* icaldirset_new(const char* path); +icalset* icaldirset_new_reader(const char* path); +icalset* icaldirset_new_writer(const char* path); -void icaldirset_free(icaldirset* store); -const char* icaldirset_path(icaldirset* store); +icalset* icaldirset_init(icalset* set, const char *dsn, void *options); +void icaldirset_free(icalset* set); + +const char* icaldirset_path(icalset* set); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately*/ -void icaldirset_mark(icaldirset* store); -icalerrorenum icaldirset_commit(icaldirset* store); +void icaldirset_mark(icalset* set); +icalerrorenum icaldirset_commit(icalset* set); -icalerrorenum icaldirset_add_component(icaldirset* store, icalcomponent* comp); -icalerrorenum icaldirset_remove_component(icaldirset* store, icalcomponent* comp); +icalerrorenum icaldirset_add_component(icalset* store, icalcomponent* comp); +icalerrorenum icaldirset_remove_component(icalset* store, icalcomponent* comp); -int icaldirset_count_components(icaldirset* store, +int icaldirset_count_components(icalset* store, icalcomponent_kind kind); /* Restrict the component returned by icaldirset_first, _next to those that pass the gauge. _clear removes the gauge. */ -icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge); -void icaldirset_clear(icaldirset* store); +icalerrorenum icaldirset_select(icalset* store, icalgauge* gauge); +void icaldirset_clear(icalset* store); /* Get a component by uid */ -icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid); -int icaldirset_has_uid(icaldirset* store, const char* uid); -icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c); +icalcomponent* icaldirset_fetch(icalset* store, const char* uid); +int icaldirset_has_uid(icalset* store, const char* uid); +icalcomponent* icaldirset_fetch_match(icalset* set, icalcomponent *c); /* Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ -icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc, +icalerrorenum icaldirset_modify(icalset* store, icalcomponent *oldc, icalcomponent *newc); -/* Iterate through the components. If a guage has been defined, these +/* Iterate through the components. If a gauge has been defined, these will skip over components that do not pass the gauge */ -icalcomponent* icaldirset_get_current_component(icaldirset* store); -icalcomponent* icaldirset_get_first_component(icaldirset* store); -icalcomponent* icaldirset_get_next_component(icaldirset* store); +icalcomponent* icaldirset_get_current_component(icalset* store); +icalcomponent* icaldirset_get_first_component(icalset* store); +icalcomponent* icaldirset_get_next_component(icalset* store); + +/* External iterator for thread safety */ +icalsetiter icaldirset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge); +icalcomponent* icaldirsetiter_to_next(icalset* set, icalsetiter* i); +icalcomponent* icaldirsetiter_to_prior(icalset* set, icalsetiter* i); + +typedef struct icaldirset_options { + int flags; /**< flags corresponding to the open() system call O_RDWR, etc. */ +} icaldirset_options; #endif /* !ICALDIRSET_H */ diff --git a/libical/src/libicalss/icaldirsetimpl.h b/libical/src/libicalss/icaldirsetimpl.h index 0e69ba2..332a369 100644 --- a/libical/src/libicalss/icaldirsetimpl.h +++ b/libical/src/libicalss/icaldirsetimpl.h @@ -1,47 +1,48 @@ /* -*- Mode: C -*- ====================================================================== FILE: icaldirsetimpl.h CREATOR: eric 21 Aug 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 "icalcluster.h" + /* This definition is in its own file so it can be kept out of the main header file, but used by "friend classes" like icalset*/ -#define ICALDIRSET_ID "dset" - struct icaldirset_impl { - char id[5]; /* "dset" */ - char* dir; - icalcomponent* gauge; - icaldirset* cluster; - int first_component; - pvl_list directory; - pvl_elem directory_iterator; + icalset super; /**< parent class */ + char* dir; /**< directory containing ics files */ + icaldirset_options options; /**< copy of options passed to icalset_new() */ + icalcluster* cluster; /**< cluster containing data */ + icalgauge* gauge; /**< gauge for filtering out data */ + int first_component; /**< ??? */ + pvl_list directory; /**< ??? */ + pvl_elem directory_iterator; /**< ??? */ }; diff --git a/libical/src/libicalss/icalfileset.c b/libical/src/libicalss/icalfileset.c index 943071d..3ae6c54 100644 --- a/libical/src/libicalss/icalfileset.c +++ b/libical/src/libicalss/icalfileset.c @@ -1,659 +1,934 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalfileset.c CREATOR: eric 23 December 1999 $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 "icalfileset.h" +#include "icalgauge.h" #include <errno.h> - +#include <sys/stat.h> /* for stat */ +#ifndef WIN32 +#include <unistd.h> /* for stat, getpid */ +#else +#include <io.h> +#include <share.h> +#endif #include <stdlib.h> -#include <stdio.h> #include <string.h> +#include <fcntl.h> /* for fcntl */ +#include "icalfilesetimpl.h" +#include "icalclusterimpl.h" -#include <fcntl.h> /* For open() flags and mode */ -#include <sys/types.h> /* For open() flags and mode */ -#include <sys/stat.h> /* For open() flags and mode */ +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp -#include "icalfileset.h" -#include "icalfilesetimpl.h" +#define _S_ISTYPE(mode, mask) (((mode) & _S_IFMT) == (mask)) -// Eugen C. <eug@thekompany.com> -#include <defines.h> -// +#define S_ISDIR(mode) _S_ISTYPE((mode), _S_IFDIR) +#define S_ISREG(mode) _S_ISTYPE((mode), _S_IFREG) +#endif -int snprintf(char *str, size_t n, char const *fmt, ...); +extern int errno; -//extern int errno; +/** Default options used when NULL is passed to icalset_new() **/ +icalfileset_options icalfileset_options_default = {O_RDWR|O_CREAT, 0644, 0, 0}; -int icalfileset_lock(icalfileset *cluster); -int icalfileset_unlock(icalfileset *cluster); -icalerrorenum icalfileset_read_file(icalfileset* cluster, mode_t mode); -int icalfileset_filesize(icalfileset* cluster); +int icalfileset_lock(icalfileset *set); +int icalfileset_unlock(icalfileset *set); +icalerrorenum icalfileset_read_file(icalfileset* set, mode_t mode); +int icalfileset_filesize(icalfileset* set); icalerrorenum icalfileset_create_cluster(const char *path); -icalfileset* icalfileset_new_impl() +icalset* icalfileset_new(const char* path) { - struct icalfileset_impl* impl; - - if ( ( impl = (struct icalfileset_impl*) - malloc(sizeof(struct icalfileset_impl))) == 0) { - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - errno = ENOMEM; - return 0; - } - - memset(impl,0,sizeof(struct icalfileset_impl)); - - strcpy(impl->id,ICALFILESET_ID); - - return impl; + return icalset_new(ICAL_FILE_SET, path, &icalfileset_options_default); } - -icalfileset* icalfileset_new(const char* path) +icalset* icalfileset_new_reader(const char* path) { - return icalfileset_new_open(path, O_RDWR|O_CREAT, 0664); + icalfileset_options reader_options = icalfileset_options_default; + reader_options.flags = O_RDONLY; + + return icalset_new(ICAL_FILE_SET, path, &reader_options); } -icalfileset* icalfileset_new_open(const char* path, int flags, mode_t mode) +icalset* icalfileset_new_writer(const char* path) { - struct icalfileset_impl *impl = icalfileset_new_impl(); - struct icaltimetype tt; - off_t cluster_file_size; + icalfileset_options writer_options = icalfileset_options_default; + writer_options.flags = O_RDONLY; - memset(&tt,0,sizeof(struct icaltimetype)); + return icalset_new(ICAL_FILE_SET, path, &writer_options); +} - icalerror_clear_errno(); - icalerror_check_arg_rz( (path!=0), "path"); +icalset* icalfileset_init(icalset *set, const char* path, void* options_in) +{ + icalfileset_options *options = (options_in) ? options_in : &icalfileset_options_default; + icalfileset *fset = (icalfileset*) set; + int flags; + mode_t mode; + off_t cluster_file_size; - if (impl == 0){ - return 0; - } + icalerror_clear_errno(); + icalerror_check_arg_rz( (path!=0), "path"); + icalerror_check_arg_rz( (fset!=0), "fset"); - impl->path = strdup(path); + fset->path = strdup(path); + fset->options = *options; - cluster_file_size = icalfileset_filesize(impl); - - if(cluster_file_size < 0){ - icalfileset_free(impl); - return 0; - } + flags = options->flags; + mode = options->mode; + + cluster_file_size = icalfileset_filesize(fset); + + if(cluster_file_size < 0){ + icalfileset_free(set); + return 0; + } - impl->fd = open(impl->path,flags, mode); +#ifndef WIN32 + fset->fd = open(fset->path, flags, mode); +#else + fset->fd = open(fset->path, flags, mode); + /* fset->fd = sopen(fset->path,flags, _SH_DENYWR, _S_IREAD | _S_IWRITE); */ +#endif - if (impl->fd < 0){ - icalerror_set_errno(ICAL_FILE_ERROR); - icalfileset_free(impl); - return 0; - } + if (fset->fd < 0){ + icalerror_set_errno(ICAL_FILE_ERROR); + icalfileset_free(set); + return 0; + } - icalfileset_lock(impl); +#ifndef WIN32 + icalfileset_lock(fset); +#endif if(cluster_file_size > 0 ){ icalerrorenum error; - if((error = icalfileset_read_file(impl,mode))!= ICAL_NO_ERROR){ - icalfileset_free(impl); - return 0; + if((error = icalfileset_read_file(fset,mode))!= ICAL_NO_ERROR){ + icalfileset_free(set); + return 0; } } - if(impl->cluster == 0){ - impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); - } + if (options->cluster) { + fset->cluster = icalcomponent_new_clone(icalcluster_get_component(options->cluster)); + fset->changed = 1; + } + + if (fset->cluster == 0) { + fset->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + } + + return set; +} + + +icalcluster* icalfileset_produce_icalcluster(const char *path) { + icalset *fileset; + icalcluster *ret; + + int errstate = icalerror_errors_are_fatal; + icalerror_errors_are_fatal = 0; - return impl; + fileset = icalfileset_new_reader(path); + + + if (fileset == 0 && icalerrno == ICAL_FILE_ERROR) { + /* file does not exist */ + ret = icalcluster_new(path, NULL); + } else { + ret = icalcluster_new(path, ((icalfileset*)fileset)->cluster); + icalfileset_free(fileset); + } + + icalerror_errors_are_fatal = errstate; + icalerror_set_errno(ICAL_NO_ERROR); + return ret; } + + char* icalfileset_read_from_file(char *s, size_t size, void *d) { - char* p = s; int fd = (int)d; /* Simulate fgets -- read single characters and stop at '\n' */ for(p=s; p<s+size-1;p++){ if(read(fd,p,1) != 1 || *p=='\n'){ p++; break; } } *p = '\0'; if(*s == 0){ return 0; } else { return s; } } -icalerrorenum icalfileset_read_file(icalfileset* cluster,mode_t mode) +icalerrorenum icalfileset_read_file(icalfileset* set,mode_t mode) { - icalparser *parser; - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; - parser = icalparser_new(); - icalparser_set_gen_data(parser,(void*)impl->fd); - impl->cluster = icalparser_parse(parser,icalfileset_read_from_file); + + icalparser_set_gen_data(parser,(void*)set->fd); + set->cluster = icalparser_parse(parser,icalfileset_read_from_file); icalparser_free(parser); - if (impl->cluster == 0 || icalerrno != ICAL_NO_ERROR){ + if (set->cluster == 0 || icalerrno != ICAL_NO_ERROR){ icalerror_set_errno(ICAL_PARSE_ERROR); - return ICAL_PARSE_ERROR; + /*return ICAL_PARSE_ERROR;*/ } - if (icalcomponent_isa(impl->cluster) != ICAL_XROOT_COMPONENT){ + if (icalcomponent_isa(set->cluster) != ICAL_XROOT_COMPONENT){ /* The parser got a single component, so it did not put it in an XROOT. */ - icalcomponent *cl = impl->cluster; - impl->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); - icalcomponent_add_component(impl->cluster,cl); + icalcomponent *cl = set->cluster; + set->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); + icalcomponent_add_component(set->cluster,cl); } return ICAL_NO_ERROR; - } -int icalfileset_filesize(icalfileset* cluster) +int icalfileset_filesize(icalfileset* fset) { - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; int cluster_file_size; struct stat sbuf; - - if (stat(impl->path,&sbuf) != 0){ + + if (stat(fset->path,&sbuf) != 0){ /* A file by the given name does not exist, or there was another error */ cluster_file_size = 0; if (errno == ENOENT) { /* It was because the file does not exist */ return 0; } else { /* It was because of another error */ icalerror_set_errno(ICAL_FILE_ERROR); return -1; } } else { /* A file by the given name exists, but is it a regular file? */ -#ifndef _QTWIN_ if (!S_ISREG(sbuf.st_mode)){ /* Nope, not a regular file */ icalerror_set_errno(ICAL_FILE_ERROR); return -1; } else { /* Lets assume that it is a file of the right type */ return sbuf.st_size; - } -#else - return sbuf.st_size; -#endif - + } } /*return -1; not reached*/ } -void icalfileset_free(icalfileset* cluster) +void icalfileset_free(icalset* set) { - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_rv((cluster!=0),"cluster"); + icalerror_check_arg_rv((set!=0),"set"); - if (impl->cluster != 0){ - icalfileset_commit(cluster); - icalcomponent_free(impl->cluster); - impl->cluster=0; + if (fset->cluster != 0){ + icalfileset_commit(set); + icalcomponent_free(fset->cluster); + fset->cluster=0; } - if(impl->fd > 0){ - icalfileset_unlock(impl); - close(impl->fd); - impl->fd = -1; + if (fset->gauge != 0){ + icalgauge_free(fset->gauge); + fset->gauge=0; } - if(impl->path != 0){ - free(impl->path); - impl->path = 0; + if(fset->fd > 0){ + icalfileset_unlock(fset); + close(fset->fd); + fset->fd = -1; } - free(impl); + if(fset->path != 0){ + free(fset->path); + fset->path = 0; + } } -const char* icalfileset_path(icalfileset* cluster) -{ - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; - icalerror_check_arg_rz((cluster!=0),"cluster"); +const char* icalfileset_path(icalset* set) { + icalerror_check_arg_rz((set!=0),"set"); - return impl->path; + return ((icalfileset*)set)->path; } -int icalfileset_lock(icalfileset *cluster) +int icalfileset_lock(icalfileset *set) { -#ifndef _WIN32 - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; +#ifndef WIN32 struct flock lock; int rtrn; - icalerror_check_arg_rz((impl->fd>0),"impl->fd"); + icalerror_check_arg_rz((set->fd>0),"set->fd"); errno = 0; lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ lock.l_start = 0; /* byte offset relative to l_whence */ lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock.l_len = 0; /* #bytes (0 means to EOF) */ - rtrn = fcntl(impl->fd, F_SETLKW, &lock); + rtrn = fcntl(set->fd, F_SETLKW, &lock); return rtrn; #else - return -1; + return 0; #endif } -int icalfileset_unlock(icalfileset *cluster) +int icalfileset_unlock(icalfileset *set) { -#ifndef _WIN32 - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; +#ifndef WIN32 struct flock lock; - icalerror_check_arg_rz((impl->fd>0),"impl->fd"); + icalerror_check_arg_rz((set->fd>0),"set->fd"); lock.l_type = F_WRLCK; /* F_RDLCK, F_WRLCK, F_UNLCK */ lock.l_start = 0; /* byte offset relative to l_whence */ lock.l_whence = SEEK_SET; /* SEEK_SET, SEEK_CUR, SEEK_END */ lock.l_len = 0; /* #bytes (0 means to EOF) */ - return (fcntl(impl->fd, F_UNLCK, &lock)); + return (fcntl(set->fd, F_UNLCK, &lock)); #else - return -1; + return 0; #endif } -#ifdef ICAL_SAFESAVES -int icalfileset_safe_saves=1; -#else -int icalfileset_safe_saves=0; -#endif - -icalerrorenum icalfileset_commit(icalfileset* cluster) +icalerrorenum icalfileset_commit(icalset* set) { char tmp[ICAL_PATH_MAX]; char *str; icalcomponent *c; off_t write_size=0; + icalfileset *fset = (icalfileset*) set; + + icalerror_check_arg_re((fset!=0),"set",ICAL_BADARG_ERROR); - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; - - icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); - - icalerror_check_arg_re((impl->fd>0),"impl->fd is invalid", + icalerror_check_arg_re((fset->fd>0),"set->fd is invalid", ICAL_INTERNAL_ERROR) ; - if (impl->changed == 0 ){ + if (fset->changed == 0 ){ return ICAL_NO_ERROR; } - if(icalfileset_safe_saves == 1){ - snprintf(tmp,ICAL_PATH_MAX,"cp %s %s.bak",impl->path,impl->path); + if (fset->options.safe_saves == 1) { +#ifndef WIN32 + snprintf(tmp,ICAL_PATH_MAX,"cp '%s' '%s.bak'",fset->path, fset->path); +#else + snprintf(tmp,ICAL_PATH_MAX,"copy %s %s.bak", fset->path, fset->path); +#endif if(system(tmp) < 0){ icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } } - if(lseek(impl->fd,SEEK_SET,0) < 0){ + if(lseek(fset->fd, 0, SEEK_SET) < 0){ icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } - for(c = icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); + for(c = icalcomponent_get_first_component(fset->cluster,ICAL_ANY_COMPONENT); c != 0; - c = icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT)){ + c = icalcomponent_get_next_component(fset->cluster,ICAL_ANY_COMPONENT)){ int sz; str = icalcomponent_as_ical_string(c); - sz=write(impl->fd,str,strlen(str)); + sz=write(fset->fd,str,strlen(str)); if ( sz != strlen(str)){ perror("write"); icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } write_size += sz; } - impl->changed = 0; + fset->changed = 0; -#ifndef _QTWIN_ - if(ftruncate(impl->fd,write_size) < 0){ +#ifndef WIN32 + if(ftruncate(fset->fd,write_size) < 0){ return ICAL_FILE_ERROR; } +#else + chsize( fset->fd, tell( fset->fd ) ); #endif return ICAL_NO_ERROR; - } -void icalfileset_mark(icalfileset* cluster){ - - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; - - icalerror_check_arg_rv((impl!=0),"cluster"); - - impl->changed = 1; +void icalfileset_mark(icalset* set) { + icalerror_check_arg_rv((set!=0),"set"); + ((icalfileset*)set)->changed = 1; } -icalcomponent* icalfileset_get_component(icalfileset* cluster){ - struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; +icalcomponent* icalfileset_get_component(icalset* set){ + icalfileset *fset = (icalfileset*) set; + icalerror_check_arg_rz((set!=0),"set"); - icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); - - return impl->cluster; + return fset->cluster; } -/* manipulate the components in the cluster */ +/* manipulate the components in the set */ -icalerrorenum icalfileset_add_component(icalfileset *cluster, +icalerrorenum icalfileset_add_component(icalset *set, icalcomponent* child) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_re((cluster!=0),"cluster", ICAL_BADARG_ERROR); + icalerror_check_arg_re((set!=0),"set", ICAL_BADARG_ERROR); icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); - icalcomponent_add_component(impl->cluster,child); + icalcomponent_add_component(fset->cluster,child); - icalfileset_mark(cluster); + icalfileset_mark(set); return ICAL_NO_ERROR; - } -icalerrorenum icalfileset_remove_component(icalfileset *cluster, +icalerrorenum icalfileset_remove_component(icalset *set, icalcomponent* child) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_re((cluster!=0),"cluster",ICAL_BADARG_ERROR); + icalerror_check_arg_re((set!=0),"set",ICAL_BADARG_ERROR); icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); - icalcomponent_remove_component(impl->cluster,child); + icalcomponent_remove_component(fset->cluster,child); - icalfileset_mark(cluster); + icalfileset_mark(set); return ICAL_NO_ERROR; } -int icalfileset_count_components(icalfileset *cluster, +int icalfileset_count_components(icalset *set, icalcomponent_kind kind) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; - if(cluster == 0){ + if (set == 0){ icalerror_set_errno(ICAL_BADARG_ERROR); return -1; } - return icalcomponent_count_components(impl->cluster,kind); + return icalcomponent_count_components(fset->cluster,kind); } -icalerrorenum icalfileset_select(icalfileset* set, icalgauge* gauge) +icalerrorenum icalfileset_select(icalset* set, icalgauge* gauge) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)set; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_re(gauge!=0,"guage",ICAL_BADARG_ERROR); + icalerror_check_arg_re(gauge!=0,"gauge",ICAL_BADARG_ERROR); - impl->gauge = gauge; + fset->gauge = gauge; return ICAL_NO_ERROR; } -void icalfileset_clear(icalfileset* gauge) +void icalfileset_clear(icalset* set) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)gauge; - - impl->gauge = 0; + icalfileset *fset = (icalfileset*) set; + + icalerror_check_arg_rv(set!=0,"set"); + fset->gauge = 0; } -icalcomponent* icalfileset_fetch(icalfileset* store,const char* uid) +icalcomponent* icalfileset_fetch(icalset* set,const char* uid) { + icalfileset *fset = (icalfileset*) set; icalcompiter i; - struct icalfileset_impl* impl = (struct icalfileset_impl*)store; + + icalerror_check_arg_rz(set!=0,"set"); - for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); + for(i = icalcomponent_begin_component(fset->cluster,ICAL_ANY_COMPONENT); icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ - icalcomponent *this = icalcompiter_deref(&i); - icalcomponent *inner = icalcomponent_get_first_real_component(this); - icalcomponent *p; - const char *this_uid; - - if(inner != 0){ - p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); - this_uid = icalproperty_get_uid(p); - - if(this_uid==0){ - icalerror_warn("icalfileset_fetch found a component with no UID"); - continue; - } - - if (strcmp(uid,this_uid)==0){ - return this; - } + icalcomponent *this = icalcompiter_deref(&i); + icalcomponent *inner; + icalproperty *p; + const char *this_uid; + + for(inner = icalcomponent_get_first_component(this,ICAL_ANY_COMPONENT); + inner != 0; + inner = icalcomponent_get_next_component(this,ICAL_ANY_COMPONENT)){ + + p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); + if ( p ) + { + this_uid = icalproperty_get_uid(p); + + if(this_uid==0){ + icalerror_warn("icalfileset_fetch found a component with no UID"); + continue; + } + + if (strcmp(uid,this_uid)==0){ + return this; + } + } + } } - } return 0; } -int icalfileset_has_uid(icalfileset* store,const char* uid) +int icalfileset_has_uid(icalset* set,const char* uid) { assert(0); /* HACK, not implemented */ return 0; } /******* support routines for icalfileset_fetch_match *********/ struct icalfileset_id{ char* uid; char* recurrence_id; int sequence; }; void icalfileset_id_free(struct icalfileset_id *id) { if(id->recurrence_id != 0){ free(id->recurrence_id); } if(id->uid != 0){ free(id->uid); } - } + struct icalfileset_id icalfileset_get_id(icalcomponent* comp) { - icalcomponent *inner; struct icalfileset_id id; icalproperty *p; inner = icalcomponent_get_first_real_component(comp); p = icalcomponent_get_first_property(inner, ICAL_UID_PROPERTY); assert(p!= 0); id.uid = strdup(icalproperty_get_uid(p)); p = icalcomponent_get_first_property(inner, ICAL_SEQUENCE_PROPERTY); if(p == 0) { id.sequence = 0; } else { id.sequence = icalproperty_get_sequence(p); } p = icalcomponent_get_first_property(inner, ICAL_RECURRENCEID_PROPERTY); if (p == 0){ id.recurrence_id = 0; } else { icalvalue *v; v = icalproperty_get_value(p); id.recurrence_id = strdup(icalvalue_as_ical_string(v)); assert(id.recurrence_id != 0); } return id; } + /* Find the component that is related to the given component. Currently, it just matches based on UID and RECURRENCE-ID */ -icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *comp) +icalcomponent* icalfileset_fetch_match(icalset* set, icalcomponent *comp) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)set; + icalfileset *fset = (icalfileset*) set; icalcompiter i; struct icalfileset_id comp_id, match_id; comp_id = icalfileset_get_id(comp); - for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); + for(i = icalcomponent_begin_component(fset->cluster,ICAL_ANY_COMPONENT); icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ icalcomponent *match = icalcompiter_deref(&i); match_id = icalfileset_get_id(match); if(strcmp(comp_id.uid, match_id.uid) == 0 && ( comp_id.recurrence_id ==0 || strcmp(comp_id.recurrence_id, match_id.recurrence_id) ==0 )){ /* HACK. What to do with SEQUENCE? */ icalfileset_id_free(&match_id); icalfileset_id_free(&comp_id); return match; } icalfileset_id_free(&match_id); } icalfileset_id_free(&comp_id); return 0; } -icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *old, +icalerrorenum icalfileset_modify(icalset* set, icalcomponent *old, icalcomponent *new) { + icalfileset *fset = (icalfileset*) set; + assert(0); /* HACK, not implemented */ return ICAL_NO_ERROR; } /* Iterate through components */ -icalcomponent* icalfileset_get_current_component (icalfileset* cluster) +icalcomponent* icalfileset_get_current_component (icalset* set) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_rz((cluster!=0),"cluster"); + icalerror_check_arg_rz((set!=0),"set"); - return icalcomponent_get_current_component(impl->cluster); + return icalcomponent_get_current_component(fset->cluster); } -icalcomponent* icalfileset_get_first_component(icalfileset* cluster) +icalcomponent* icalfileset_get_first_component(icalset* set) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; icalcomponent *c=0; + icalfileset *fset = (icalfileset*) set; - icalerror_check_arg_rz((cluster!=0),"cluster"); + icalerror_check_arg_rz((set!=0),"set"); do { if (c == 0){ - c = icalcomponent_get_first_component(impl->cluster, + c = icalcomponent_get_first_component(fset->cluster, ICAL_ANY_COMPONENT); } else { - c = icalcomponent_get_next_component(impl->cluster, + c = icalcomponent_get_next_component(fset->cluster, ICAL_ANY_COMPONENT); } - if(c != 0 && (impl->gauge == 0 || - icalgauge_compare(impl->gauge,c) == 1)){ + if(c != 0 && (fset->gauge == 0 || + icalgauge_compare(fset->gauge, c) == 1)){ return c; } } while(c != 0); return 0; } -icalcomponent* icalfileset_get_next_component(icalfileset* cluster) +icalcomponent* icalfileset_get_next_component(icalset* set) { - struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; + icalfileset *fset = (icalfileset*) set; icalcomponent *c; - icalerror_check_arg_rz((cluster!=0),"cluster"); + icalerror_check_arg_rz((set!=0),"set"); do { - c = icalcomponent_get_next_component(impl->cluster, + c = icalcomponent_get_next_component(fset->cluster, ICAL_ANY_COMPONENT); - if(c != 0 && (impl->gauge == 0 || - icalgauge_compare(impl->gauge,c) == 1)){ + if(c != 0 && (fset->gauge == 0 || + icalgauge_compare(fset->gauge,c) == 1)){ return c; } } while(c != 0); return 0; } +/* +icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge) +{ + icalsetiter itr = icalsetiter_null; + icalcomponent* comp = NULL; + icalcompiter citr; + icalfileset *fset = (icalfileset*) set; + + icalerror_check_arg_re((set!=0), "set", icalsetiter_null); + + itr.gauge = gauge; + + citr = icalcomponent_begin_component(fset->cluster, kind); + comp = icalcompiter_deref(&citr); + + while (comp != 0) { + comp = icalcompiter_deref(&citr); + if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) { + itr.iter = citr; + return itr; + } + comp = icalcompiter_next(&citr); + } + + return icalsetiter_null; +} +*/ + +icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge) +{ + icalsetiter itr = icalsetiter_null; + icalcomponent* comp = NULL; + icalcompiter citr; + icalfileset *fset = (icalfileset*) set; + struct icaltimetype start, next; + icalproperty *dtstart, *rrule, *prop, *due; + struct icalrecurrencetype recur; + int g = 0; + + icalerror_check_arg_re((set!=0), "set", icalsetiter_null); + + itr.gauge = gauge; + + citr = icalcomponent_begin_component(fset->cluster, kind); + comp = icalcompiter_deref(&citr); + + if (gauge == 0) { + itr.iter = citr; + return itr; + } + + while (comp != 0) { + + /* check if it is a recurring component and with guage expand, if so + we need to add recurrence-id property to the given component */ + rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); + g = icalgauge_get_expand(gauge); + + if (rrule != 0 + && g == 1) { + + recur = icalproperty_get_rrule(rrule); + if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { + dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); + if (dtstart) + start = icalproperty_get_dtstart(dtstart); + } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { + due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); + if (due) + start = icalproperty_get_due(due); + } + + if (itr.last_component == NULL) { + itr.ritr = icalrecur_iterator_new(recur, start); + next = icalrecur_iterator_next(itr.ritr); + itr.last_component = comp; + } + else { + next = icalrecur_iterator_next(itr.ritr); + if (icaltime_is_null_time(next)){ + itr.last_component = NULL; + icalrecur_iterator_free(itr.ritr); + itr.ritr = NULL; + return icalsetiter_null; + } else { + itr.last_component = comp; + } + } + + /* add recurrence-id to the component + if there is a recurrence-id already, remove it, then add the new one */ + if (prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY)) + icalcomponent_remove_property(comp, prop); + icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); + + } + + if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) { + /* matches and returns */ + itr.iter = citr; + return itr; + } + + /* if there is no previous component pending, then get the next component */ + if (itr.last_component == NULL) + comp = icalcompiter_next(&citr); + } + + return icalsetiter_null; +} +icalcomponent* icalfileset_form_a_matched_recurrence_component(icalsetiter* itr) +{ + icalcomponent* comp = NULL; + struct icaltimetype start, next; + icalproperty *dtstart, *rrule, *prop, *due; + struct icalrecurrencetype recur; + + comp = itr->last_component; + + if (comp == NULL || itr->gauge == NULL) { + return NULL; + } + + rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); + + recur = icalproperty_get_rrule(rrule); + + if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { + dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); + if (dtstart) + start = icalproperty_get_dtstart(dtstart); + } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { + due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); + if (due) + start = icalproperty_get_due(due); + } + + if (itr->ritr == NULL) { + itr->ritr = icalrecur_iterator_new(recur, start); + next = icalrecur_iterator_next(itr->ritr); + itr->last_component = comp; + } else { + next = icalrecur_iterator_next(itr->ritr); + if (icaltime_is_null_time(next)){ + /* no more recurrence, returns */ + itr->last_component = NULL; + icalrecur_iterator_free(itr->ritr); + itr->ritr = NULL; + return NULL; + } else { + itr->last_component = comp; + } + } + + /* add recurrence-id to the component + * if there is a recurrence-id already, remove it, then add the new one */ + if (prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY)) + icalcomponent_remove_property(comp, prop); + icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); + + if (itr->gauge == 0 || icalgauge_compare(itr->gauge, comp) == 1) { + /* matches and returns */ + return comp; + } + /* not matched */ + return NULL; + +} +icalcomponent* icalfilesetiter_to_next(icalset* set, icalsetiter* i) +{ + + icalcomponent* c = NULL; + icalfileset *fset = (icalfileset*) set; + struct icaltimetype start, next; + icalproperty *dtstart, *rrule, *prop, *due; + struct icalrecurrencetype recur; + int g = 0; + + + do { + c = icalcompiter_next(&(i->iter)); + + if (c == 0) continue; + if (i->gauge == 0) return c; + + + rrule = icalcomponent_get_first_property(c, ICAL_RRULE_PROPERTY); + g = icalgauge_get_expand(i->gauge); + + /* a recurring component with expand query */ + if (rrule != 0 + && g == 1) { + + recur = icalproperty_get_rrule(rrule); + + if (icalcomponent_isa(c) == ICAL_VEVENT_COMPONENT) { + dtstart = icalcomponent_get_first_property(c, ICAL_DTSTART_PROPERTY); + if (dtstart) + start = icalproperty_get_dtstart(dtstart); + } else if (icalcomponent_isa(c) == ICAL_VTODO_COMPONENT) { + due = icalcomponent_get_first_property(c, ICAL_DUE_PROPERTY); + if (due) + start = icalproperty_get_due(due); + } + + if (i->ritr == NULL) { + i->ritr = icalrecur_iterator_new(recur, start); + next = icalrecur_iterator_next(i->ritr); + i->last_component = c; + } else { + next = icalrecur_iterator_next(i->ritr); + if (icaltime_is_null_time(next)) { + /* no more recurrence, returns */ + i->last_component = NULL; + icalrecur_iterator_free(i->ritr); + i->ritr = NULL; + return NULL; + } else { + i->last_component = c; + } + } + } + + /* add recurrence-id to the component + * if there is a recurrence-id already, remove it, then add the new one */ + if (prop = icalcomponent_get_first_property(c, ICAL_RECURRENCEID_PROPERTY)) + icalcomponent_remove_property(c, prop); + icalcomponent_add_property(c, icalproperty_new_recurrenceid(next)); + + if(c != 0 && (i->gauge == 0 || + icalgauge_compare(i->gauge, c) == 1)){ + return c; + } + } while (c != 0); + + return 0; +} diff --git a/libical/src/libicalss/icalfileset.h b/libical/src/libicalss/icalfileset.h index 51254d2..dc044ea 100644 --- a/libical/src/libicalss/icalfileset.h +++ b/libical/src/libicalss/icalfileset.h @@ -1,107 +1,134 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalfileset.h CREATOR: eric 23 December 1999 $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 ======================================================================*/ #ifndef ICALFILESET_H #define ICALFILESET_H -#include "icalerror.h" #include "ical.h" #include "icalset.h" +#include "icalcluster.h" #include "icalgauge.h" +#include <sys/types.h> /* For open() flags and mode */ +#include <sys/stat.h> /* For open() flags and mode */ +#include <fcntl.h> /* For open() flags and mode */ -extern int icalfileset_safe_saves; - -typedef void icalfileset; +#ifdef WIN32 +#define mode_t int +#endif +extern int icalfileset_safe_saves; -/* icalfileset - icalfilesetfile - icalfilesetdir -*/ +typedef struct icalfileset_impl icalfileset; +icalset* icalfileset_new(const char* path); +icalset* icalfileset_new_reader(const char* path); +icalset* icalfileset_new_writer(const char* path); -icalfileset* icalfileset_new(const char* path); +icalset* icalfileset_init(icalset *set, const char *dsn, void* options); -#ifdef _WIN32 -#define mode_t int -#endif +icalfileset* icalfileset_new_from_cluster(const char* path, icalcluster *cluster); -/* Like _new, but takes open() flags for opening the file */ -icalfileset* icalfileset_new_open(const char* path, - int flags, mode_t mode); +icalcluster* icalfileset_produce_icalcluster(const char *path); -void icalfileset_free(icalfileset* cluster); +void icalfileset_free(icalset* cluster); -const char* icalfileset_path(icalfileset* cluster); +const char* icalfileset_path(icalset* cluster); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately. */ -void icalfileset_mark(icalfileset* cluster); -icalerrorenum icalfileset_commit(icalfileset* cluster); +void icalfileset_mark(icalset* set); +icalerrorenum icalfileset_commit(icalset* set); -icalerrorenum icalfileset_add_component(icalfileset* cluster, +icalerrorenum icalfileset_add_component(icalset* set, icalcomponent* child); -icalerrorenum icalfileset_remove_component(icalfileset* cluster, +icalerrorenum icalfileset_remove_component(icalset* set, icalcomponent* child); -int icalfileset_count_components(icalfileset* cluster, +int icalfileset_count_components(icalset* set, icalcomponent_kind kind); -/* Restrict the component returned by icalfileset_first, _next to those - that pass the gauge. _clear removes the gauge */ -icalerrorenum icalfileset_select(icalfileset* store, icalgauge* gauge); -void icalfileset_clear(icalfileset* store); +/** + * Restrict the component returned by icalfileset_first, _next to those + * that pass the gauge. _clear removes the gauge + */ +icalerrorenum icalfileset_select(icalset* set, icalgauge* gauge); + +/** clear the gauge **/ +void icalfileset_clear(icalset* set); -/* Get and search for a component by uid */ -icalcomponent* icalfileset_fetch(icalfileset* cluster, const char* uid); -int icalfileset_has_uid(icalfileset* cluster, const char* uid); -icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *c); +/** Get and search for a component by uid **/ +icalcomponent* icalfileset_fetch(icalset* set, const char* uid); +int icalfileset_has_uid(icalset* set, const char* uid); +icalcomponent* icalfileset_fetch_match(icalset* set, icalcomponent *c); -/* Modify components according to the MODIFY method of CAP. Works on - the currently selected components. */ -icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *oldcomp, +/** + * Modify components according to the MODIFY method of CAP. Works on the + * currently selected components. + */ +icalerrorenum icalfileset_modify(icalset* set, + icalcomponent *oldcomp, icalcomponent *newcomp); -/* Iterate through components. If a guage has been defined, these +/* Iterate through components. If a gauge has been defined, these will skip over components that do not pass the gauge */ -icalcomponent* icalfileset_get_current_component (icalfileset* cluster); -icalcomponent* icalfileset_get_first_component(icalfileset* cluster); -icalcomponent* icalfileset_get_next_component(icalfileset* cluster); -/* Return a reference to the internal component. You probably should +icalcomponent* icalfileset_get_current_component (icalset* cluster); +icalcomponent* icalfileset_get_first_component(icalset* cluster); +icalcomponent* icalfileset_get_next_component(icalset* cluster); + +/* External iterator for thread safety */ +icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge); +icalcomponent * icalfilesetiter_to_next(icalset* set, icalsetiter *iter); +icalcomponent* icalfileset_form_a_matched_recurrence_component(icalsetiter* itr); + +/** Return a reference to the internal component. You probably should not be using this. */ -icalcomponent* icalfileset_get_component(icalfileset* cluster); +icalcomponent* icalfileset_get_component(icalset* cluster); + +/** + * @brief options for opening an icalfileset. + * + * These options should be passed to the icalset_new() function + */ + +typedef struct icalfileset_options { + int flags; /**< flags for open() O_RDONLY, etc */ + mode_t mode; /**< file mode */ + int safe_saves; /**< to lock or not */ + icalcluster *cluster; /**< use this cluster to initialize data */ +} icalfileset_options; +extern icalfileset_options icalfileset_options_default; #endif /* !ICALFILESET_H */ diff --git a/libical/src/libicalss/icalfilesetimpl.h b/libical/src/libicalss/icalfilesetimpl.h index fcd3415..fe39604 100644 --- a/libical/src/libicalss/icalfilesetimpl.h +++ b/libical/src/libicalss/icalfilesetimpl.h @@ -1,49 +1,53 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalfilesetimpl.h CREATOR: eric 23 December 1999 $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 ======================================================================*/ +#ifndef ICALFILESETIMPL_H +#define ICALFILESETIMPL_H #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "icalgauge.h" /* This definition is in its own file so it can be kept out of the main header file, but used by "friend classes" like icaldirset*/ #define ICALFILESET_ID "fset" struct icalfileset_impl { - - char id[5]; /*fset*/ - char *path; - icalcomponent* cluster; - icalgauge* gauge; - int changed; - int fd; /* file descriptor */ + icalset super; /**< parent class */ + char *path; /**< pathname of file */ + icalfileset_options options; /**< copy of options passed to icalset_new() */ + + icalcomponent* cluster; /**< cluster containing data */ + icalgauge* gauge; /**< gauge for filtering out data */ + int changed; /**< boolean flag, 1 if data has changed */ + int fd; /**< file descriptor */ }; +#endif diff --git a/libical/src/libicalss/icalgauge.c b/libical/src/libicalss/icalgauge.c index b958ecf..f4854c7 100644 --- a/libical/src/libicalss/icalgauge.c +++ b/libical/src/libicalss/icalgauge.c @@ -1,447 +1,529 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalgauge.c CREATOR: eric 23 December 1999 $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 ======================================================================*/ #include "ical.h" #include "icalgauge.h" #include "icalgaugeimpl.h" #include <stdlib.h> -extern char* input_buffer; -extern char* input_buffer_p; -int ssparse(void); +#include "icalssyacc.h" -struct icalgauge_impl *icalss_yy_gauge; +typedef void* yyscan_t; -icalgauge* icalgauge_new_from_sql(char* sql) +int ssparse(yyscan_t ); + + +icalgauge* icalgauge_new_from_sql(char* sql, int expand) { struct icalgauge_impl *impl; + yyscan_t yy_globals = NULL; int r; if ( ( impl = (struct icalgauge_impl*) malloc(sizeof(struct icalgauge_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } impl->select = pvl_newlist(); impl->from = pvl_newlist(); impl->where = pvl_newlist(); + impl->expand = expand; + + sslex_init(&yy_globals); + + ssset_extra(impl, yy_globals); - icalss_yy_gauge = impl; + ss_scan_string(sql, yy_globals); - input_buffer_p = input_buffer = sql; - r = ssparse(); + r = ssparse(yy_globals); + sslex_destroy(yy_globals); - return impl; + if (r == 0) { + return impl; + } + else { + icalgauge_free(impl); + return NULL; + } } +int icalgauge_get_expand(icalgauge* gauge) +{ +return (gauge->expand); + +} void icalgauge_free(icalgauge* gauge) { - struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge; struct icalgauge_where *w; - assert(impl->select != 0); - assert(impl->where != 0); - assert(impl->from != 0); + assert(gauge->select != 0); + assert(gauge->where != 0); + assert(gauge->from != 0); - if(impl->select){ - while( (w=pvl_pop(impl->select)) != 0){ + if(gauge->select){ + while( (w=pvl_pop(gauge->select)) != 0){ if(w->value != 0){ free(w->value); } free(w); } - pvl_free(impl->select); + pvl_free(gauge->select); + gauge->select = 0; } - if(impl->where){ - while( (w=pvl_pop(impl->where)) != 0){ + if(gauge->where){ + while( (w=pvl_pop(gauge->where)) != 0){ if(w->value != 0){ free(w->value); } free(w); } - pvl_free(impl->where); + pvl_free(gauge->where); + gauge->where = 0; } - if(impl->from){ - pvl_free(impl->from); + if(gauge->from){ + pvl_free(gauge->from); + gauge->from = 0; } + + free(gauge); } -/* Convert a VQUERY component into a gauge */ + +/** Convert a VQUERY component into a gauge */ icalcomponent* icalgauge_make_gauge(icalcomponent* query); -/* icaldirset_test compares a component against a gauge, and returns +/** + icaldirset_test compares a component against a gauge, and returns true if the component passes the test The gauge is a VCALENDAR component that specifies how to test the - target components. The guage holds a collection of VEVENT, VTODO or + target components. The gauge holds a collection of VEVENT, VTODO or VJOURNAL sub-components. Each of the sub-components has a collection of properties that are compared to corresponding properties in the target component, according to the X-LIC-COMPARETYPE parameters to the gauge's properties. When a gauge has several sub-components, the results of testing the target against each of them is ORed together - the target component will pass if it matches any of the sub-components in the gauge. However, the results of matching the properties in a sub-component are ANDed -- the target must match every property in a gauge sub-component to match the sub-component. Here is an example: BEGIN:XROOT DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000 ORGANIZER;X-LIC-COMPARETYPE=EQUAL:mrbig@host.com END:XROOT BEGIN:XROOT LOCATION;X-LIC-COMPARETYPE=EQUAL:McNary's Pub END:XROOT This gauge has two sub-components; one which will match a VEVENT based on start time, and organizer, and another that matches based on LOCATION. A target component will pass the test if it matched either of the sub-components. */ int icalgauge_compare_recurse(icalcomponent* comp, icalcomponent* gauge) { int pass = 1,localpass = 0; icalproperty *p; icalcomponent *child,*subgauge; icalcomponent_kind gaugekind, compkind; icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); gaugekind = icalcomponent_isa(gauge); compkind = icalcomponent_isa(comp); if( ! (gaugekind == compkind || gaugekind == ICAL_ANY_COMPONENT) ){ return 0; } /* Test properties. For each property in the gauge, search through the component for a similar property. If one is found, compare the two properties value with the comparison specified in the gauge with the X-LIC-COMPARETYPE parameter */ for(p = icalcomponent_get_first_property(gauge,ICAL_ANY_PROPERTY); p != 0; p = icalcomponent_get_next_property(gauge,ICAL_ANY_PROPERTY)){ icalproperty* targetprop; icalparameter* compareparam; icalparameter_xliccomparetype compare; int rel; /* The relationship between the gauge and target values.*/ /* Extract the comparison type from the gauge. If there is no comparison type, assume that it is "EQUAL" */ compareparam = icalproperty_get_first_parameter( p, ICAL_XLICCOMPARETYPE_PARAMETER); if (compareparam!=0){ compare = icalparameter_get_xliccomparetype(compareparam); } else { compare = ICAL_XLICCOMPARETYPE_EQUAL; } /* Find a property in the component that has the same type as the gauge property. HACK -- multiples of a single property type in the gauge will match only the first instance in the component */ targetprop = icalcomponent_get_first_property(comp, icalproperty_isa(p)); if(targetprop != 0){ /* Compare the values of the gauge property and the target property */ rel = icalvalue_compare(icalproperty_get_value(p), icalproperty_get_value(targetprop)); /* Now see if the comparison is equavalent to the comparison specified in the gauge */ if (rel == compare){ localpass++; } else if (compare == ICAL_XLICCOMPARETYPE_LESSEQUAL && ( rel == ICAL_XLICCOMPARETYPE_LESS || rel == ICAL_XLICCOMPARETYPE_EQUAL)) { localpass++; } else if (compare == ICAL_XLICCOMPARETYPE_GREATEREQUAL && ( rel == ICAL_XLICCOMPARETYPE_GREATER || rel == ICAL_XLICCOMPARETYPE_EQUAL)) { localpass++; } else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL && ( rel == ICAL_XLICCOMPARETYPE_GREATER || rel == ICAL_XLICCOMPARETYPE_LESS)) { localpass++; } else { localpass = 0; } pass = pass && (localpass>0); } } /* Test subcomponents. Look for a child component that has a counterpart in the gauge. If one is found, recursively call icaldirset_test */ for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT); subgauge != 0; subgauge = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){ gaugekind = icalcomponent_isa(subgauge); if (gaugekind == ICAL_ANY_COMPONENT){ child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); } else { child = icalcomponent_get_first_component(comp,gaugekind); } if(child !=0){ localpass = icalgauge_compare_recurse(child,subgauge); pass = pass && localpass; } else { pass = 0; } } return pass; } int icalgauge_compare(icalgauge* gauge,icalcomponent* comp) { - struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge; icalcomponent *inner; int local_pass = 0; int last_clause = 1, this_clause = 1; pvl_elem e; + icalcomponent_kind kind; + icalproperty *rrule; + int compare_recur = 0; + icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); + if (gauge == 0 || comp == 0) return 0; + inner = icalcomponent_get_first_real_component(comp); if(inner == 0){ - icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); - return 0; + /* Wally Yau: our component is not always wrapped with + * a <VCALENDAR>. It's not an error. + * icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + * return 0; */ + kind = icalcomponent_isa(comp); + if(kind == ICAL_VEVENT_COMPONENT || + kind == ICAL_VTODO_COMPONENT || + kind == ICAL_VJOURNAL_COMPONENT || + kind == ICAL_VQUERY_COMPONENT || + kind == ICAL_VAGENDA_COMPONENT){ + inner = comp; + } + else { + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); + return 0; + } + inner = comp; } - /* Check that this component is one of the FROM types */ local_pass = 0; - for(e = pvl_head(impl->from);e!=0;e=pvl_next(e)){ + for(e = pvl_head(gauge->from);e!=0;e=pvl_next(e)){ icalcomponent_kind k = (icalcomponent_kind)pvl_data(e); if(k == icalcomponent_isa(inner)){ local_pass=1; } } if(local_pass == 0){ return 0; } - /* Check each where clause against the component */ - for(e = pvl_head(impl->where);e!=0;e=pvl_next(e)){ + /**** Check each where clause against the component ****/ + for(e = pvl_head(gauge->where);e!=0;e=pvl_next(e)){ struct icalgauge_where *w = pvl_data(e); icalcomponent *sub_comp; icalvalue *v; icalproperty *prop; icalvalue_kind vk; if(w->prop == ICAL_NO_PROPERTY || w->value == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } /* First, create a value from the gauge */ vk = icalenum_property_kind_to_value_kind(w->prop); if(vk == ICAL_NO_VALUE){ - icalerror_set_errno(ICAL_INTERNAL_ERROR); + icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } - v = icalvalue_new_from_string(vk,w->value); + if (w->compare == ICALGAUGECOMPARE_ISNULL || w->compare == ICALGAUGECOMPARE_ISNOTNULL) + v = icalvalue_new(vk); + else + v = icalvalue_new_from_string(vk,w->value); if (v == 0){ /* Keep error set by icalvalue_from-string*/ return 0; } /* Now find the corresponding property in the component, descending into a sub-component if necessary */ if(w->comp == ICAL_NO_COMPONENT){ sub_comp = inner; } else { sub_comp = icalcomponent_get_first_component(inner,w->comp); if(sub_comp == 0){ return 0; } } + /* check if it is a recurring */ + rrule = icalcomponent_get_first_property(sub_comp,ICAL_RRULE_PROPERTY); + + if (gauge->expand + && rrule) { + + if (w->prop == ICAL_DTSTART_PROPERTY || + w->prop == ICAL_DTEND_PROPERTY || + w->prop == ICAL_DUE_PROPERTY){ + /** needs to use recurrence-id to do comparison */ + compare_recur = 1; + } + + } + + this_clause = 0; - local_pass = 0; + local_pass = (w->compare == ICALGAUGECOMPARE_ISNULL) ? 1 : 0; + for(prop = icalcomponent_get_first_property(sub_comp,w->prop); prop != 0; prop = icalcomponent_get_next_property(sub_comp,w->prop)){ icalvalue* prop_value; icalgaugecompare relation; + if (w->compare == ICALGAUGECOMPARE_ISNULL) { + local_pass = 0; + break; + } + + if (w->compare == ICALGAUGECOMPARE_ISNOTNULL) { + local_pass = 1; + break; + } + + if (compare_recur) { + icalproperty *p = icalcomponent_get_first_property(sub_comp, ICAL_RECURRENCEID_PROPERTY); + prop_value = icalproperty_get_value(p); + } + else /* prop value from this component */ prop_value = icalproperty_get_value(prop); relation = (icalgaugecompare)icalvalue_compare(prop_value,v); if (relation == w->compare){ local_pass++; } else if (w->compare == ICALGAUGECOMPARE_LESSEQUAL && ( relation == ICALGAUGECOMPARE_LESS || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_GREATEREQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_NOTEQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_LESS)) { local_pass++; } else { local_pass = 0; } } + this_clause = local_pass > 0 ? 1 : 0; + /* Now look at the logic operator for this clause to see how the value should be merge with the previous clause */ if(w->logic == ICALGAUGELOGIC_AND){ last_clause = this_clause && last_clause; - } else if(w->logic == ICALGAUGELOGIC_AND) { + } else if(w->logic == ICALGAUGELOGIC_OR) { last_clause = this_clause || last_clause; } else { last_clause = this_clause; } - } + + icalvalue_free(v); + + }/**** check next one in where clause ****/ return last_clause; } +/** @brief Debug + * Print gauge information to stdout. + */ -void icalgauge_dump(icalcomponent* gauge) +void icalgauge_dump(icalgauge* gauge) { - pvl_elem *p; - struct icalgauge_impl *impl = (struct icalgauge_impl*)gauge; - + pvl_elem p; printf("--- Select ---\n"); - for(p = pvl_head(impl->select);p!=0;p=pvl_next(p)){ + for(p = pvl_head(gauge->select);p!=0;p=pvl_next(p)){ struct icalgauge_where *w = pvl_data(p); if(w->comp != ICAL_NO_COMPONENT){ printf("%s ",icalenum_component_kind_to_string(w->comp)); } if(w->prop != ICAL_NO_PROPERTY){ printf("%s ",icalenum_property_kind_to_string(w->prop)); } if (w->compare != ICALGAUGECOMPARE_NONE){ printf("%d ",w->compare); } if (w->value!=0){ printf("%s",w->value); } printf("\n"); } printf("--- From ---\n"); - for(p = pvl_head(impl->from);p!=0;p=pvl_next(p)){ + for(p = pvl_head(gauge->from);p!=0;p=pvl_next(p)){ icalcomponent_kind k = (icalcomponent_kind)pvl_data(p); printf("%s\n",icalenum_component_kind_to_string(k)); } printf("--- Where ---\n"); - for(p = pvl_head(impl->where);p!=0;p=pvl_next(p)){ + for(p = pvl_head(gauge->where);p!=0;p=pvl_next(p)){ struct icalgauge_where *w = pvl_data(p); if(w->logic != ICALGAUGELOGIC_NONE){ printf("%d ",w->logic); } if(w->comp != ICAL_NO_COMPONENT){ printf("%s ",icalenum_component_kind_to_string(w->comp)); } if(w->prop != ICAL_NO_PROPERTY){ printf("%s ",icalenum_property_kind_to_string(w->prop)); } if (w->compare != ICALGAUGECOMPARE_NONE){ printf("%d ",w->compare); } if (w->value!=0){ printf("%s",w->value); } printf("\n"); } - - } diff --git a/libical/src/libicalss/icalgauge.h b/libical/src/libicalss/icalgauge.h index 1caf0ac..c35b4f7 100644 --- a/libical/src/libicalss/icalgauge.h +++ b/libical/src/libicalss/icalgauge.h @@ -1,51 +1,61 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalgauge.h CREATOR: eric 23 December 1999 $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 ======================================================================*/ #ifndef ICALGAUGE_H #define ICALGAUGE_H -typedef void icalgauge; +/** @file icalgauge.h + * @brief Routines implementing a filter for ical components + */ -icalgauge* icalgauge_new_from_sql(char* sql); +typedef struct icalgauge_impl icalgauge; + +icalgauge* icalgauge_new_from_sql(char* sql, int expand); + +int icalgauge_get_expand(icalgauge* gauge); void icalgauge_free(icalgauge* gauge); char* icalgauge_as_sql(icalcomponent* gauge); -void icalgauge_dump(icalcomponent* gauge); +void icalgauge_dump(icalgauge* gauge); + -/* Return true is comp matches the gauge. The component must be in - cannonical form -- a VCALENDAR with one VEVENT, VTODO or VJOURNAL - sub component */ +/** @brief Return true if comp matches the gauge. + * + * The component must be in + * cannonical form -- a VCALENDAR with one VEVENT, VTODO or VJOURNAL + * sub component + */ int icalgauge_compare(icalgauge* g, icalcomponent* comp); -/* Clone the component, but only return the properties specified in - the gauge */ +/** Clone the component, but only return the properties + * specified in the gauge */ icalcomponent* icalgauge_new_clone(icalgauge* g, icalcomponent* comp); #endif /* ICALGAUGE_H*/ diff --git a/libical/src/libicalss/icalgaugeimpl.h b/libical/src/libicalss/icalgaugeimpl.h index 73a2813..e56b1c0 100644 --- a/libical/src/libicalss/icalgaugeimpl.h +++ b/libical/src/libicalss/icalgaugeimpl.h @@ -1,63 +1,63 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalgaugeimpl.h CREATOR: eric 09 Aug 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/ ======================================================================*/ #include "ical.h" -#include "pvl.h" - typedef enum icalgaugecompare { ICALGAUGECOMPARE_EQUAL=ICAL_XLICCOMPARETYPE_EQUAL, ICALGAUGECOMPARE_LESS=ICAL_XLICCOMPARETYPE_LESS, ICALGAUGECOMPARE_LESSEQUAL=ICAL_XLICCOMPARETYPE_LESSEQUAL, ICALGAUGECOMPARE_GREATER=ICAL_XLICCOMPARETYPE_GREATER, ICALGAUGECOMPARE_GREATEREQUAL=ICAL_XLICCOMPARETYPE_GREATEREQUAL, ICALGAUGECOMPARE_NOTEQUAL=ICAL_XLICCOMPARETYPE_NOTEQUAL, ICALGAUGECOMPARE_REGEX=ICAL_XLICCOMPARETYPE_REGEX, + ICALGAUGECOMPARE_ISNULL=ICAL_XLICCOMPARETYPE_ISNULL, + ICALGAUGECOMPARE_ISNOTNULL=ICAL_XLICCOMPARETYPE_ISNOTNULL, ICALGAUGECOMPARE_NONE=0 } icalgaugecompare; typedef enum icalgaugelogic { ICALGAUGELOGIC_NONE, ICALGAUGELOGIC_AND, ICALGAUGELOGIC_OR } icalgaugelogic; struct icalgauge_where { icalgaugelogic logic; icalcomponent_kind comp; icalproperty_kind prop; icalgaugecompare compare; char* value; }; struct icalgauge_impl { - - pvl_list select; /*Of icalgaugecompare, using only prop and comp fields*/ - pvl_list from; /* List of component_kinds, as integers */ - pvl_list where; /* List of icalgaugecompare */ + pvl_list select; /**< Of icalgaugecompare, using only prop and comp fields*/ + pvl_list from; /**< List of component_kinds, as integers */ + pvl_list where; /**< List of icalgaugecompare */ + int expand; }; diff --git a/libical/src/libicalss/icalmessage.c b/libical/src/libicalss/icalmessage.c index d5c57c1..731a2c7 100644 --- a/libical/src/libicalss/icalmessage.c +++ b/libical/src/libicalss/icalmessage.c @@ -1,373 +1,378 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalmessage.c CREATOR: ebusboom 07 Nov 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/ ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "icalmessage.h" #include "icalenums.h" #include <ctype.h> /* for tolower()*/ #include <string.h> /* for strstr */ #include <stdlib.h> /* for free(), malloc() */ icalcomponent* icalmessage_get_inner(icalcomponent* comp) { if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){ return icalcomponent_get_first_real_component(comp); } else { return comp; } } -char* lowercase(const char* str) +static char* lowercase(const char* str) { char* p = 0; char* n = icalmemory_strdup(str); if(str ==0){ return 0; } for(p = n; *p!=0; p++){ *p = tolower(*p); } return n; } icalproperty* icalmessage_find_attendee(icalcomponent* comp, const char* user) { icalcomponent *inner = icalmessage_get_inner(comp); icalproperty *p,*attendee = 0; char* luser = lowercase(user); for(p = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY); p != 0; p = icalcomponent_get_next_property(inner, ICAL_ATTENDEE_PROPERTY) ){ char* lattendee; lattendee = lowercase(icalproperty_get_attendee(p)); if (strstr(lattendee,user) != 0){ attendee = p; break; } free(lattendee); } free(luser); return attendee; } void icalmessage_copy_properties(icalcomponent* to, icalcomponent* from, icalproperty_kind kind) { icalcomponent *to_inner = icalmessage_get_inner(to); icalcomponent *from_inner = icalmessage_get_inner(from); if (to_inner == 0 && from_inner == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return; } if(!icalcomponent_get_first_property(from_inner,kind)){ return; } icalcomponent_add_property(to_inner, icalproperty_new_clone( icalcomponent_get_first_property( from_inner, kind) ) ); } icalcomponent *icalmessage_new_reply_base(icalcomponent* c, const char* user, const char* msg) { icalproperty *attendee; char tmp[45]; icalcomponent *reply = icalcomponent_vanew( ICAL_VCALENDAR_COMPONENT, icalproperty_new_method(ICAL_METHOD_REPLY), icalcomponent_vanew( ICAL_VEVENT_COMPONENT, icalproperty_new_dtstamp(icaltime_from_timet(time(0),0)), 0), 0); icalcomponent *inner = icalmessage_get_inner(reply); icalerror_check_arg_rz(c,"c"); icalmessage_copy_properties(reply,c,ICAL_UID_PROPERTY); icalmessage_copy_properties(reply,c,ICAL_ORGANIZER_PROPERTY); icalmessage_copy_properties(reply,c,ICAL_RECURRENCEID_PROPERTY); icalmessage_copy_properties(reply,c,ICAL_SUMMARY_PROPERTY); icalmessage_copy_properties(reply,c,ICAL_SEQUENCE_PROPERTY); icalcomponent_set_dtstamp(reply,icaltime_from_timet(time(0),0)); if(msg != 0){ icalcomponent_add_property(inner,icalproperty_new_comment(msg)); } /* Copy this user's attendee property */ attendee = icalmessage_find_attendee(c,user); if (attendee == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalcomponent_free(reply); return 0; } icalcomponent_add_property(inner,icalproperty_new_clone(attendee)); /* Add PRODID and VERSION */ icalcomponent_add_property(reply,icalproperty_new_version("2.0")); +#ifndef WIN32 sprintf(tmp, "-//SoftwareStudio//NONSGML %s %s //EN",PACKAGE,VERSION); +#else + sprintf(tmp, + "-//SoftwareStudio//NONSGML %s %s //EN",ICAL_PACKAGE,ICAL_VERSION); +#endif icalcomponent_add_property(reply,icalproperty_new_prodid(tmp)); return reply; } icalcomponent* icalmessage_new_accept_reply(icalcomponent* c, const char* user, const char* msg) { icalcomponent *reply; icalproperty *attendee; icalcomponent *inner; icalerror_check_arg_rz(c,"c"); reply = icalmessage_new_reply_base(c,user,msg); if(reply == 0){ return 0; } inner = icalmessage_get_inner(reply); attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY); icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_ACCEPTED)); return reply; } icalcomponent* icalmessage_new_decline_reply(icalcomponent* c, const char* user, const char* msg) { icalcomponent *reply; icalproperty *attendee; icalcomponent *inner; icalerror_check_arg_rz(c,"c"); reply = icalmessage_new_reply_base(c,user,msg); inner = icalmessage_get_inner(reply); if(reply == 0){ return 0; } attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY); icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DECLINED)); return reply; } /* New is modified version of old */ icalcomponent* icalmessage_new_counterpropose_reply(icalcomponent* oldc, icalcomponent* newc, const char* user, const char* msg) { icalcomponent *reply; icalerror_check_arg_rz(oldc,"oldc"); icalerror_check_arg_rz(newc,"newc"); - reply = icalcomponent_new_clone(newc); + reply = icalmessage_new_reply_base(newc,user,msg); icalcomponent_set_method(reply,ICAL_METHOD_COUNTER); - return newc; + return reply; } icalcomponent* icalmessage_new_delegate_reply(icalcomponent* c, const char* user, const char* delegatee, const char* msg) { icalcomponent *reply; icalproperty *attendee; icalcomponent *inner; icalerror_check_arg_rz(c,"c"); reply = icalmessage_new_reply_base(c,user,msg); inner = icalmessage_get_inner(reply); if(reply == 0){ return 0; } attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY); icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DELEGATED)); icalproperty_set_parameter(attendee, icalparameter_new_delegatedto(delegatee)); return reply; } icalcomponent* icalmessage_new_delegate_request(icalcomponent* c, const char* user, const char* delegatee, const char* msg) { icalcomponent *reply; icalproperty *attendee; icalcomponent *inner; icalerror_check_arg_rz(c,"c"); reply = icalmessage_new_reply_base(c,user,msg); inner = icalmessage_get_inner(reply); if(reply == 0){ return 0; } icalcomponent_set_method(reply,ICAL_METHOD_REQUEST); attendee = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY); icalproperty_set_parameter(attendee, icalparameter_new_partstat(ICAL_PARTSTAT_DELEGATED)); icalproperty_set_parameter(attendee, icalparameter_new_delegatedto(delegatee)); icalcomponent_add_property( inner, icalproperty_vanew_attendee( delegatee, icalparameter_new_delegatedfrom( icalproperty_get_attendee(attendee) ), 0 ) ); return reply; } icalcomponent* icalmessage_new_cancel_event(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_cancel_instance(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_cancel_all(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_error_reply(icalcomponent* c, const char* user, const char* msg, const char* debug, icalrequeststatus code) { icalcomponent *reply; icalcomponent *inner, *cinner; struct icalreqstattype rs; icalerror_check_arg_rz(c,"c"); reply = icalmessage_new_reply_base(c,user,msg); inner = icalmessage_get_inner(reply); cinner = icalmessage_get_inner(c); if(reply == 0){ return 0; } if( code != ICAL_UNKNOWN_STATUS){ rs.code = code; rs.debug = debug; icalcomponent_add_property(inner, icalproperty_new_requeststatus(rs)); } else { /* code == ICAL_UNKNOWN_STATUS */ /* Copy all of the request status properties */ icalproperty *p; for(p = icalcomponent_get_first_property(cinner, ICAL_REQUESTSTATUS_PROPERTY); p != 0; p = icalcomponent_get_next_property(cinner, ICAL_REQUESTSTATUS_PROPERTY)){ icalcomponent_add_property(inner,icalproperty_new_clone(p)); } } return reply; } diff --git a/libical/src/libicalss/icalset.c b/libical/src/libicalss/icalset.c index 2120609..0ad2269 100644 --- a/libical/src/libicalss/icalset.c +++ b/libical/src/libicalss/icalset.c @@ -1,367 +1,493 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalset.c CREATOR: eric 17 Jul 2000 Icalset is the "base class" for representations of a collection of iCal components. Derived classes (actually delegates) include: icalfileset Store components in a single file icaldirset Store components in multiple files in a directory icalheapset Store components on the heap icalmysqlset Store components in a mysql database. $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 ======================================================================*/ #include "ical.h" #include "icalset.h" #include "icalfileset.h" #include "icalfilesetimpl.h" #include "icaldirset.h" #include "icaldirsetimpl.h" #include <stdlib.h> -/*#include "icalheapset.h"*/ -/*#include "icalmysqlset.h"*/ - -#define ICALSET_ID "set " - -struct icalset_fp { - void (*free)(icalset* set); - const char* (*path)(icalset* set); - void (*mark)(icalset* set); - icalerrorenum (*commit)(icalset* set); - icalerrorenum (*add_component)(icalset* set, icalcomponent* comp); - icalerrorenum (*remove_component)(icalset* set, icalcomponent* comp); - int (*count_components)(icalset* set, - icalcomponent_kind kind); - icalerrorenum (*select)(icalset* set, icalcomponent* gauge); - void (*clear)(icalset* set); - icalcomponent* (*fetch)(icalset* set, const char* uid); - icalcomponent* (*fetch_match)(icalset* set, icalcomponent *comp); - int (*has_uid)(icalset* set, const char* uid); - icalerrorenum (*modify)(icalset* set, icalcomponent *old, - icalcomponent *new); - icalcomponent* (*get_current_component)(icalset* set); - icalcomponent* (*get_first_component)(icalset* set); - icalcomponent* (*get_next_component)(icalset* set); -}; - -struct icalset_fp icalset_dirset_fp = { +#include <string.h> +#include <errno.h> + +#ifdef WITH_BDB4 +#include "icalbdbset.h" +#include "icalbdbsetimpl.h" +#endif + +/* #define _DLOPEN_TEST */ +#ifdef _DLOPEN_TEST +#include <sys/types.h> +#include <dlfcn.h> +#include <dirent.h> +#endif + +static icalset icalset_dirset_init = { + ICAL_DIR_SET, + sizeof(icaldirset), + NULL, + icaldirset_init, icaldirset_free, icaldirset_path, icaldirset_mark, icaldirset_commit, icaldirset_add_component, icaldirset_remove_component, icaldirset_count_components, icaldirset_select, icaldirset_clear, icaldirset_fetch, icaldirset_fetch_match, icaldirset_has_uid, icaldirset_modify, icaldirset_get_current_component, icaldirset_get_first_component, - icaldirset_get_next_component + icaldirset_get_next_component, + icaldirset_begin_component, + icaldirsetiter_to_next, + icaldirsetiter_to_prior }; -struct icalset_fp icalset_fileset_fp = { +static icalset icalset_fileset_init = { + ICAL_FILE_SET, + sizeof(icalfileset), + NULL, + icalfileset_init, icalfileset_free, icalfileset_path, icalfileset_mark, icalfileset_commit, icalfileset_add_component, icalfileset_remove_component, icalfileset_count_components, icalfileset_select, icalfileset_clear, icalfileset_fetch, icalfileset_fetch_match, icalfileset_has_uid, icalfileset_modify, icalfileset_get_current_component, icalfileset_get_first_component, - icalfileset_get_next_component + icalfileset_get_next_component, + icalfileset_begin_component, + icalfilesetiter_to_next, + NULL }; -struct icalset_impl { +#ifdef WITH_BDB4 +static icalset icalset_bdbset_init = { + ICAL_BDB_SET, + sizeof(icalbdbset), + NULL, + icalbdbset_init, + icalbdbset_free, + icalbdbset_path, + icalbdbset_mark, + icalbdbset_commit, + icalbdbset_add_component, + icalbdbset_remove_component, + icalbdbset_count_components, + icalbdbset_select, + icalbdbset_clear, + icalbdbset_fetch, + icalbdbset_fetch_match, + icalbdbset_has_uid, + icalbdbset_modify, + icalbdbset_get_current_component, + icalbdbset_get_first_component, + icalbdbset_get_next_component, + icalbdbset_begin_component, + icalbdbsetiter_to_next, + NULL +}; +#endif - char id[5]; /* "set " */ +#ifdef _DLOPEN_TEST +static int icalset_init_done = 0; +static pvl_list icalset_kinds = 0; - void *derived_impl; - struct icalset_fp *fp; -}; +typedef icalset *(*fptr)(void); -/* Figure out what was actually passed in as the set. This could be a - set or and of the derived types such as dirset or fileset. Note - this routine returns a value, not a reference, to avoid memory - leaks in the methods */ -struct icalset_impl icalset_get_impl(icalset* set) -{ - struct icalset_impl impl; - - memset(&impl,0,sizeof(impl)); - icalerror_check_arg_re( (set!=0),"set",impl); - - if(strcmp((char*)set,ICALSET_ID)==0) { - /* It is actually a set, so just sent the reference back out. */ - return *(struct icalset_impl*)set; - } else if(strcmp((char*)set,ICALFILESET_ID)==0) { - /* Make a new set from the fileset */ - impl.fp = &icalset_fileset_fp; - impl.derived_impl = set; - strcpy(impl.id,ICALFILESET_ID);/* HACK. Is this necessary? */ - return impl; - } else if(strcmp((char*)set,ICALDIRSET_ID)==0) { - /* Make a new set from the dirset */ - impl.fp = &icalset_dirset_fp; - impl.derived_impl = set; - strcpy(impl.id,ICALDIRSET_ID);/* HACK. Is this necessary? */ - return impl; - } else { - /* The type of set is unknown, so throw an error */ - icalerror_assert((0),"Unknown set type"); - return impl; - } +/** + * Try to load the file and register any icalset found within. + */ +static int load(const char *file) { + + void *modh; + fptr inith; + icalset *icalset_init_ptr; + + if ((modh = dlopen(file, RTLD_NOW)) == 0) { + perror("dlopen"); + return 0; + } + + if ((inith = (fptr)dlsym(modh, "InitModule")) == 0) { + perror("dlsym"); + return 0; + } + + while ((icalset_init_ptr = ((inith)())) != 0) { + pvl_push(icalset_kinds, &icalset_init_ptr); + } + + return 1; } +/** + * Look in the given directory for files called mod_*.o and try to + * load them. + */ +int icalset_loaddir(const char *path) { + DIR *d; + struct dirent *dp; + char buf[PATH_MAX], + *bufptr; + int tot = 0; -struct icalset_impl* icalset_new_impl() -{ - - struct icalset_impl* impl; + strcpy(buf, path); + bufptr = buf + strlen(buf); - if ( ( impl = (struct icalset_impl*) - malloc(sizeof(struct icalset_impl))) == 0) { - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } + if (*(bufptr-1) != '/') + *bufptr++ = '/'; - strcpy(impl->id,ICALSET_ID); + if ((d = opendir(path)) == 0) { + perror("opendir"); + return 0; + } - impl->derived_impl = 0; - impl->fp = 0; + while ((dp = readdir(d)) != 0) { + if (strncmp(dp->d_name, "mod_", 4)) continue; - return impl; -} + strcpy(bufptr, dp->d_name); -struct icalset_impl* icalset_new_file_from_ref(icalfileset *fset) -{ - struct icalset_impl *impl = icalset_new_impl(); + load(buf); + tot++; + } + (void)closedir(d); - icalerror_check_arg_rz( (fset!=0),"fset"); + return 1; +} - if(impl == 0){ - free(impl); - return 0; - } +int icalset_register_class(icalset *set); - impl->derived_impl = fset; +static void icalset_init(void) { + assert(icalset_kinds == 0); + icalset_kinds = pvl_newlist(); - if (impl->derived_impl == 0){ - free(impl); - return 0; - } + pvl_push(icalset_kinds, &icalset_fileset_init); + pvl_push(icalset_kinds, &icalset_dirset_init); +#ifdef WITH_BDB4 + pvl_push(icalset_kinds, &icalset_bdb4set_init); +#endif - impl->fp = &icalset_fileset_fp; +#ifdef EXT_PATH + icalset_loaddir(EXT_PATH); +#endif - return (struct icalset_impl*)impl; + icalset_init_done++; } -icalset* icalset_new_file(const char* path) -{ - icalfileset *fset = icalfileset_new(path); +int icalset_register_class(icalset *set) { - if(fset == 0){ - return 0; - } + if (!icalset_init_done) + icalset_init(); - return (icalset*)icalset_new_file_from_ref(fset); + pvl_push(icalset_kinds, set); + return 1; } -icalset* icalset_new_dir_from_ref(icaldirset *dset) -{ +#endif - struct icalset_impl *impl = icalset_new_impl(); +icalset* icalset_new(icalset_kind kind, const char* dsn, void* options) { + icalset *data = NULL; + icalset *ret = NULL; - icalerror_check_arg_rz( (dset!=0),"dset"); +#ifdef _DLOPEN_TEST + pvl_elem e; + icalset *impl; - if(impl == 0){ - return 0; + if (!icalset_init_done) + icalset_init(); + + for(e = pvl_head(icalset_kinds); e!=0; e = pvl_next(e)) { + impl = (icalset*)pvl_data(e); + if (impl->kind == kind) + break; + } + if (e == 0) { + icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); + return(NULL); } - impl->derived_impl = dset; + data = (icalset*)malloc(impl->size); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } - if (impl->derived_impl == 0){ - free(impl); + /* The first member of the derived class must be an icalset. */ + memset(data,0,impl->size); + /* *data = *impl; */ + memcpy(data, impl, sizeof(icalset)); + + data->dsn = strdup(dsn); +#else + switch(kind) { + case ICAL_FILE_SET: + data = (icalset*) malloc(sizeof(icalfileset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + memset(data,0,sizeof(icalfileset)); + *data = icalset_fileset_init; + break; + case ICAL_DIR_SET: + data = (icalset*) malloc(sizeof(icaldirset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; + return 0; + } + memset(data,0,sizeof(icaldirset)); + *data = icalset_dirset_init; + break; +#ifdef WITH_BDB4 + case ICAL_BDB_SET: + data = (icalset*) malloc(sizeof(icalbdbset)); + if (data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + errno = ENOMEM; return 0; } + memset(data,0,sizeof(icalbdbset)); + *data = icalset_bdbset_init; + break; +#endif + + default: + icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); + /** unimplemented **/ + return(NULL); + } + + if ( data == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + data->kind = kind; + data->dsn = strdup(dsn); +#endif - impl->fp = &icalset_dirset_fp; + /** call the implementation specific initializer **/ + if ((ret = data->init(data, dsn, options)) == NULL) + icalset_free(data); - return impl; + return ret; } -icalset* icalset_new_dir(const char* path) +icalset* icalset_new_file(const char* path) { - icaldirset *dset = icaldirset_new(path); - - if(dset == 0){ - return 0; - } + return icalset_new(ICAL_FILE_SET, path, NULL); +} - return icalset_new_dir_from_ref(dset); +icalset* icalset_new_file_writer(const char* path) +{ + return icalfileset_new_writer(path); } -icalset* icalset_new_heap(void) +icalset* icalset_new_file_reader(const char* path) { - struct icalset_impl *impl = icalset_new_impl(); + return icalfileset_new_reader(path); +} - if(impl == 0){ - free(impl); - return 0; - } +icalset* icalset_new_dir(const char* path) +{ + return icalset_new(ICAL_DIR_SET, path, NULL); +} - return 0; +icalset* icalset_new_dir_writer(const char* path) +{ + return icaldirset_new_writer(path); } -icalset* icalset_new_mysql(const char* path) +icalset* icalset_new_dir_reader(const char* path) { - struct icalset_impl *impl = icalset_new_impl(); + return icaldirset_new_reader(path); +} - if(impl == 0){ - free(impl); - return 0; - } - return 0; -} + +/* Functions for built-in methods */ + +/** + * free memory associated with this icalset + * automatically calls the implementation specific free routine + */ void icalset_free(icalset* set) { - struct icalset_impl impl = icalset_get_impl(set); - (*(impl.fp->free))(impl.derived_impl); + if (set->free) + set->free(set); - if(strcmp((char*)set,ICALSET_ID)) { - free(set); - } -} + if (set->dsn) + free(set->dsn); -const char* icalset_path(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->path))(impl.derived_impl); + free(set); } -void icalset_mark(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - (*(impl.fp->mark))(impl.derived_impl); + +const char* icalset_path(icalset* set) { + return set->path(set); } -icalerrorenum icalset_commit(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->commit))(impl.derived_impl); +void icalset_mark(icalset* set) { + set->mark(set); } -icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->add_component))(impl.derived_impl,comp); +icalerrorenum icalset_commit(icalset* set) { + return set->commit(set); } -icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->remove_component))(impl.derived_impl,comp); +icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) { + return set->add_component(set,comp); } -int icalset_count_components(icalset* set,icalcomponent_kind kind) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->count_components))(impl.derived_impl,kind); +icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) { + return set->remove_component(set,comp); } -icalerrorenum icalset_select(icalset* set, icalcomponent* gauge) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->select))(impl.derived_impl,gauge); +int icalset_count_components(icalset* set,icalcomponent_kind kind) { + return set->count_components(set,kind); } -void icalset_clear(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - (*(impl.fp->clear))(impl.derived_impl); +icalerrorenum icalset_select(icalset* set, icalgauge* gauge) { + return set->select(set, gauge); } -icalcomponent* icalset_fetch(icalset* set, const char* uid) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->fetch))(impl.derived_impl,uid); +void icalset_clear(icalset* set) { + set->clear(set); } -icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->fetch_match))(impl.derived_impl,comp); +icalcomponent* icalset_fetch(icalset* set, const char* uid) { + return set->fetch(set, uid); } +icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) { + return set->fetch_match(set, comp); +} -int icalset_has_uid(icalset* set, const char* uid) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->has_uid))(impl.derived_impl,uid); +int icalset_has_uid(icalset* set, const char* uid) { + return set->has_uid(set, uid); } icalerrorenum icalset_modify(icalset* set, icalcomponent *old, - icalcomponent *new) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->modify))(impl.derived_impl,old,new); + icalcomponent *new) { + return set->modify(set, old, new); } -icalcomponent* icalset_get_current_component(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->get_current_component))(impl.derived_impl); +icalcomponent* icalset_get_current_component(icalset* set) { + return set->get_current_component(set); } -icalcomponent* icalset_get_first_component(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->get_first_component))(impl.derived_impl); +icalcomponent* icalset_get_first_component(icalset* set) { + return set->get_first_component(set); } -icalcomponent* icalset_get_next_component(icalset* set) -{ - struct icalset_impl impl = icalset_get_impl(set); - return (*(impl.fp->get_next_component))(impl.derived_impl); +icalcomponent* icalset_get_next_component(icalset* set) { + return set->get_next_component(set); +} + +icalsetiter icalsetiter_null = {{ICAL_NO_COMPONENT, 0}, 0}; + +icalsetiter icalset_begin_component(icalset* set, + icalcomponent_kind kind, icalgauge* gauge) { + return set->icalset_begin_component(set, kind, gauge); +} + +icalcomponent* icalsetiter_next(icalsetiter* itr) { + + icalcomponent* c = 0; + icalerror_check_arg_rz( (itr != NULL), "i"); + + do { + c = icalcompiter_next(&(itr->iter)); + if(c != 0 && (itr->gauge == 0 || + icalgauge_compare(itr->gauge, c) == 1)){ + return c; + } + } while (c != 0); + + return 0; } +icalcomponent* icalsetiter_prior(icalsetiter* i) { + + icalcomponent* c = 0; + icalerror_check_arg_rz( (i != NULL), "i" ); + + do { + c = icalcompiter_prior(&(i->iter)); + if(c != 0 && (i->gauge == 0 || + icalgauge_compare(i->gauge, c) == 1)){ + return c; + } + } while (c != 0); + + return 0; +} +icalcomponent* icalsetiter_deref(icalsetiter* i) { + icalerror_check_arg_rz( (i != NULL), "i" ); + return (icalcompiter_deref(&(i->iter))); +} +/* for subclasses that use multiple clusters that require specialized cluster traversal */ +icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i) +{ + return set->icalsetiter_to_next(set, i); +} +icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i) +{ + return set->icalsetiter_to_prior(set, i); +} diff --git a/libical/src/libicalss/icalset.h b/libical/src/libicalss/icalset.h index 7b083da..4008c62 100644 --- a/libical/src/libicalss/icalset.h +++ b/libical/src/libicalss/icalset.h @@ -1,111 +1,184 @@ /* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalset.h - CREATOR: eric 28 November 1999 - +/** + @file icalset.h + @author eric 28 November 1999 Icalset is the "base class" for representations of a collection of iCal components. Derived classes (actually delegatees) include: - icalfileset Store componetns in a single file + icalfileset Store components in a single file icaldirset Store components in multiple files in a directory + icalbdbset Store components in a Berkeley DB File icalheapset Store components on the heap icalmysqlset Store components in a mysql database. +**/ +/* $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 ======================================================================*/ #ifndef ICALSET_H #define ICALSET_H #include <limits.h> /* For PATH_MAX */ #include "ical.h" -#include "icalerror.h" +#include "icalgauge.h" #ifdef PATH_MAX #define ICAL_PATH_MAX PATH_MAX #else #define ICAL_PATH_MAX 1024 #endif - - -typedef void icalset; +typedef struct icalset_impl icalset; typedef enum icalset_kind { ICAL_FILE_SET, ICAL_DIR_SET, - ICAL_HEAP_SET, - ICAL_MYSQL_SET, - ICAL_CAP_SET + ICAL_BDB_SET } icalset_kind; +typedef struct icalsetiter +{ + icalcompiter iter; /* icalcomponent_kind, pvl_elem iter */ + icalgauge* gauge; + icalrecur_iterator* ritr; /*the last iterator*/ + icalcomponent* last_component; /*the pending recurring component to be processed */ + const char* tzid; /* the calendar's timezone id */ +} icalsetiter; + +struct icalset_impl { + icalset_kind kind; + int size; + char *dsn; + icalset* (*init)(icalset* set, const char *dsn, void *options); + void (*free)(icalset* set); + const char* (*path)(icalset* set); + void (*mark)(icalset* set); + icalerrorenum (*commit)(icalset* set); + icalerrorenum (*add_component)(icalset* set, icalcomponent* comp); + icalerrorenum (*remove_component)(icalset* set, icalcomponent* comp); + int (*count_components)(icalset* set, + icalcomponent_kind kind); + icalerrorenum (*select)(icalset* set, icalgauge* gauge); + void (*clear)(icalset* set); + icalcomponent* (*fetch)(icalset* set, const char* uid); + icalcomponent* (*fetch_match)(icalset* set, icalcomponent *comp); + int (*has_uid)(icalset* set, const char* uid); + icalerrorenum (*modify)(icalset* set, icalcomponent *old, + icalcomponent *newc); + icalcomponent* (*get_current_component)(icalset* set); + icalcomponent* (*get_first_component)(icalset* set); + icalcomponent* (*get_next_component)(icalset* set); + icalsetiter (*icalset_begin_component)(icalset* set, + icalcomponent_kind kind, icalgauge* gauge); + icalcomponent* (*icalsetiter_to_next)(icalset* set, icalsetiter* i); + icalcomponent* (*icalsetiter_to_prior)(icalset* set, icalsetiter* i); +}; + +/** @brief Register a new derived class */ +int icalset_register_class(icalset *set); + + +/** @brief Generic icalset constructor + * + * @param kind The type of icalset to create + * @param dsn Data Source Name - usually a pathname or DB handle + * @param options Any implementation specific options + * + * @return A valid icalset reference or NULL if error. + * + * This creates any of the icalset types available. + */ + +icalset* icalset_new(icalset_kind kind, const char* dsn, void* options); -/* Create a specific derived type of set */ icalset* icalset_new_file(const char* path); +icalset* icalset_new_file_reader(const char* path); +icalset* icalset_new_file_writer(const char* path); + icalset* icalset_new_dir(const char* path); -icalset* icalset_new_heap(void); -icalset* icalset_new_mysql(const char* path); -/*icalset* icalset_new_cap(icalcstp* cstp);*/ +icalset* icalset_new_file_reader(const char* path); +icalset* icalset_new_file_writer(const char* path); void icalset_free(icalset* set); const char* icalset_path(icalset* set); -/* Mark the cluster as changed, so it will be written to disk when it - is freed. Commit writes to disk immediately*/ +/** Mark the cluster as changed, so it will be written to disk when it + is freed. **/ void icalset_mark(icalset* set); + +/** Write changes to disk immediately */ icalerrorenum icalset_commit(icalset* set); icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp); icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp); int icalset_count_components(icalset* set, icalcomponent_kind kind); -/* Restrict the component returned by icalset_first, _next to those - that pass the gauge. _clear removes the gauge. */ -icalerrorenum icalset_select(icalset* set, icalcomponent* gauge); +/** Restrict the component returned by icalset_first, _next to those + that pass the gauge. */ +icalerrorenum icalset_select(icalset* set, icalgauge* gauge); + +/** Clears the gauge defined by icalset_select() */ void icalset_clear_select(icalset* set); -/* Get a component by uid */ +/** Get a component by uid */ icalcomponent* icalset_fetch(icalset* set, const char* uid); + int icalset_has_uid(icalset* set, const char* uid); icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *c); -/* Modify components according to the MODIFY method of CAP. Works on +/** Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ icalerrorenum icalset_modify(icalset* set, icalcomponent *oldc, icalcomponent *newc); -/* Iterate through the components. If a guage has been defined, these +/** Iterate through the components. If a guage has been defined, these will skip over components that do not pass the gauge */ icalcomponent* icalset_get_current_component(icalset* set); icalcomponent* icalset_get_first_component(icalset* set); icalcomponent* icalset_get_next_component(icalset* set); +/** External Iterator with gauge - for thread safety */ +extern icalsetiter icalsetiter_null; + +icalsetiter icalset_begin_component(icalset* set, + icalcomponent_kind kind, icalgauge* gauge); + +/** Default _next, _prior, _deref for subclasses that use single cluster */ +icalcomponent* icalsetiter_next(icalsetiter* i); +icalcomponent* icalsetiter_prior(icalsetiter* i); +icalcomponent* icalsetiter_deref(icalsetiter* i); + +/** for subclasses that use multiple clusters that require specialized cluster traversal */ +icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i); +icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i); + #endif /* !ICALSET_H */ diff --git a/libical/src/libicalss/icalspanlist.c b/libical/src/libicalss/icalspanlist.c index cab6a81..f42ff41 100644 --- a/libical/src/libicalss/icalspanlist.c +++ b/libical/src/libicalss/icalspanlist.c @@ -1,309 +1,567 @@ /* -*- Mode: C -*- ====================================================================== FILE: icalspanlist.c CREATOR: ebusboom 23 aug 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/ ======================================================================*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "ical.h" #include "icalspanlist.h" -#include "pvl.h" + #include <stdlib.h> /* for free and malloc */ +#include <string.h> struct icalspanlist_impl { - pvl_list spans; + pvl_list spans; /**< list of icaltime_span data **/ + struct icaltimetype start; /**< start time of span **/ + struct icaltimetype end; /**< end time of span **/ }; -int compare_span(void* a, void* b) +/** @brief Internal comparison function for two spans + * + * @param a a spanlist. + * @param b another spanlist. + * + * @return -1, 0, 1 depending on the comparison of the start times. + * + * Used to insert spans into the tree in sorted order. + */ + +static int compare_span(void* a, void* b) { struct icaltime_span *span_a = (struct icaltime_span *)a ; struct icaltime_span *span_b = (struct icaltime_span *)b ; if(span_a->start == span_b->start){ return 0; } else if(span_a->start < span_b->start){ return -1; } else { /*if(span_a->start > span->b.start)*/ return 1; } } -icalcomponent* icalspanlist_get_inner(icalcomponent* comp) + +/** @brief callback function for collecting spanlists of a + * series of events. + * + * @param comp A valid icalcomponent. + * @param span The span to insert into data. + * @param data The actual spanlist to insert into + * + * This callback is used by icalcomponent_foreach_recurrence() + * to build up a spanlist. + */ + +static void icalspanlist_new_callback(icalcomponent *comp, + struct icaltime_span *span, + void *data) { - if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT){ - return icalcomponent_get_first_real_component(comp); - } else { - return comp; - } + icaltime_span *s; + icalspanlist *sl = (icalspanlist*) data; + + if (span->is_busy == 0) + return; + + if ((s=(icaltime_span *) malloc(sizeof(icaltime_span))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return; + } + + /** copy span data into allocated memory.. **/ + *s = *span; + pvl_insert_ordered(sl->spans, compare_span, (void*)s); } + -void print_span(int c, struct icaltime_span span ); +/** @brief Make a free list from a set of VEVENT components. + * + * @param set A valid icalset containing VEVENTS + * @param start The free list starts at this date/time + * @param end The free list ends at this date/time + * + * @return A spanlist corresponding to the VEVENTS + * + * Given a set of components, a start time and an end time + * return a spanlist that contains the free/busy times. + */ - -/* Make a free list from a set of component */ icalspanlist* icalspanlist_new(icalset *set, struct icaltimetype start, struct icaltimetype end) { struct icaltime_span range; pvl_elem itr; icalcomponent *c,*inner; icalcomponent_kind kind, inner_kind; - struct icalspanlist_impl *sl; + icalspanlist *sl; struct icaltime_span *freetime; if ( ( sl = (struct icalspanlist_impl*) malloc(sizeof(struct icalspanlist_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } sl->spans = pvl_newlist(); + sl->start = start; + sl->end = end; range.start = icaltime_as_timet(start); range.end = icaltime_as_timet(end); - printf("Range start: %s",ctime(&range.start)); - printf("Range end : %s",ctime(&range.end)); - - /* Get a list of spans of busy time from the events in the set and order the spans based on the start time */ for(c = icalset_get_first_component(set); c != 0; c = icalset_get_next_component(set)){ - struct icaltime_span span; - kind = icalcomponent_isa(c); inner = icalcomponent_get_inner(c); if(!inner){ continue; } inner_kind = icalcomponent_isa(inner); if( kind != ICAL_VEVENT_COMPONENT && inner_kind != ICAL_VEVENT_COMPONENT){ continue; } icalerror_clear_errno(); - - span = icalcomponent_get_span(c); - span.is_busy = 1; - - if(icalerrno != ICAL_NO_ERROR){ - continue; - } - - if ((range.start < span.end && icaltime_is_null_time(end)) || - (range.start < span.end && range.end > span.start )){ - - struct icaltime_span *s; - - if ((s=(struct icaltime_span *) - malloc(sizeof(struct icaltime_span))) == 0){ - icalerror_set_errno(ICAL_NEWFAILED_ERROR); - return 0; - } - - memcpy(s,&span,sizeof(span)); - - pvl_insert_ordered(sl->spans,compare_span,(void*)s); - - } - } + + icalcomponent_foreach_recurrence(c, start, end, + icalspanlist_new_callback, + (void*)sl); + + } /* Now Fill in the free time spans. loop through the spans. if the start of the range is not within the span, create a free entry that runs from the start of the range to the start of the span. */ for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { - struct icaltime_span *s = (icalproperty*)pvl_data(itr); + struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr); if ((freetime=(struct icaltime_span *) malloc(sizeof(struct icaltime_span))) == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } if(range.start < s->start){ freetime->start = range.start; freetime->end = s->start; freetime->is_busy = 0; pvl_insert_ordered(sl->spans,compare_span,(void*)freetime); } else { free(freetime); } range.start = s->end; } /* If the end of the range is null, then assume that everything after the last item in the calendar is open and add a span that indicates this */ if( icaltime_is_null_time(end)){ struct icaltime_span* last_span; - last_span = pvl_data(pvl_tail(sl->spans)); + last_span = (struct icaltime_span*)pvl_data(pvl_tail(sl->spans)); if (last_span != 0){ if ((freetime=(struct icaltime_span *) malloc(sizeof(struct icaltime_span))) == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } freetime->is_busy = 0; freetime->start = last_span->end; freetime->end = freetime->start; pvl_insert_ordered(sl->spans,compare_span,(void*)freetime); } } return sl; - } +/** @brief Destructor. + * @param s A valid icalspanlist + * + * Free memory associated with the spanlist + */ + void icalspanlist_free(icalspanlist* s) { struct icaltime_span *span; - struct icalspanlist_impl* impl = (struct icalspanlist_impl*)s; - - while( (span=pvl_pop(impl->spans)) != 0){ + + if (s == NULL) + return; + + while( (span=pvl_pop(s->spans)) != 0){ free(span); } - pvl_free(impl->spans); + pvl_free(s->spans); - impl->spans = 0; + s->spans = 0; + + free(s); } -void icalspanlist_dump(icalspanlist* s){ +/** @brief (Debug) print out spanlist to stdout. + * @param sl A valid icalspanlist. + */ +void icalspanlist_dump(icalspanlist* sl){ int i = 0; - struct icalspanlist_impl* sl = (struct icalspanlist_impl*)s; pvl_elem itr; for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { - struct icaltime_span *s = (icalproperty*)pvl_data(itr); + struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr); printf("#%02d %d start: %s",++i,s->is_busy,ctime(&s->start)); printf(" end : %s",ctime(&s->end)); } } icalcomponent* icalspanlist_make_free_list(icalspanlist* sl); icalcomponent* icalspanlist_make_busy_list(icalspanlist* sl); + +/** @brief Find next free time span in a spanlist. + * + * @param sl The spanlist to search. + * @param t The time to start looking. + * + * Given a spanlist and a time, find the next period of time + * that is free + */ + struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl, struct icaltimetype t) { - struct icalspanlist_impl* impl = (struct icalspanlist_impl*)sl; pvl_elem itr; struct icalperiodtype period; struct icaltime_span *s; time_t rangett= icaltime_as_timet(t); period.start = icaltime_null_time(); period.end = icaltime_null_time(); - /* Is the reference time before the first span? If so, assume - that the reference time is free */ - itr = pvl_head(impl->spans); - s = (icalproperty*)pvl_data(itr); + itr = pvl_head(sl->spans); + s = (struct icaltime_span *)pvl_data(itr); if (s == 0){ /* No elements in span */ return period; } + /* Is the reference time before the first span? If so, assume + that the reference time is free */ if(rangett <s->start ){ /* End of period is start of first span if span is busy, end of the span if it is free */ period.start = t; - if (s->is_busy == 0){ + if (s->is_busy == 1){ period.end = icaltime_from_timet(s->start,0); } else { period.end = icaltime_from_timet(s->end,0); } return period; } /* Otherwise, find the first free span that contains the reference time. */ - - for( itr = pvl_head(impl->spans); + for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { - s = (icalproperty*)pvl_data(itr); + s = (struct icaltime_span *)pvl_data(itr); if(s->is_busy == 0 && s->start >= rangett && ( rangett < s->end || s->end == s->start)){ if (rangett < s->start){ period.start = icaltime_from_timet(s->start,0); } else { period.start = icaltime_from_timet(rangett,0); } period.end = icaltime_from_timet(s->end,0); return period; } } period.start = icaltime_null_time(); period.end = icaltime_null_time(); return period; } struct icalperiodtype icalspanlist_next_busy_time(icalspanlist* sl, struct icaltimetype t); + +/** @brief Returns an hour-by-hour array of free/busy times over a + * given period. + * + * @param sl A valid icalspanlist + * @param delta_t The time slice to divide by, in seconds. Default 3600. + * + * @return A pointer to an array of integers containing the number of + * busy events in each delta_t time period. The final entry + * contains the value -1. + * + * This calculation is somewhat tricky. This is due to the fact that + * the time range contains the start time, but does not contain the + * end time. To perform a proper calculation we subtract one second + * off the end times to get a true containing time. + * + * Also note that if you supplying a spanlist that does not start or + * end on a time boundary divisible by delta_t you may get results + * that are not quite what you expect. + */ + +int* icalspanlist_as_freebusy_matrix(icalspanlist* sl, int delta_t) { + pvl_elem itr; + int spanduration_secs; + int *matrix; + int matrix_slots; + time_t sl_start, sl_end; + + icalerror_check_arg_rz( (sl!=0), "spanlist"); + + if (!delta_t) + delta_t = 3600; + + /** calculate the start and end time as time_t **/ + sl_start = icaltime_as_timet_with_zone(sl->start, icaltimezone_get_utc_timezone()); + sl_end = icaltime_as_timet_with_zone(sl->end, icaltimezone_get_utc_timezone()); + + + /** insure that the time period falls on a time boundary divisable + by delta_t */ + + sl_start /= delta_t; + sl_start *= delta_t; + + sl_end /= delta_t; + sl_end *= delta_t; + + + /** find the duration of this spanlist **/ + spanduration_secs = sl_end - sl_start; + + + /** malloc our matrix, add one extra slot for a final -1 **/ + matrix_slots = spanduration_secs/delta_t + 1; + + matrix = (int*) malloc(sizeof(int) * matrix_slots); + if (matrix == NULL) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return NULL; + } + memset(matrix, 0, sizeof(int) * matrix_slots); + matrix[matrix_slots-1] = -1; + + /* loop through each span and mark the slots in the array */ + + for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { + struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr); + + if (s->is_busy == 1) { + int offset_start = s->start/delta_t - sl_start/delta_t; + int offset_end = (s->end - 1) /delta_t - sl_start/delta_t + 1; + int i; + + if (offset_end >= matrix_slots) + offset_end = matrix_slots - 1; + + i = offset_start; + for (i=offset_start; i < offset_end; i++) { + matrix[i]++; + } + } + } + return matrix; +} + + +/** @brief Return a VFREEBUSY component for the corresponding spanlist + * + * @param sl A valid icalspanlist, from icalspanlist_new() + * @param organizer The organizer specified as MAILTO:user@domain + * @param attendee The attendee specified as MAILTO:user@domain + * + * @return A valid icalcomponent or NULL. + * + * This function returns a VFREEBUSY component for the given spanlist. + * The start time is mapped to DTSTART, the end time to DTEND. + * Each busy span is represented as a separate FREEBUSY entry. + * An attendee parameter is required, and organizer parameter is + * optional. + */ + +icalcomponent *icalspanlist_as_vfreebusy(icalspanlist* sl, + const char* organizer, + const char* attendee) { + icalcomponent *comp; + icalproperty *p; + struct icaltimetype atime = icaltime_from_timet( time(0),0); + pvl_elem itr; + icaltimezone *utc_zone; + icalparameter *param; + + if (!attendee) { + icalerror_set_errno(ICAL_USAGE_ERROR); + return 0; + } + + utc_zone = icaltimezone_get_utc_timezone (); + + comp = icalcomponent_new_vfreebusy(); + + icalcomponent_add_property(comp, icalproperty_new_dtstart(sl->start)); + icalcomponent_add_property(comp, icalproperty_new_dtend(sl->end)); + icalcomponent_add_property(comp, icalproperty_new_dtstamp(atime)); + + if (organizer) { + icalcomponent_add_property(comp, icalproperty_new_organizer(organizer)); + } + icalcomponent_add_property(comp, icalproperty_new_attendee(attendee)); + + /* now add the freebusy sections.. */ + + for( itr = pvl_head(sl->spans); itr != 0; itr = pvl_next(itr)) { + struct icalperiodtype period; + struct icaltime_span *s = (struct icaltime_span*)pvl_data(itr); + + if (s->is_busy == 1) { + + period.start = icaltime_from_timet_with_zone (s->start, 0, utc_zone); + period.end = icaltime_from_timet_with_zone (s->end, 0, utc_zone); + period.duration = icaldurationtype_null_duration(); + + + p = icalproperty_new_freebusy(period); + param = icalparameter_new_fbtype(ICAL_FBTYPE_BUSY); + icalproperty_add_parameter(p, param); + + icalcomponent_add_property(comp, p); + } + + } + + return comp; +} + + +/** @brief Return a spanlist corresponding to the VFREEBUSY portion of + * an icalcomponent. + * + * @param c A valid icalcomponent. + * + * @return A valid icalspanlist or NULL if no VFREEBUSY section. + * + */ + + +icalspanlist *icalspanlist_from_vfreebusy(icalcomponent* comp) +{ + icalcomponent *inner; + icalproperty *prop; + icalspanlist *sl; + + icalerror_check_arg_rz((comp != NULL), "comp"); + + inner = icalcomponent_get_inner(comp); + if (!inner) return NULL; + + if ( ( sl = (icalspanlist*) malloc(sizeof(icalspanlist))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + sl->spans = pvl_newlist(); + + /* cycle through each FREEBUSY property, adding to the spanlist */ + for (prop = icalcomponent_get_first_property(inner, ICAL_FREEBUSY_PROPERTY); + prop != NULL; + prop = icalcomponent_get_next_property(inner, ICAL_FREEBUSY_PROPERTY)) { + icaltime_span *s = (icaltime_span *) malloc(sizeof(icaltime_span)); + icalparameter *param; + struct icalperiodtype period; + icalparameter_fbtype fbtype; + + if (s == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + param = icalproperty_get_first_parameter(prop, ICAL_FBTYPE_PARAMETER); + fbtype = (param) ? icalparameter_get_fbtype(param) : ICAL_FBTYPE_BUSY; + + switch (fbtype) { + case ICAL_FBTYPE_FREE: + case ICAL_FBTYPE_NONE: + case ICAL_FBTYPE_X: + s->is_busy = 1; + default: + s->is_busy = 0; + } + + period = icalproperty_get_freebusy(prop); + s->start = icaltime_as_timet_with_zone(period.start, icaltimezone_get_utc_timezone()); + s->end = icaltime_as_timet_with_zone(period.end, icaltimezone_get_utc_timezone()); +; + pvl_insert_ordered(sl->spans, compare_span, (void*)s); + } + /** @todo calculate start/end limits.. fill in holes? **/ + return sl; +} diff --git a/libical/src/libicalss/icalspanlist.h b/libical/src/libicalss/icalspanlist.h index 83cb1c8..91f0acb 100644 --- a/libical/src/libicalss/icalspanlist.h +++ b/libical/src/libicalss/icalspanlist.h @@ -1,54 +1,77 @@ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalspanlist.h CREATOR: eric 21 Aug 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/ =========================================================================*/ #ifndef ICALSPANLIST_H #define ICALSPANLIST_H #include "ical.h" #include "icalset.h" -typedef void icalspanlist; +/** @file icalspanlist.h + * @brief Code that supports collections of free/busy spans of time + */ + +typedef struct icalspanlist_impl icalspanlist; + + +/** @brief Constructor + * Make a free list from a set of component. Start and end should be in UTC + */ -/* Make a free list from a set of component. Start and end should be in UTC */ icalspanlist* icalspanlist_new(icalset *set, struct icaltimetype start, struct icaltimetype end); +/** @brief Destructor + */ void icalspanlist_free(icalspanlist* spl); +/* Unimplemented functions */ icalcomponent* icalspanlist_make_free_list(icalspanlist* sl); icalcomponent* icalspanlist_make_busy_list(icalspanlist* sl); -/* Get first free or busy time after time t. all times are in UTC */ +/** Get first next free time after time t. all times are in UTC. */ struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl, struct icaltimetype t); +/** Get first next busy time after time t. all times are in UTC. */ struct icalperiodtype icalspanlist_next_busy_time(icalspanlist* sl, struct icaltimetype t); void icalspanlist_dump(icalspanlist* s); +/** @brief Return a valid VFREEBUSY component for this span */ +icalcomponent *icalspanlist_as_vfreebusy(icalspanlist* s_in, + const char* organizer, + const char* attendee); + +/** @brief Return an integer matrix of total events per delta_t timespan */ +int *icalspanlist_as_freebusy_matrix(icalspanlist* span, int delta_t); + +/** @brief Construct an icalspanlist from a VFREEBUSY component */ +icalspanlist *icalspanlist_from_vfreebusy(icalcomponent* c); + #endif diff --git a/libical/src/libicalss/icalss.h b/libical/src/libicalss/icalss.h index cd07919..8930e11 100644 --- a/libical/src/libicalss/icalss.h +++ b/libical/src/libicalss/icalss.h @@ -1,885 +1,770 @@ +#ifdef __cplusplus +extern "C" { +#endif +/* + $Id$ +*/ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalgauge.h CREATOR: eric 23 December 1999 - $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 ======================================================================*/ #ifndef ICALGAUGE_H #define ICALGAUGE_H -typedef void icalgauge; +/** @file icalgauge.h + * @brief Routines implementing a filter for ical components + */ -icalgauge* icalgauge_new_from_sql(char* sql); +typedef struct icalgauge_impl icalgauge; + +icalgauge* icalgauge_new_from_sql(char* sql, int expand); + +int icalgauge_get_expand(icalgauge* gauge); void icalgauge_free(icalgauge* gauge); char* icalgauge_as_sql(icalcomponent* gauge); -void icalgauge_dump(icalcomponent* gauge); +void icalgauge_dump(icalgauge* gauge); + -/* Return true is comp matches the gauge. The component must be in - cannonical form -- a VCALENDAR with one VEVENT, VTODO or VJOURNAL - sub component */ +/** @brief Return true if comp matches the gauge. + * + * The component must be in + * cannonical form -- a VCALENDAR with one VEVENT, VTODO or VJOURNAL + * sub component + */ int icalgauge_compare(icalgauge* g, icalcomponent* comp); -/* Clone the component, but only return the properties specified in - the gauge */ +/** Clone the component, but only return the properties + * specified in the gauge */ icalcomponent* icalgauge_new_clone(icalgauge* g, icalcomponent* comp); #endif /* ICALGAUGE_H*/ /* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalset.h - CREATOR: eric 28 November 1999 - +/** + @file icalset.h + @author eric 28 November 1999 Icalset is the "base class" for representations of a collection of iCal components. Derived classes (actually delegatees) include: - icalfileset Store componetns in a single file + icalfileset Store components in a single file icaldirset Store components in multiple files in a directory + icalbdbset Store components in a Berkeley DB File icalheapset Store components on the heap icalmysqlset Store components in a mysql database. +**/ - $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 ======================================================================*/ #ifndef ICALSET_H #define ICALSET_H #include <limits.h> /* For PATH_MAX */ #ifdef PATH_MAX #define ICAL_PATH_MAX PATH_MAX #else #define ICAL_PATH_MAX 1024 #endif -#ifdef _WIN32 -#define mode_t int -#endif - - - -typedef void icalset; +typedef struct icalset_impl icalset; typedef enum icalset_kind { ICAL_FILE_SET, ICAL_DIR_SET, - ICAL_HEAP_SET, - ICAL_MYSQL_SET, - ICAL_CAP_SET + ICAL_BDB_SET } icalset_kind; +typedef struct icalsetiter +{ + icalcompiter iter; /* icalcomponent_kind, pvl_elem iter */ + icalgauge* gauge; + icalrecur_iterator* ritr; /*the last iterator*/ + icalcomponent* last_component; /*the pending recurring component to be processed */ + const char* tzid; /* the calendar's timezone id */ +} icalsetiter; + +struct icalset_impl { + icalset_kind kind; + int size; + char *dsn; + icalset* (*init)(icalset* set, const char *dsn, void *options); + void (*free)(icalset* set); + const char* (*path)(icalset* set); + void (*mark)(icalset* set); + icalerrorenum (*commit)(icalset* set); + icalerrorenum (*add_component)(icalset* set, icalcomponent* comp); + icalerrorenum (*remove_component)(icalset* set, icalcomponent* comp); + int (*count_components)(icalset* set, + icalcomponent_kind kind); + icalerrorenum (*select)(icalset* set, icalgauge* gauge); + void (*clear)(icalset* set); + icalcomponent* (*fetch)(icalset* set, const char* uid); + icalcomponent* (*fetch_match)(icalset* set, icalcomponent *comp); + int (*has_uid)(icalset* set, const char* uid); + icalerrorenum (*modify)(icalset* set, icalcomponent *old, + icalcomponent *newc); + icalcomponent* (*get_current_component)(icalset* set); + icalcomponent* (*get_first_component)(icalset* set); + icalcomponent* (*get_next_component)(icalset* set); + icalsetiter (*icalset_begin_component)(icalset* set, + icalcomponent_kind kind, icalgauge* gauge); + icalcomponent* (*icalsetiter_to_next)(icalset* set, icalsetiter* i); + icalcomponent* (*icalsetiter_to_prior)(icalset* set, icalsetiter* i); +}; + +/** @brief Register a new derived class */ +int icalset_register_class(icalset *set); + + +/** @brief Generic icalset constructor + * + * @param kind The type of icalset to create + * @param dsn Data Source Name - usually a pathname or DB handle + * @param options Any implementation specific options + * + * @return A valid icalset reference or NULL if error. + * + * This creates any of the icalset types available. + */ + +icalset* icalset_new(icalset_kind kind, const char* dsn, void* options); -/* Create a specific derived type of set */ icalset* icalset_new_file(const char* path); +icalset* icalset_new_file_reader(const char* path); +icalset* icalset_new_file_writer(const char* path); + icalset* icalset_new_dir(const char* path); -icalset* icalset_new_heap(void); -icalset* icalset_new_mysql(const char* path); -/*icalset* icalset_new_cap(icalcstp* cstp);*/ +icalset* icalset_new_file_reader(const char* path); +icalset* icalset_new_file_writer(const char* path); void icalset_free(icalset* set); const char* icalset_path(icalset* set); -/* Mark the cluster as changed, so it will be written to disk when it - is freed. Commit writes to disk immediately*/ +/** Mark the cluster as changed, so it will be written to disk when it + is freed. **/ void icalset_mark(icalset* set); + +/** Write changes to disk immediately */ icalerrorenum icalset_commit(icalset* set); icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp); icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp); int icalset_count_components(icalset* set, icalcomponent_kind kind); -/* Restrict the component returned by icalset_first, _next to those - that pass the gauge. _clear removes the gauge. */ -icalerrorenum icalset_select(icalset* set, icalcomponent* gauge); +/** Restrict the component returned by icalset_first, _next to those + that pass the gauge. */ +icalerrorenum icalset_select(icalset* set, icalgauge* gauge); + +/** Clears the gauge defined by icalset_select() */ void icalset_clear_select(icalset* set); -/* Get a component by uid */ +/** Get a component by uid */ icalcomponent* icalset_fetch(icalset* set, const char* uid); + int icalset_has_uid(icalset* set, const char* uid); icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *c); -/* Modify components according to the MODIFY method of CAP. Works on +/** Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ icalerrorenum icalset_modify(icalset* set, icalcomponent *oldc, icalcomponent *newc); -/* Iterate through the components. If a guage has been defined, these +/** Iterate through the components. If a guage has been defined, these will skip over components that do not pass the gauge */ icalcomponent* icalset_get_current_component(icalset* set); icalcomponent* icalset_get_first_component(icalset* set); icalcomponent* icalset_get_next_component(icalset* set); +/** External Iterator with gauge - for thread safety */ +extern icalsetiter icalsetiter_null; + +icalsetiter icalset_begin_component(icalset* set, + icalcomponent_kind kind, icalgauge* gauge); + +/** Default _next, _prior, _deref for subclasses that use single cluster */ +icalcomponent* icalsetiter_next(icalsetiter* i); +icalcomponent* icalsetiter_prior(icalsetiter* i); +icalcomponent* icalsetiter_deref(icalsetiter* i); + +/** for subclasses that use multiple clusters that require specialized cluster traversal */ +icalcomponent* icalsetiter_to_next(icalset* set, icalsetiter* i); +icalcomponent* icalsetiter_to_prior(icalset* set, icalsetiter* i); + #endif /* !ICALSET_H */ /* -*- Mode: C -*- */ /*====================================================================== + FILE: icalcluster.h + CREATOR: eric 23 December 1999 + + + + (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 + + +======================================================================*/ + +#ifndef ICALCLUSTER_H +#define ICALCLUSTER_H + + +typedef struct icalcluster_impl icalcluster; + +icalcluster* icalcluster_new(const char *key, icalcomponent *data); +icalcluster* icalcluster_new_clone(const icalcluster *cluster); + +void icalcluster_free(icalcluster *cluster); + +const char* icalcluster_key(icalcluster *cluster); +int icalcluster_is_changed(icalcluster *cluster); +void icalcluster_mark(icalcluster *cluster); +void icalcluster_commit(icalcluster *cluster); + +icalcomponent* icalcluster_get_component(icalcluster* cluster); +int icalcluster_count_components(icalcluster *cluster, icalcomponent_kind kind); +icalerrorenum icalcluster_add_component(icalcluster* cluster, + icalcomponent* child); +icalerrorenum icalcluster_remove_component(icalcluster* cluster, + icalcomponent* child); + +icalcomponent* icalcluster_get_current_component(icalcluster* cluster); +icalcomponent* icalcluster_get_first_component(icalcluster* cluster); +icalcomponent* icalcluster_get_next_component(icalcluster* cluster); + +#endif /* !ICALCLUSTER_H */ + + + +/* -*- Mode: C -*- */ +/*====================================================================== FILE: icalfileset.h CREATOR: eric 23 December 1999 - $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 ======================================================================*/ #ifndef ICALFILESET_H #define ICALFILESET_H #include <sys/types.h> /* For open() flags and mode */ #include <sys/stat.h> /* For open() flags and mode */ #include <fcntl.h> /* For open() flags and mode */ -extern int icalfileset_safe_saves; +#ifdef WIN32 +#define mode_t int +#endif -typedef void icalfileset; +extern int icalfileset_safe_saves; +typedef struct icalfileset_impl icalfileset; -/* icalfileset - icalfilesetfile - icalfilesetdir -*/ +icalset* icalfileset_new(const char* path); +icalset* icalfileset_new_reader(const char* path); +icalset* icalfileset_new_writer(const char* path); +icalset* icalfileset_init(icalset *set, const char *dsn, void* options); -icalfileset* icalfileset_new(const char* path); +icalfileset* icalfileset_new_from_cluster(const char* path, icalcluster *cluster); -/* Like _new, but takes open() flags for opening the file */ -icalfileset* icalfileset_new_open(const char* path, - int flags, mode_t mode); +icalcluster* icalfileset_produce_icalcluster(const char *path); -void icalfileset_free(icalfileset* cluster); +void icalfileset_free(icalset* cluster); -const char* icalfileset_path(icalfileset* cluster); +const char* icalfileset_path(icalset* cluster); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately. */ -void icalfileset_mark(icalfileset* cluster); -icalerrorenum icalfileset_commit(icalfileset* cluster); +void icalfileset_mark(icalset* set); +icalerrorenum icalfileset_commit(icalset* set); -icalerrorenum icalfileset_add_component(icalfileset* cluster, +icalerrorenum icalfileset_add_component(icalset* set, icalcomponent* child); -icalerrorenum icalfileset_remove_component(icalfileset* cluster, +icalerrorenum icalfileset_remove_component(icalset* set, icalcomponent* child); -int icalfileset_count_components(icalfileset* cluster, +int icalfileset_count_components(icalset* set, icalcomponent_kind kind); -/* Restrict the component returned by icalfileset_first, _next to those - that pass the gauge. _clear removes the gauge */ -icalerrorenum icalfileset_select(icalfileset* store, icalgauge* gauge); -void icalfileset_clear(icalfileset* store); +/** + * Restrict the component returned by icalfileset_first, _next to those + * that pass the gauge. _clear removes the gauge + */ +icalerrorenum icalfileset_select(icalset* set, icalgauge* gauge); -/* Get and search for a component by uid */ -icalcomponent* icalfileset_fetch(icalfileset* cluster, const char* uid); -int icalfileset_has_uid(icalfileset* cluster, const char* uid); -icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *c); +/** clear the gauge **/ +void icalfileset_clear(icalset* set); +/** Get and search for a component by uid **/ +icalcomponent* icalfileset_fetch(icalset* set, const char* uid); +int icalfileset_has_uid(icalset* set, const char* uid); +icalcomponent* icalfileset_fetch_match(icalset* set, icalcomponent *c); -/* Modify components according to the MODIFY method of CAP. Works on - the currently selected components. */ -icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *oldcomp, + +/** + * Modify components according to the MODIFY method of CAP. Works on the + * currently selected components. + */ +icalerrorenum icalfileset_modify(icalset* set, + icalcomponent *oldcomp, icalcomponent *newcomp); -/* Iterate through components. If a guage has been defined, these +/* Iterate through components. If a gauge has been defined, these will skip over components that do not pass the gauge */ -icalcomponent* icalfileset_get_current_component (icalfileset* cluster); -icalcomponent* icalfileset_get_first_component(icalfileset* cluster); -icalcomponent* icalfileset_get_next_component(icalfileset* cluster); -/* Return a reference to the internal component. You probably should +icalcomponent* icalfileset_get_current_component (icalset* cluster); +icalcomponent* icalfileset_get_first_component(icalset* cluster); +icalcomponent* icalfileset_get_next_component(icalset* cluster); + +/* External iterator for thread safety */ +icalsetiter icalfileset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge); +icalcomponent * icalfilesetiter_to_next(icalset* set, icalsetiter *iter); +icalcomponent* icalfileset_form_a_matched_recurrence_component(icalsetiter* itr); + +/** Return a reference to the internal component. You probably should not be using this. */ -icalcomponent* icalfileset_get_component(icalfileset* cluster); +icalcomponent* icalfileset_get_component(icalset* cluster); + +/** + * @brief options for opening an icalfileset. + * + * These options should be passed to the icalset_new() function + */ +typedef struct icalfileset_options { + int flags; /**< flags for open() O_RDONLY, etc */ + mode_t mode; /**< file mode */ + int safe_saves; /**< to lock or not */ + icalcluster *cluster; /**< use this cluster to initialize data */ +} icalfileset_options; + +extern icalfileset_options icalfileset_options_default; #endif /* !ICALFILESET_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icaldirset.h CREATOR: eric 28 November 1999 - $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 ======================================================================*/ #ifndef ICALDIRSET_H #define ICALDIRSET_H /* icaldirset Routines for storing, fetching, and searching for ical * objects in a database */ -typedef void icaldirset; +typedef struct icaldirset_impl icaldirset; +icalset* icaldirset_new(const char* path); -icaldirset* icaldirset_new(const char* path); +icalset* icaldirset_new_reader(const char* path); +icalset* icaldirset_new_writer(const char* path); -void icaldirset_free(icaldirset* store); -const char* icaldirset_path(icaldirset* store); +icalset* icaldirset_init(icalset* set, const char *dsn, void *options); +void icaldirset_free(icalset* set); + +const char* icaldirset_path(icalset* set); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately*/ -void icaldirset_mark(icaldirset* store); -icalerrorenum icaldirset_commit(icaldirset* store); +void icaldirset_mark(icalset* set); +icalerrorenum icaldirset_commit(icalset* set); -icalerrorenum icaldirset_add_component(icaldirset* store, icalcomponent* comp); -icalerrorenum icaldirset_remove_component(icaldirset* store, icalcomponent* comp); +icalerrorenum icaldirset_add_component(icalset* store, icalcomponent* comp); +icalerrorenum icaldirset_remove_component(icalset* store, icalcomponent* comp); -int icaldirset_count_components(icaldirset* store, +int icaldirset_count_components(icalset* store, icalcomponent_kind kind); /* Restrict the component returned by icaldirset_first, _next to those that pass the gauge. _clear removes the gauge. */ -icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge); -void icaldirset_clear(icaldirset* store); +icalerrorenum icaldirset_select(icalset* store, icalgauge* gauge); +void icaldirset_clear(icalset* store); /* Get a component by uid */ -icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid); -int icaldirset_has_uid(icaldirset* store, const char* uid); -icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c); +icalcomponent* icaldirset_fetch(icalset* store, const char* uid); +int icaldirset_has_uid(icalset* store, const char* uid); +icalcomponent* icaldirset_fetch_match(icalset* set, icalcomponent *c); /* Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ -icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc, +icalerrorenum icaldirset_modify(icalset* store, icalcomponent *oldc, icalcomponent *newc); -/* Iterate through the components. If a guage has been defined, these +/* Iterate through the components. If a gauge has been defined, these will skip over components that do not pass the gauge */ -icalcomponent* icaldirset_get_current_component(icaldirset* store); -icalcomponent* icaldirset_get_first_component(icaldirset* store); -icalcomponent* icaldirset_get_next_component(icaldirset* store); +icalcomponent* icaldirset_get_current_component(icalset* store); +icalcomponent* icaldirset_get_first_component(icalset* store); +icalcomponent* icaldirset_get_next_component(icalset* store); + +/* External iterator for thread safety */ +icalsetiter icaldirset_begin_component(icalset* set, icalcomponent_kind kind, icalgauge* gauge); +icalcomponent* icaldirsetiter_to_next(icalset* set, icalsetiter* i); +icalcomponent* icaldirsetiter_to_prior(icalset* set, icalsetiter* i); + +typedef struct icaldirset_options { + int flags; /**< flags corresponding to the open() system call O_RDWR, etc. */ +} icaldirset_options; #endif /* !ICALDIRSET_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalcalendar.h CREATOR: eric 23 December 1999 - $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 ======================================================================*/ #ifndef ICALCALENDAR_H #define ICALCALENDAR_H /* icalcalendar * Routines for storing calendar data in a file system. The calendar * has two icaldirsets, one for incoming components and one for booked * components. It also has interfaces to access the free/busy list * and a list of calendar properties */ -typedef void icalcalendar; +typedef struct icalcalendar_impl icalcalendar; icalcalendar* icalcalendar_new(char* dir); void icalcalendar_free(icalcalendar* calendar); int icalcalendar_lock(icalcalendar* calendar); int icalcalendar_unlock(icalcalendar* calendar); int icalcalendar_islocked(icalcalendar* calendar); int icalcalendar_ownlock(icalcalendar* calendar); icalset* icalcalendar_get_booked(icalcalendar* calendar); icalset* icalcalendar_get_incoming(icalcalendar* calendar); icalset* icalcalendar_get_properties(icalcalendar* calendar); icalset* icalcalendar_get_freebusy(icalcalendar* calendar); #endif /* !ICALCALENDAR_H */ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalclassify.h CREATOR: eric 21 Aug 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/ =========================================================================*/ #ifndef ICALCLASSIFY_H #define ICALCLASSIFY_H - -typedef enum icalclass { - ICAL_NO_CLASS, - ICAL_PUBLISH_NEW_CLASS, - ICAL_PUBLISH_UPDATE_CLASS, - ICAL_PUBLISH_FREEBUSY_CLASS, - ICAL_REQUEST_NEW_CLASS, - ICAL_REQUEST_UPDATE_CLASS, - ICAL_REQUEST_RESCHEDULE_CLASS, - ICAL_REQUEST_DELEGATE_CLASS, - ICAL_REQUEST_NEW_ORGANIZER_CLASS, - ICAL_REQUEST_FORWARD_CLASS, - ICAL_REQUEST_STATUS_CLASS, - ICAL_REQUEST_FREEBUSY_CLASS, - ICAL_REPLY_ACCEPT_CLASS, - ICAL_REPLY_DECLINE_CLASS, - ICAL_REPLY_DELEGATE_CLASS, - ICAL_REPLY_CRASHER_ACCEPT_CLASS, - ICAL_REPLY_CRASHER_DECLINE_CLASS, - ICAL_ADD_INSTANCE_CLASS, - ICAL_CANCEL_EVENT_CLASS, - ICAL_CANCEL_INSTANCE_CLASS, - ICAL_CANCEL_ALL_CLASS, - ICAL_REFRESH_CLASS, - ICAL_COUNTER_CLASS, - ICAL_DECLINECOUNTER_CLASS, - ICAL_MALFORMED_CLASS, - ICAL_OBSOLETE_CLASS, /* 21 */ - ICAL_MISSEQUENCED_CLASS, /* 22 */ - ICAL_UNKNOWN_CLASS /* 23 */ -} ical_class; - -ical_class icalclassify(icalcomponent* c,icalcomponent* match, +icalproperty_xlicclass icalclassify(icalcomponent* c,icalcomponent* match, const char* user); icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp); -char* icalclassify_class_to_string(ical_class iclass); +char* icalclassify_class_to_string(icalproperty_xlicclass c); #endif /* ICALCLASSIFY_H*/ /* -*- Mode: C -*- */ /*====================================================================== FILE: icalspanlist.h CREATOR: eric 21 Aug 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/ =========================================================================*/ #ifndef ICALSPANLIST_H #define ICALSPANLIST_H -typedef void icalspanlist; +/** @file icalspanlist.h + * @brief Code that supports collections of free/busy spans of time + */ + +typedef struct icalspanlist_impl icalspanlist; + + +/** @brief Constructor + * Make a free list from a set of component. Start and end should be in UTC + */ -/* Make a free list from a set of component. Start and end should be in UTC */ icalspanlist* icalspanlist_new(icalset *set, struct icaltimetype start, struct icaltimetype end); +/** @brief Destructor + */ void icalspanlist_free(icalspanlist* spl); +/* Unimplemented functions */ icalcomponent* icalspanlist_make_free_list(icalspanlist* sl); icalcomponent* icalspanlist_make_busy_list(icalspanlist* sl); -/* Get first free or busy time after time t. all times are in UTC */ +/** Get first next free time after time t. all times are in UTC. */ struct icalperiodtype icalspanlist_next_free_time(icalspanlist* sl, struct icaltimetype t); +/** Get first next busy time after time t. all times are in UTC. */ struct icalperiodtype icalspanlist_next_busy_time(icalspanlist* sl, struct icaltimetype t); void icalspanlist_dump(icalspanlist* s); +/** @brief Return a valid VFREEBUSY component for this span */ +icalcomponent *icalspanlist_as_vfreebusy(icalspanlist* s_in, + const char* organizer, + const char* attendee); + +/** @brief Return an integer matrix of total events per delta_t timespan */ +int *icalspanlist_as_freebusy_matrix(icalspanlist* span, int delta_t); + +/** @brief Construct an icalspanlist from a VFREEBUSY component */ +icalspanlist *icalspanlist_from_vfreebusy(icalcomponent* c); + #endif /* -*- Mode: C -*- */ /*====================================================================== FILE: icalmessage.h CREATOR: eric 07 Nov 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/ =========================================================================*/ #ifndef ICALMESSAGE_H #define ICALMESSAGE_H icalcomponent* icalmessage_new_accept_reply(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_decline_reply(icalcomponent* c, const char* user, const char* msg); /* New is modified version of old */ icalcomponent* icalmessage_new_counterpropose_reply(icalcomponent* oldc, icalcomponent* newc, const char* user, const char* msg); icalcomponent* icalmessage_new_delegate_reply(icalcomponent* c, const char* user, const char* delegatee, const char* msg); icalcomponent* icalmessage_new_cancel_event(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_cancel_instance(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_cancel_all(icalcomponent* c, const char* user, const char* msg); icalcomponent* icalmessage_new_error_reply(icalcomponent* c, const char* user, const char* msg, const char* debug, icalrequeststatus rs); #endif /* ICALMESSAGE_H*/ -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalcstp.h - CREATOR: eric 20 April 1999 - - $Id$ - - - (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 icalcstp.h - -======================================================================*/ - - -#ifndef ICALCSTP_H -#define ICALCSTP_H - - - -/* Connection state, from the state machine in RFC2445 */ -enum cstps_state { - NO_STATE, - CONNECTED, - AUTHENTICATED, - IDENTIFIED, - DISCONNECTED, - RECEIVE -}; - -/* CSTP Commands that a client can issue to a server */ -typedef enum icalcstp_command { - ICAL_ABORT_COMMAND, - ICAL_AUTHENTICATE_COMMAND, - ICAL_CAPABILITY_COMMAND, - ICAL_CONTINUE_COMMAND, - ICAL_CALIDEXPAND_COMMAND, - ICAL_IDENTIFY_COMMAND, - ICAL_DISCONNECT_COMMAND, - ICAL_SENDDATA_COMMAND, - ICAL_STARTTLS_COMMAND, - ICAL_UPNEXPAND_COMMAND, - ICAL_COMPLETE_COMMAND, - ICAL_UNKNOWN_COMMAND -} icalcstp_command; - - - -/* A statement is a combination of command or response code and a - component that the server and client exchage with each other. */ -struct icalcstp_statement { - icalcstp_command command; - char* str_data; /* If non-NUll use as arguments to command */ - int int_data; /* If non-NULL use as arguments to command */ - - icalrequeststatus code; - - icalcomponent* data; +#ifdef __cplusplus }; - -const char* icalcstp_command_to_string(icalcstp_command command); -icalcstp_command icalcstp_string_to_command(const char* str); - -#endif /* !ICALCSTP_H */ - - - -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalcstpclient.h - CREATOR: eric 4 Feb 01 - - $Id$ - - - (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 icalcstp.h - -======================================================================*/ - - -#ifndef ICALCSTPC_H -#define ICALCSTPC_H - - -/********************** Client (Sender) Interfaces **************************/ - -/* How to use: - - 1) Construct a new icalcstpc - 2) Issue a command by calling one of the command routines. - 3) Repeat until both call icalcstpc_next_output and - icalcstpc_next_input return 0: - 3a) Call icalcstpc_next_output. Send string to server. - 3b) Get string from server, & give to icalcstp_next_input() - 4) Iterate with icalcstpc_first_response & icalcstp_next_response to - get the servers responses - 5) Repeat at #2 -*/ - - -typedef void icalcstpc; - -/* Response code sent by the server. */ -typedef struct icalcstpc_response { - icalrequeststatus code; - char *arg; /* These strings are owned by libical */ - char *debug_text; - char *more_text; - void* result; -} icalcstpc_response; - - -icalcstpc* icalcstpc_new(); - -void icalcstpc_free(icalcstpc* cstpc); - -int icalcstpc_set_timeout(icalcstpc* cstp, int sec); - - -/* Get the next string to send to the server */ -char* icalcstpc_next_output(icalcstpc* cstp, char* line); - -/* process the next string from the server */ -int icalcstpc_next_input(icalcstpc* cstp, char * line); - -/* After icalcstpc_next_input returns a 0, there are responses - ready. use these to get them */ -icalcstpc_response icalcstpc_first_response(icalcstpc* cstp); -icalcstpc_response icalcstpc_next_response(icalcstpc* cstp); - -/* Issue a command */ -icalerrorenum icalcstpc_abort(icalcstpc* cstp); -icalerrorenum icalcstpc_authenticate(icalcstpc* cstp, char* mechanism, - char* init_data, char* f(char*) ); -icalerrorenum icalcstpc_capability(icalcstpc* cstp); -icalerrorenum icalcstpc_calidexpand(icalcstpc* cstp,char* calid); -icalerrorenum icalcstpc_continue(icalcstpc* cstp, unsigned int time); -icalerrorenum icalcstpc_disconnect(icalcstpc* cstp); -icalerrorenum icalcstpc_identify(icalcstpc* cstp, char* id); -icalerrorenum icalcstpc_starttls(icalcstpc* cstp, char* command, - char* init_data, char* f(char*)); -icalerrorenum icalcstpc_senddata(icalcstpc* cstp, unsigned int time, - icalcomponent *comp); -icalerrorenum icalcstpc_upnexpand(icalcstpc* cstp,char* calid); -icalerrorenum icalcstpc_sendata(icalcstpc* cstp, unsigned int time, - icalcomponent *comp); - - -#endif /* !ICALCSTPC_H */ - - - -/* -*- Mode: C -*- */ -/*====================================================================== - FILE: icalcstpserver.h - CREATOR: eric 13 Feb 01 - - $Id$ - - - (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 icalcstp.h - -======================================================================*/ - - -#ifndef ICALCSTPS_H -#define ICALCSTPS_H - - - -/********************** Server (Reciever) Interfaces *************************/ - -/* On the server side, the caller will recieve data from the incoming - socket and pass it to icalcstps_next_input. The caller then takes - the return from icalcstps_next_outpu and sends it out through the - socket. This gives the caller a point of control. If the cstp code - connected to the socket itself, it would be hard for the caller to - do anything else after the cstp code was started. - - All of the server and client command routines will generate - response codes. On the server side, these responses will be turned - into text and sent to the client. On the client side, the reponse - is the one sent from the server. - - Since each command can return multiple responses, the responses are - stored in the icalcstps object and are accesses by - icalcstps_first_response() and icalcstps_next_response() - - How to use: - - 1) Construct a new icalcstps, bound to your code via stubs - 2) Repeat forever: - 2a) Get string from client & give to icalcstps_next_input() - 2b) Repeat until icalcstp_next_output returns 0: - 2b1) Call icalcstps_next_output. - 2b2) Send string to client. -*/ - - - -typedef void icalcstps; - -/* Pointers to the rountines that - icalcstps_process_incoming will call when it recognizes a CSTP - command in the data. BTW, the CONTINUE command is named 'cont' - because 'continue' is a C keyword */ - -struct icalcstps_commandfp { - icalerrorenum (*abort)(icalcstps* cstp); - icalerrorenum (*authenticate)(icalcstps* cstp, char* mechanism, - char* data); - icalerrorenum (*calidexpand)(icalcstps* cstp, char* calid); - icalerrorenum (*capability)(icalcstps* cstp); - icalerrorenum (*cont)(icalcstps* cstp, unsigned int time); - icalerrorenum (*identify)(icalcstps* cstp, char* id); - icalerrorenum (*disconnect)(icalcstps* cstp); - icalerrorenum (*sendata)(icalcstps* cstp, unsigned int time, - icalcomponent *comp); - icalerrorenum (*starttls)(icalcstps* cstp, char* command, - char* data); - icalerrorenum (*upnexpand)(icalcstps* cstp, char* upn); - icalerrorenum (*unknown)(icalcstps* cstp, char* command, char* data); -}; - - - -icalcstps* icalcstps_new(struct icalcstps_commandfp stubs); - -void icalcstps_free(icalcstps* cstp); - -int icalcstps_set_timeout(icalcstps* cstp, int sec); - -/* Get the next string to send to the client */ -char* icalcstps_next_output(icalcstps* cstp); - -/* process the next string from the client */ -int icalcstps_next_input(icalcstps* cstp); - -#endif /* ICALCSTPS */ +#endif diff --git a/libical/src/libicalss/icalsslexer.c b/libical/src/libicalss/icalsslexer.c index e10bcd3..28d1b66 100644 --- a/libical/src/libicalss/icalsslexer.c +++ b/libical/src/libicalss/icalsslexer.c @@ -1,1713 +1,2485 @@ +#define YY_REENTRANT 1 +#define YY_TEXT_IS_ARRAY +#define YY_REENTRANT_BISON_PURE 1 +#ifndef YY_REENTRANT +#define yytext sstext +#define yyleng ssleng +#define yyin ssin +#define yyout ssout +#endif #define yy_create_buffer ss_create_buffer #define yy_delete_buffer ss_delete_buffer #define yy_scan_buffer ss_scan_buffer #define yy_scan_string ss_scan_string #define yy_scan_bytes ss_scan_bytes #define yy_flex_debug ss_flex_debug #define yy_init_buffer ss_init_buffer #define yy_flush_buffer ss_flush_buffer #define yy_load_buffer_state ss_load_buffer_state #define yy_switch_to_buffer ss_switch_to_buffer -#define yyin ssin -#define yyleng ssleng #define yylex sslex -#define yyout ssout #define yyrestart ssrestart -#define yytext sstext +#define yylex_init sslex_init +#define yylex_destroy sslex_destroy +#define yyget_extra ssget_extra +#define yyset_extra ssset_extra +#define yyget_in ssget_in +#define yyset_in ssset_in +#define yyget_out ssget_out +#define yyset_out ssset_out +#define yyget_leng ssget_leng +#define yyget_text ssget_text +#define yyget_lineno ssget_lineno +#define yyset_lineno ssset_lineno +#ifdef YY_REENTRANT_BISON_PURE +#define yyget_lval ssget_lval +#define yyset_lval ssset_lval +#ifdef YYLTYPE +#define yyget_lloc ssget_lloc +#define yyset_lloc ssset_lloc +#endif +#endif #define yywrap sswrap +/* -*-C-*- */ /* A lexical scanner generated by flex */ -/* Scanner skeleton version: - * $Header$ - */ - #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 +/* %- */ +/* begin standard C headers. */ #include <stdio.h> -// Eugen C. <eug@thekompany.com> -#include <defines.h> -#ifndef _QTWIN_ -#include <unistd.h> -#else -#include <io.h> -#endif -// Eugen C. <eug@thekompany.com> - - -/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ -#ifdef c_plusplus -#ifndef __cplusplus -#define __cplusplus -#endif -#endif - +#include <errno.h> +#include <stdlib.h> +/* end standard C headers. */ +/* %+ */ +/* %* */ #ifdef __cplusplus -#include <stdlib.h> +/* %+ */ +/* %* */ /* Use prototypes in function declarations. */ #define YY_USE_PROTOS /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ #if __STDC__ #define YY_USE_PROTOS #define YY_USE_CONST #endif /* __STDC__ */ #endif /* ! __cplusplus */ -#ifdef __TURBOC__ - #pragma warn -rch - #pragma warn -use -#include <io.h> -#include <stdlib.h> -#define YY_USE_CONST -#define YY_USE_PROTOS -#endif - #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif #ifdef YY_USE_PROTOS #define YY_PROTO(proto) proto #else #define YY_PROTO(proto) () #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +#ifdef YY_REENTRANT + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For use wherever a Global is accessed or assigned. */ +#define YY_G(var) (((struct yy_globals_t*)yy_globals)->var) + +/* For use in function prototypes to append the additional argument. */ +#ifdef YY_USE_PROTOS +#define YY_LAST_ARG , yyscan_t yy_globals +#define YY_ONLY_ARG yyscan_t yy_globals +#else +#define YY_LAST_ARG , yy_globals +#define YY_ONLY_ARG yy_globals +#define YY_DECL_LAST_ARG yyscan_t yy_globals; +#endif + +/* For use in function calls to pass the additional argument. */ +#define YY_CALL_LAST_ARG , yy_globals +#define YY_CALL_ONLY_ARG yy_globals + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin YY_G(yyin_r) +#define yyout YY_G(yyout_r) +#define yyextra YY_G(yyextra_r) +#define yyleng YY_G(yyleng_r) +#define yytext YY_G(yytext_r) +#define yylineno YY_G(yylineno_r) + +int yylex_init YY_PROTO((yyscan_t* scanner)); +int yylex_destroy YY_PROTO((yyscan_t scanner)); + +#else /* not YY_REENTRANT */ + + /* Define these macros to be no-ops. */ +#define YY_G(var) (var) +#define YY_LAST_ARG +#define YY_ONLY_ARG void +#define YY_CALL_LAST_ARG +#define YY_CALL_ONLY_ARG +#define YY_DECL_LAST_ARG +#endif + /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ -#define BEGIN yy_start = 1 + 2 * +#define BEGIN YY_G(yy_start) = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ -#define YY_START ((yy_start - 1) / 2) +#define YY_START ((YY_G(yy_start) - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart( yyin ) +#define YY_NEW_FILE yyrestart( yyin YY_CALL_LAST_ARG ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #define YY_BUF_SIZE 16384 + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#ifndef YY_REENTRANT +extern size_t yyleng; +#endif -extern int yyleng; +/* %- */ +#ifndef YY_REENTRANT extern FILE *yyin, *yyout; +#endif +/* %* */ #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 /* The funky do-while in the following #define is used to turn the definition * int a single C statement (which needs a semi-colon terminator). This * avoids problems with code like: * * if ( condition_holds ) * yyless( 5 ); * else * do_something_else(); * * Prior to using the do-while the compiler would get upset at the * "else" because it interpreted the "if" statement as being all * done when it reached the ';' after the yyless() call. */ /* Return all but the first 'n' matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ - *yy_cp = yy_hold_char; \ + *yy_cp = YY_G(yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ - yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_G(yy_c_buf_p) = yy_cp = yy_bp + n - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) -#define unput(c) yyunput( c, yytext_ptr ) +#define unput(c) yyunput( c, YY_G(yytext_ptr) YY_CALL_LAST_ARG ) /* The following is because we cannot portably get our hands on size_t * (without autoconf's help, which isn't available because we want * flex-generated scanners to compile on their own). */ -typedef unsigned int yy_size_t; +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef unsigned int yy_size_t; +#endif +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { +/* %- */ FILE *yy_input_file; +/* %+ */ +/* %* */ char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via yyrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ +/* %- Standard (non-C++) definition */ +/* %c */ +#ifndef ssIN_HEADER +#ifndef YY_REENTRANT static YY_BUFFER_STATE yy_current_buffer = 0; +#endif +/* %e */ +#endif /* !ssIN_HEADER */ +/* %* */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". */ #define YY_CURRENT_BUFFER yy_current_buffer +/* %- Standard (non-C++) definition */ + +#ifndef YY_REENTRANT +/* %c */ +#ifndef ssIN_HEADER /* yy_hold_char holds the character lost when yytext is formed. */ static char yy_hold_char; static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; +size_t yyleng; /* Points to current character in buffer. */ static char *yy_c_buf_p = (char *) 0; static int yy_init = 1; /* whether we need to initialize */ static int yy_start = 0; /* start state number */ /* Flag which is used to allow yywrap()'s to do buffer switches * instead of setting up a fresh yyin. A bit of a hack ... */ static int yy_did_buffer_switch_on_eof; +/* %e */ +#endif /* !ssIN_HEADER */ +#endif /* end !YY_REENTRANT */ + +void yyrestart YY_PROTO(( FILE *input_file YY_LAST_ARG )); + + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer YY_LAST_ARG )); +void yy_load_buffer_state YY_PROTO(( YY_ONLY_ARG )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size YY_LAST_ARG )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b YY_LAST_ARG )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file YY_LAST_ARG )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b YY_LAST_ARG )); -void yyrestart YY_PROTO(( FILE *input_file )); +#define YY_FLUSH_BUFFER yy_flush_buffer( YY_G(yy_current_buffer) YY_CALL_LAST_ARG) -void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); -void yy_load_buffer_state YY_PROTO(( void )); -YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); -void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); -void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); -void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); -#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size YY_LAST_ARG )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str YY_LAST_ARG )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len YY_LAST_ARG )); -YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); -YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); -YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); +/* %* */ -static void *yy_flex_alloc YY_PROTO(( yy_size_t )); -static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); -static void yy_flex_free YY_PROTO(( void * )); +/* %c */ +#ifndef ssIN_HEADER +static void *yy_flex_alloc YY_PROTO(( yy_size_t YY_LAST_ARG )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t YY_LAST_ARG )); +static void yy_flex_free YY_PROTO(( void * YY_LAST_ARG )); +/* %e */ +#endif /* !ssIN_HEADER */ #define yy_new_buffer yy_create_buffer #define yy_set_interactive(is_interactive) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_is_interactive = is_interactive; \ + if ( ! YY_G(yy_current_buffer) ) \ + YY_G(yy_current_buffer) = \ + yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); \ + YY_G(yy_current_buffer)->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ - if ( ! yy_current_buffer ) \ - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ - yy_current_buffer->yy_at_bol = at_bol; \ + if ( ! YY_G(yy_current_buffer) ) \ + YY_G(yy_current_buffer) = \ + yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); \ + YY_G(yy_current_buffer)->yy_at_bol = at_bol; \ } -#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) +#define YY_AT_BOL() (YY_G(yy_current_buffer)->yy_at_bol) +/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */ +/* Begin user sect3 */ +#ifndef ssIN_HEADER typedef unsigned char YY_CHAR; +#endif /* !ssIN_HEADER */ +#ifndef ssIN_HEADER +#ifndef YY_REENTRANT FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +#endif +#endif /* !ssIN_HEADER */ +#ifndef ssIN_HEADER typedef int yy_state_type; -extern char yytext[]; - - -static yy_state_type yy_get_previous_state YY_PROTO(( void )); -static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); -static int yy_get_next_buffer YY_PROTO(( void )); +#endif /* !ssIN_HEADER */ + +/* %- Standard (non-C++) definition */ +/* %c */ +#ifndef ssIN_HEADER +static yy_state_type yy_get_previous_state YY_PROTO(( YY_ONLY_ARG )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state YY_LAST_ARG)); +static int yy_get_next_buffer YY_PROTO(( YY_ONLY_ARG )); static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); +/* %e */ +#endif /* !ssIN_HEADER */ +/* %* */ /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ - yytext_ptr = yy_bp; \ - yyleng = (int) (yy_cp - yy_bp); \ - yy_hold_char = *yy_cp; \ + YY_G(yytext_ptr) = yy_bp; \ +/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \ */\ + yyleng = (size_t) (yy_cp - yy_bp); \ + YY_G(yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ +/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \ */\ if ( yyleng >= YYLMAX ) \ YY_FATAL_ERROR( "token too large, exceeds YYLMAX" ); \ - yy_flex_strncpy( yytext, yytext_ptr, yyleng + 1 ); \ - yy_c_buf_p = yy_cp; + yy_flex_strncpy( yytext, YY_G(yytext_ptr), yyleng + 1 YY_CALL_LAST_ARG); \ + YY_G(yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 19 -#define YY_END_OF_BUFFER 20 -static yyconst short int yy_accept[47] = +/* %* */ + +/* %c */ +#ifndef ssIN_HEADER +/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */ +#define YY_NUM_RULES 23 +#define YY_END_OF_BUFFER 24 +static yyconst short int yy_accept[56] = { 0, - 0, 0, 0, 0, 0, 0, 20, 18, 14, 14, - 18, 13, 17, 4, 15, 7, 5, 8, 17, 17, - 17, 17, 17, 14, 6, 0, 17, 9, 10, 17, - 17, 12, 17, 17, 16, 11, 17, 17, 17, 2, - 17, 17, 17, 3, 1, 0 + 0, 0, 0, 0, 0, 0, 24, 22, 18, 18, + 22, 17, 21, 4, 19, 8, 5, 9, 21, 21, + 21, 21, 21, 21, 21, 18, 7, 0, 21, 10, + 6, 11, 21, 21, 14, 21, 21, 13, 21, 21, + 20, 12, 21, 15, 21, 21, 21, 2, 16, 21, + 21, 21, 3, 1, 0 } ; static yyconst int yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 1, 1, 5, 1, - 1, 6, 1, 7, 6, 6, 1, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 1, 8, 9, - 10, 11, 1, 1, 12, 6, 13, 14, 15, 16, - 6, 17, 6, 6, 6, 18, 19, 20, 21, 6, - 6, 22, 23, 24, 6, 6, 25, 6, 6, 6, - 1, 1, 1, 1, 1, 1, 12, 6, 13, 14, - - 15, 16, 6, 17, 6, 6, 6, 18, 19, 20, - 21, 6, 6, 22, 23, 24, 6, 6, 25, 6, - 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 4, 5, 1, 1, 1, 1, 1, 6, 1, + 1, 7, 1, 8, 7, 7, 1, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 9, 10, 11, + 12, 13, 1, 7, 14, 7, 15, 16, 17, 18, + 7, 19, 20, 7, 7, 21, 22, 23, 24, 7, + 7, 25, 26, 27, 28, 7, 29, 7, 7, 7, + 1, 1, 1, 1, 1, 1, 14, 7, 15, 16, + + 17, 18, 7, 19, 20, 7, 7, 21, 22, 23, + 24, 7, 7, 25, 26, 27, 28, 7, 29, 7, + 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst int yy_meta[26] = +static yyconst int yy_meta[30] = { 0, - 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, - 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2 + 1, 1, 1, 2, 1, 1, 3, 1, 2, 1, + 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3 } ; -static yyconst short int yy_base[49] = +static yyconst short int yy_base[58] = { 0, - 0, 0, 0, 0, 0, 0, 53, 54, 24, 26, - 42, 0, 0, 54, 54, 41, 54, 40, 29, 26, - 25, 31, 28, 28, 54, 39, 0, 54, 54, 29, - 21, 0, 23, 25, 54, 0, 20, 23, 15, 0, - 23, 20, 10, 0, 0, 54, 31, 30 + 0, 0, 0, 0, 0, 0, 68, 69, 28, 31, + 55, 0, 0, 69, 69, 54, 53, 52, 40, 37, + 35, 12, 35, 42, 39, 35, 69, 51, 0, 69, + 69, 69, 40, 31, 0, 27, 32, 0, 31, 34, + 69, 0, 28, 0, 28, 31, 22, 0, 0, 31, + 28, 17, 0, 0, 69, 39, 40 } ; -static yyconst short int yy_def[49] = +static yyconst short int yy_def[58] = { 0, - 46, 1, 1, 1, 1, 1, 46, 46, 46, 46, - 46, 47, 48, 46, 46, 46, 46, 46, 48, 48, - 48, 48, 48, 46, 46, 47, 48, 46, 46, 48, - 48, 48, 48, 48, 46, 48, 48, 48, 48, 48, - 48, 48, 48, 48, 48, 0, 46, 46 + 55, 1, 1, 1, 1, 1, 55, 55, 55, 55, + 55, 56, 57, 55, 55, 55, 55, 55, 57, 57, + 57, 57, 57, 57, 57, 55, 55, 56, 57, 55, + 55, 55, 57, 57, 57, 57, 57, 57, 57, 57, + 55, 57, 57, 57, 57, 57, 57, 57, 57, 57, + 57, 57, 57, 57, 0, 55, 55 } ; -static yyconst short int yy_nxt[80] = +static yyconst short int yy_nxt[99] = { 0, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 13, 13, 13, 20, 13, 13, 13, 13, - 21, 13, 22, 13, 23, 24, 24, 24, 24, 24, - 24, 27, 26, 45, 44, 43, 42, 41, 40, 39, - 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, - 28, 25, 46, 7, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46 + 8, 9, 10, 9, 11, 12, 13, 14, 8, 15, + 16, 17, 18, 19, 13, 13, 13, 20, 13, 21, + 13, 13, 22, 23, 13, 24, 13, 13, 25, 26, + 26, 26, 26, 26, 26, 36, 26, 26, 26, 37, + 28, 28, 29, 54, 53, 52, 51, 50, 49, 48, + 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, + 35, 34, 33, 32, 31, 30, 27, 55, 7, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55 + } ; -static yyconst short int yy_chk[80] = +static yyconst short int yy_chk[99] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 9, 9, 10, 10, 24, - 24, 48, 47, 43, 42, 41, 39, 38, 37, 34, - 33, 31, 30, 26, 23, 22, 21, 20, 19, 18, - 16, 11, 7, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46 - } ; + 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, + 9, 9, 10, 10, 10, 22, 26, 26, 26, 22, + 56, 56, 57, 52, 51, 50, 47, 46, 45, 43, + 40, 39, 37, 36, 34, 33, 28, 25, 24, 23, + 21, 20, 19, 18, 17, 16, 11, 7, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55, 55, 55, + 55, 55, 55, 55, 55, 55, 55, 55 -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; + } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #ifndef YYLMAX #define YYLMAX 8192 #endif +#ifndef YY_REENTRANT char yytext[YYLMAX]; char *yytext_ptr; +#endif #line 1 "icalsslexer.l" #define INITIAL 0 #line 2 "icalsslexer.l" /* -*- Mode: C -*- ====================================================================== FILE: icalsslexer.l CREATOR: eric 8 Aug 2000 DESCRIPTION: $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 ======================================================================*/ #include "icalssyacc.h" #include "icalgaugeimpl.h" #include "assert.h" #include <string.h> /* For strdup() */ -int icalparser_flex_input(char* buf, int max_size); -void icalparser_clear_flex_input(); - -#undef YY_INPUT -#define YY_INPUT(b,r,ms) ( r= icalparser_flex_input(b,ms)) +#undef YYPURE +#define YYPURE #undef SS_FATAL_ERROR #define SS_FATAL_ERROR(msg) sserror(msg) - #define sql 1 #define string_value 2 -#line 465 "icalsslexer.c" +#line 596 "lex.ss.c" +/* %e */ +#endif /* !ssIN_HEADER */ + +/* Special case for "unistd.h", since it is non-ANSI. We include it way + * down here because we want the user's section 1 to have been scanned first. + * The user has a chance to override it with an option. + */ +#ifndef YY_NO_UNISTD_H +/* %- */ +#include <unistd.h> +/* %+ */ +/* %* */ +#endif /* !YY_NO_UNISTD_H */ + + +#ifndef YY_EXTRA_TYPE +#define YY_EXTRA_TYPE void * +#endif + +/* %- Reentrant structure and macros (non-C++). */ +#ifdef YY_REENTRANT + +/* %c */ +#ifndef ssIN_HEADER +struct yy_globals_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + YY_BUFFER_STATE yy_current_buffer; + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + +#ifdef YY_TEXT_IS_ARRAY + char yytext_r[YYLMAX]; + char *yytext_ptr; + int yy_more_offset; + int yy_prev_more_offset; +#else + char *yytext_r; + int yy_more_flag; + int yy_more_len; +#endif + +#ifdef YY_REENTRANT_BISON_PURE + YYSTYPE * yylval_r; +#ifdef YYLTYPE + YYLTYPE * yylloc_r; +#endif +#endif + + }; +/* %e */ +#endif /* !ssIN_HEADER */ + +/* %c */ +#ifndef ssIN_HEADER +static int yy_init_globals YY_PROTO(( yyscan_t )); +/* %e */ +#endif /* !ssIN_HEADER */ + +/* This must go here because YYSTYPE and YYLSTYPE are included + * from bison output in section 1.*/ +#ifdef YY_REENTRANT_BISON_PURE +# define yylval YY_G(yylval_r) +# ifdef YYLTYPE +# define yylloc YY_G(yylloc_r) +# endif +#endif /* YY_REENTRANT_BISON_PURE */ + +#endif /* end if YY_REENTRANT */ + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ +#ifndef YY_NO_GET_EXTRA +YY_EXTRA_TYPE yyget_extra YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_SET_EXTRA +void yyset_extra YY_PROTO(( YY_EXTRA_TYPE user_defined YY_LAST_ARG )); +#endif + +#ifndef YY_NO_GET_IN +FILE *yyget_in YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_SET_IN +void yyset_in YY_PROTO(( FILE * in_str YY_LAST_ARG )); +#endif + +#ifndef YY_NO_GET_OUT +FILE *yyget_out YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_SET_OUT +void yyset_out YY_PROTO(( FILE * out_str YY_LAST_ARG )); +#endif + +#ifndef YY_NO_GET_LENG +int yyget_leng YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_GET_TEXT +char *yyget_text YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_GET_LINENO +int yyget_lineno YY_PROTO(( YY_ONLY_ARG )); +#endif + +#ifndef YY_NO_SET_LINENO +void yyset_lineno YY_PROTO(( int line_number YY_LAST_ARG )); +#endif + +#ifdef YY_REENTRANT_BISON_PURE +#ifndef YY_NO_GET_LVAL +YYSTYPE * yyget_lval YY_PROTO(( YY_ONLY_ARG )); +#endif +void yyset_lval YY_PROTO(( YYSTYPE * yylvalp YY_LAST_ARG )); +#ifdef YYLTYPE +#ifndef YY_NO_GET_LLOC + YYLTYPE *yyget_lloc YY_PROTO(( YY_ONLY_ARG )); +#endif +#ifndef YY_NO_SET_LLOC + void yyset_lloc YY_PROTO(( YYLTYPE * yyllocp YY_LAST_ARG )); +#endif +#endif /* YYLTYPE */ +#endif /* YY_REENTRANT_BISON_PURE */ /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus -extern "C" int yywrap YY_PROTO(( void )); +extern "C" int yywrap YY_PROTO(( YY_ONLY_ARG )); #else -extern int yywrap YY_PROTO(( void )); +extern int yywrap YY_PROTO(( YY_ONLY_ARG )); #endif #endif +/* %- */ +/* %c */ +#ifndef ssIN_HEADER #ifndef YY_NO_UNPUT -static void yyunput YY_PROTO(( int c, char *buf_ptr )); +static void yyunput YY_PROTO(( int c, char *buf_ptr YY_LAST_ARG)); #endif +/* %e */ +#endif /* !ssIN_HEADER */ +/* %* */ #ifndef yytext_ptr -static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int YY_LAST_ARG)); #endif #ifdef YY_NEED_STRLEN -static int yy_flex_strlen YY_PROTO(( yyconst char * )); +static int yy_flex_strlen YY_PROTO(( yyconst char * YY_LAST_ARG)); #endif #ifndef YY_NO_INPUT +/* %- Standard (non-C++) definition */ +/* %c */ +#ifndef ssIN_HEADER #ifdef __cplusplus -static int yyinput YY_PROTO(( void )); +static int yyinput YY_PROTO(( YY_ONLY_ARG )); #else -static int input YY_PROTO(( void )); +static int input YY_PROTO(( YY_ONLY_ARG )); #endif +/* %e */ +#endif /* !ssIN_HEADER */ +/* %* */ #endif #if YY_STACK_USED +#ifndef YY_REENTRANT +/* %c */ +#ifndef ssIN_HEADER static int yy_start_stack_ptr = 0; static int yy_start_stack_depth = 0; static int *yy_start_stack = 0; +/* %e */ +#endif /* !ssIN_HEADER */ +#endif #ifndef YY_NO_PUSH_STATE -static void yy_push_state YY_PROTO(( int new_state )); +static void yy_push_state YY_PROTO(( int new_state YY_LAST_ARG)); #endif #ifndef YY_NO_POP_STATE -static void yy_pop_state YY_PROTO(( void )); +static void yy_pop_state YY_PROTO(( YY_ONLY_ARG )); #endif #ifndef YY_NO_TOP_STATE -static int yy_top_state YY_PROTO(( void )); +static int yy_top_state YY_PROTO(( YY_ONLY_ARG )); #endif #else #define YY_NO_PUSH_STATE 1 #define YY_NO_POP_STATE 1 #define YY_NO_TOP_STATE 1 #endif -#ifdef YY_MALLOC_DECL -YY_MALLOC_DECL -#else -#if __STDC__ -#ifndef __cplusplus -#include <stdlib.h> -#endif -#else -/* Just try to get by without declaring the routines. This will fail - * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) - * or sizeof(void*) != sizeof(int). - */ -#endif -#endif - /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO +/* %- Standard (non-C++) definition */ /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +/* %+ C++ definition */ +/* %* */ #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ - if ( yy_current_buffer->yy_is_interactive ) \ +/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \ */\ + if ( YY_G(yy_current_buffer)->yy_is_interactive ) \ { \ - int c = '*', n; \ + int c = '*'; \ + size_t n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ - else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ - && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + } +/* %+ C++ definition \ */\ +/* %* */ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR +/* %- */ #define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +/* %+ */ +/* %* */ #endif /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL -#define YY_DECL int yylex YY_PROTO(( void )) +/* %- Standard (non-C++) definition */ + +/* If the bison pure parser is used, then bison will provide + one or two additional arguments. */ + +#ifdef YY_REENTRANT_BISON_PURE +# ifdef YYLTYPE +# ifdef YY_USE_PROTOS +# define YY_LEX_ARGS (YYSTYPE * yylvalp, YYLTYPE * yyllocp YY_LAST_ARG) +# else +# define YY_LEX_ARGS (yylvalp, yyllocp YY_LAST_ARG) \ + YYSTYPE * yylvalp; YYLTYPE * yyllocp; YY_DECL_LAST_ARG +# endif +# else +# ifdef YY_USE_PROTOS +# define YY_LEX_ARGS (YYSTYPE * yylvalp YY_LAST_ARG) +# else +# define YY_LEX_ARGS (yylvalp YY_LAST_ARG) \ + YYSTYPE * yylvalp; YY_DECL_LAST_ARG +# endif +# endif +#else +# ifdef YY_USE_PROTOS +# define YY_LEX_ARGS (YY_ONLY_ARG) +# else +# define YY_LEX_ARGS (YY_ONLY_ARG) YY_DECL_LAST_ARG +# endif +#endif + + +extern int yylex YY_PROTO( YY_LEX_ARGS ); + +#define YY_DECL int yylex YY_LEX_ARGS +/* %+ C++ definition */ +/* %* */ #endif /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif +/* %% [6.0] YY_RULE_SETUP definition goes here */ #define YY_RULE_SETUP \ YY_USER_ACTION +/* %c */ +#ifndef ssIN_HEADER YY_DECL { register yy_state_type yy_current_state; - register char *yy_cp = NULL, *yy_bp = NULL; + register char *yy_cp, *yy_bp; register int yy_act; -#line 69 "icalsslexer.l" +/* %% [7.0] user's declarations go here */ +#line 66 "icalsslexer.l" + +#line 959 "lex.ss.c" -#line 623 "icalsslexer.c" +#ifdef YY_REENTRANT_BISON_PURE + yylval = yylvalp; +#ifdef YYLTYPE + yylloc = yyllocp; +#endif +#endif - if ( yy_init ) + if ( YY_G(yy_init) ) { - yy_init = 0; + YY_G(yy_init) = 0; #ifdef YY_USER_INIT YY_USER_INIT; #endif - if ( ! yy_start ) - yy_start = 1; /* first start state */ + if ( ! YY_G(yy_start) ) + YY_G(yy_start) = 1; /* first start state */ if ( ! yyin ) +/* %- */ yyin = stdin; +/* %+ */ +/* %* */ if ( ! yyout ) +/* %- */ yyout = stdout; +/* %+ */ +/* %* */ - if ( ! yy_current_buffer ) - yy_current_buffer = - yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! YY_G(yy_current_buffer) ) + YY_G(yy_current_buffer) = + yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); - yy_load_buffer_state(); + yy_load_buffer_state( YY_CALL_ONLY_ARG ); } while ( 1 ) /* loops until end-of-file is reached */ { - yy_cp = yy_c_buf_p; +/* %% [8.0] yymore()-related code goes here */ + yy_cp = YY_G(yy_c_buf_p); /* Support of yytext. */ - *yy_cp = yy_hold_char; + *yy_cp = YY_G(yy_hold_char); /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; - yy_current_state = yy_start; +/* %% [9.0] code to set up and find next match goes here */ + yy_current_state = YY_G(yy_start); yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + YY_G(yy_last_accepting_state) = yy_current_state; + YY_G(yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 47 ) + if ( yy_current_state >= 56 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 54 ); + while ( yy_base[yy_current_state] != 69 ); yy_find_action: +/* %% [10.0] code to find the action number goes here */ yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + yy_cp = YY_G(yy_last_accepting_cpos); + yy_current_state = YY_G(yy_last_accepting_state); yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; +/* %% [11.0] code for yylineno update goes here */ do_action: /* This label is used only to access EOF actions. */ +/* %% [12.0] debug code goes here */ switch ( yy_act ) { /* beginning of action switch */ +/* %% [13.0] actions go here */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yy_hold_char; - yy_cp = yy_last_accepting_cpos; - yy_current_state = yy_last_accepting_state; + *yy_cp = YY_G(yy_hold_char); + yy_cp = YY_G(yy_last_accepting_cpos); + yy_current_state = YY_G(yy_last_accepting_state); goto yy_find_action; case 1: YY_RULE_SETUP -#line 75 "icalsslexer.l" +#line 72 "icalsslexer.l" { return SELECT; } YY_BREAK case 2: YY_RULE_SETUP -#line 76 "icalsslexer.l" +#line 73 "icalsslexer.l" { return FROM; } YY_BREAK case 3: YY_RULE_SETUP -#line 77 "icalsslexer.l" +#line 74 "icalsslexer.l" { return WHERE; } YY_BREAK case 4: YY_RULE_SETUP -#line 78 "icalsslexer.l" +#line 75 "icalsslexer.l" { return COMMA; } YY_BREAK case 5: YY_RULE_SETUP -#line 79 "icalsslexer.l" +#line 76 "icalsslexer.l" { return EQUALS; } YY_BREAK case 6: YY_RULE_SETUP -#line 80 "icalsslexer.l" -{ return NOTEQUALS; } +#line 77 "icalsslexer.l" +{ return EQUALS; } YY_BREAK case 7: YY_RULE_SETUP -#line 81 "icalsslexer.l" -{ return LESS; } +#line 78 "icalsslexer.l" +{ return NOTEQUALS; } YY_BREAK case 8: YY_RULE_SETUP -#line 82 "icalsslexer.l" -{ return GREATER; } +#line 79 "icalsslexer.l" +{ return LESS; } YY_BREAK case 9: YY_RULE_SETUP -#line 83 "icalsslexer.l" -{ return LESSEQUALS; } +#line 80 "icalsslexer.l" +{ return GREATER; } YY_BREAK case 10: YY_RULE_SETUP -#line 84 "icalsslexer.l" -{ return GREATEREQUALS; } +#line 81 "icalsslexer.l" +{ return LESSEQUALS; } YY_BREAK case 11: YY_RULE_SETUP -#line 85 "icalsslexer.l" -{ return AND; } +#line 82 "icalsslexer.l" +{ return GREATEREQUALS; } YY_BREAK case 12: YY_RULE_SETUP -#line 86 "icalsslexer.l" -{ return OR; } +#line 83 "icalsslexer.l" +{ return AND; } YY_BREAK case 13: YY_RULE_SETUP -#line 87 "icalsslexer.l" -{ return QUOTE; } +#line 84 "icalsslexer.l" +{ return OR; } YY_BREAK case 14: YY_RULE_SETUP -#line 88 "icalsslexer.l" -; +#line 85 "icalsslexer.l" +{ return IS; } YY_BREAK case 15: YY_RULE_SETUP -#line 89 "icalsslexer.l" -{ return EOL; } +#line 86 "icalsslexer.l" +{ return NOT; } YY_BREAK case 16: YY_RULE_SETUP +#line 87 "icalsslexer.l" +{ return SQLNULL; } + YY_BREAK +case 17: +YY_RULE_SETUP +#line 88 "icalsslexer.l" +{ return QUOTE; } + YY_BREAK +case 18: +YY_RULE_SETUP +#line 89 "icalsslexer.l" +; + YY_BREAK +case 19: +YY_RULE_SETUP #line 90 "icalsslexer.l" +{ return EOL; } + YY_BREAK +case 20: +YY_RULE_SETUP +#line 92 "icalsslexer.l" { - int c = input(); + int c = input(yy_globals); unput(c); if(c!='\''){ - sslval.v_string= icalmemory_tmp_copy(sstext); + yylvalp->v_string= icalmemory_tmp_copy(yytext); return STRING; } else { /*ssmore();*/ } } YY_BREAK -case 17: +case 21: YY_RULE_SETUP -#line 101 "icalsslexer.l" -{ sslval.v_string= icalmemory_tmp_copy(sstext); - return STRING; } +#line 103 "icalsslexer.l" +{ + yylval->v_string= icalmemory_tmp_copy(yytext); + return STRING; +} YY_BREAK -case 18: +case 22: YY_RULE_SETUP -#line 105 "icalsslexer.l" +#line 109 "icalsslexer.l" { return yytext[0]; } YY_BREAK -case 19: +case 23: YY_RULE_SETUP -#line 107 "icalsslexer.l" +#line 111 "icalsslexer.l" ECHO; YY_BREAK -#line 811 "icalsslexer.c" +#line 1188 "lex.ss.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(sql): case YY_STATE_EOF(string_value): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + int yy_amount_of_matched_text = (int) (yy_cp - YY_G(yytext_ptr)) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yy_hold_char; + *yy_cp = YY_G(yy_hold_char); YY_RESTORE_YY_MORE_OFFSET - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + if ( YY_G(yy_current_buffer)->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * yylex(). If so, then we have to assure * consistency between yy_current_buffer and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ - yy_n_chars = yy_current_buffer->yy_n_chars; - yy_current_buffer->yy_input_file = yyin; - yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + YY_G(yy_n_chars) = YY_G(yy_current_buffer)->yy_n_chars; + YY_G(yy_current_buffer)->yy_input_file = yyin; + YY_G(yy_current_buffer)->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ - if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( YY_G(yy_c_buf_p) <= &YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars)] ) { /* This was really a NUL. */ yy_state_type yy_next_state; - yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( YY_CALL_ONLY_ARG ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ - yy_next_state = yy_try_NUL_trans( yy_current_state ); + yy_next_state = yy_try_NUL_trans( yy_current_state YY_CALL_LAST_ARG); - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ - yy_cp = ++yy_c_buf_p; + yy_cp = ++YY_G(yy_c_buf_p); yy_current_state = yy_next_state; goto yy_match; } else { - yy_cp = yy_c_buf_p; +/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */ + yy_cp = YY_G(yy_c_buf_p); goto yy_find_action; } } - else switch ( yy_get_next_buffer() ) + else switch ( yy_get_next_buffer( YY_CALL_ONLY_ARG ) ) { case EOB_ACT_END_OF_FILE: { - yy_did_buffer_switch_on_eof = 0; + YY_G(yy_did_buffer_switch_on_eof) = 0; - if ( yywrap() ) + if ( yywrap( YY_CALL_ONLY_ARG ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ - yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! YY_G(yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = - yytext_ptr + yy_amount_of_matched_text; + YY_G(yy_c_buf_p) = + YY_G(yytext_ptr) + yy_amount_of_matched_text; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( YY_CALL_ONLY_ARG ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = YY_G(yy_c_buf_p); + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: - yy_c_buf_p = - &yy_current_buffer->yy_ch_buf[yy_n_chars]; + YY_G(yy_c_buf_p) = + &YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars)]; - yy_current_state = yy_get_previous_state(); + yy_current_state = yy_get_previous_state( YY_CALL_ONLY_ARG ); - yy_cp = yy_c_buf_p; - yy_bp = yytext_ptr + YY_MORE_ADJ; + yy_cp = YY_G(yy_c_buf_p); + yy_bp = YY_G(yytext_ptr) + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of yylex */ - +/* %e */ +#endif /* !ssIN_HEADER */ +/* %+ */ +/* %c */ +#ifndef ssIN_HEADER +/* %e */ +#endif /* !ssIN_HEADER */ +/* %* */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ -static int yy_get_next_buffer() +/* %- */ +/* %c */ +#ifndef ssIN_HEADER +#ifdef YY_USE_PROTOS +static int yy_get_next_buffer(YY_ONLY_ARG) +#else +static int yy_get_next_buffer(YY_ONLY_ARG) +YY_DECL_LAST_ARG +#endif +/* %+ */ +/* %* */ { - register char *dest = yy_current_buffer->yy_ch_buf; - register char *source = yytext_ptr; + register char *dest = YY_G(yy_current_buffer)->yy_ch_buf; + register char *source = YY_G(yytext_ptr); register int number_to_move, i; int ret_val; - if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + if ( YY_G(yy_c_buf_p) > &YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars) + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); - if ( yy_current_buffer->yy_fill_buffer == 0 ) + if ( YY_G(yy_current_buffer)->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + if ( YY_G(yy_c_buf_p) - YY_G(yytext_ptr) - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + number_to_move = (int) (YY_G(yy_c_buf_p) - YY_G(yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); - if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + if ( YY_G(yy_current_buffer)->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ - yy_current_buffer->yy_n_chars = yy_n_chars = 0; + YY_G(yy_current_buffer)->yy_n_chars = YY_G(yy_n_chars) = 0; else { - int num_to_read = - yy_current_buffer->yy_buf_size - number_to_move - 1; + size_t num_to_read = + YY_G(yy_current_buffer)->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ #ifdef YY_USES_REJECT YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); #else /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = yy_current_buffer; + YY_BUFFER_STATE b = YY_G(yy_current_buffer); int yy_c_buf_p_offset = - (int) (yy_c_buf_p - b->yy_ch_buf); + (int) (YY_G(yy_c_buf_p) - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ yy_flex_realloc( (void *) b->yy_ch_buf, - b->yy_buf_size + 2 ); + b->yy_buf_size + 2 YY_CALL_LAST_ARG ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); - yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + YY_G(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - num_to_read = yy_current_buffer->yy_buf_size - + num_to_read = YY_G(yy_current_buffer)->yy_buf_size - number_to_move - 1; #endif } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ - YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), - yy_n_chars, num_to_read ); + YY_INPUT( (&YY_G(yy_current_buffer)->yy_ch_buf[number_to_move]), + YY_G(yy_n_chars), num_to_read ); - yy_current_buffer->yy_n_chars = yy_n_chars; + YY_G(yy_current_buffer)->yy_n_chars = YY_G(yy_n_chars); } - if ( yy_n_chars == 0 ) + if ( YY_G(yy_n_chars) == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; - yyrestart( yyin ); + yyrestart( yyin YY_CALL_LAST_ARG); } else { ret_val = EOB_ACT_LAST_MATCH; - yy_current_buffer->yy_buffer_status = + YY_G(yy_current_buffer)->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; - yy_n_chars += number_to_move; - yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; - yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + YY_G(yy_n_chars) += number_to_move; + YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; + YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + YY_G(yytext_ptr) = &YY_G(yy_current_buffer)->yy_ch_buf[0]; return ret_val; } - +/* %e */ +#endif /* !ssIN_HEADER */ /* yy_get_previous_state - get the state just before the EOB char was reached */ -static yy_state_type yy_get_previous_state() +/* %- */ +/* %c */ +#ifndef ssIN_HEADER +#ifdef YY_USE_PROTOS +static yy_state_type yy_get_previous_state(YY_ONLY_ARG) +#else +static yy_state_type yy_get_previous_state(YY_ONLY_ARG) +YY_DECL_LAST_ARG +#endif +/* %+ */ +/* %* */ { register yy_state_type yy_current_state; register char *yy_cp; - yy_current_state = yy_start; +/* %% [15.0] code to get the start state into yy_current_state goes here */ + yy_current_state = YY_G(yy_start); - for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + for ( yy_cp = YY_G(yytext_ptr) + YY_MORE_ADJ; yy_cp < YY_G(yy_c_buf_p); ++yy_cp ) { +/* %% [16.0] code to find the next state goes here */ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + YY_G(yy_last_accepting_state) = yy_current_state; + YY_G(yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 47 ) + if ( yy_current_state >= 56 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ +/* %- */ #ifdef YY_USE_PROTOS -static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state YY_LAST_ARG ) #else -static yy_state_type yy_try_NUL_trans( yy_current_state ) +static yy_state_type yy_try_NUL_trans( yy_current_state YY_LAST_ARG ) yy_state_type yy_current_state; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { register int yy_is_jam; - register char *yy_cp = yy_c_buf_p; +/* %% [17.0] code to find the next state, and perhaps do backing up, goes here */ + register char *yy_cp = YY_G(yy_c_buf_p); register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { - yy_last_accepting_state = yy_current_state; - yy_last_accepting_cpos = yy_cp; + YY_G(yy_last_accepting_state) = yy_current_state; + YY_G(yy_last_accepting_cpos) = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 47 ) + if ( yy_current_state >= 56 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 46); + yy_is_jam = (yy_current_state == 55); return yy_is_jam ? 0 : yy_current_state; } +/* %- */ #ifndef YY_NO_UNPUT #ifdef YY_USE_PROTOS -static void yyunput( int c, register char *yy_bp ) +static void yyunput( int c, register char *yy_bp YY_LAST_ARG ) #else -static void yyunput( c, yy_bp ) +static void yyunput( c, yy_bp YY_LAST_ARG) int c; register char *yy_bp; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - register char *yy_cp = yy_c_buf_p; + register char *yy_cp = YY_G(yy_c_buf_p); /* undo effects of setting up yytext */ - *yy_cp = yy_hold_char; + *yy_cp = YY_G(yy_hold_char); - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_G(yy_current_buffer)->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ - register int number_to_move = yy_n_chars + 2; - register char *dest = &yy_current_buffer->yy_ch_buf[ - yy_current_buffer->yy_buf_size + 2]; + register int number_to_move = YY_G(yy_n_chars) + 2; + register char *dest = &YY_G(yy_current_buffer)->yy_ch_buf[ + YY_G(yy_current_buffer)->yy_buf_size + 2]; register char *source = - &yy_current_buffer->yy_ch_buf[number_to_move]; + &YY_G(yy_current_buffer)->yy_ch_buf[number_to_move]; - while ( source > yy_current_buffer->yy_ch_buf ) + while ( source > YY_G(yy_current_buffer)->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); - yy_current_buffer->yy_n_chars = - yy_n_chars = yy_current_buffer->yy_buf_size; + YY_G(yy_current_buffer)->yy_n_chars = + YY_G(yy_n_chars) = YY_G(yy_current_buffer)->yy_buf_size; - if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + if ( yy_cp < YY_G(yy_current_buffer)->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; +/* %% [18.0] update yylineno here */ - yytext_ptr = yy_bp; - yy_hold_char = *yy_cp; - yy_c_buf_p = yy_cp; + YY_G(yytext_ptr) = yy_bp; + YY_G(yy_hold_char) = *yy_cp; + YY_G(yy_c_buf_p) = yy_cp; } +/* %- */ #endif /* ifndef YY_NO_UNPUT */ +/* %* */ +/* %- */ +#ifndef YY_NO_INPUT #ifdef __cplusplus -static int yyinput() +static int yyinput(YY_ONLY_ARG) #else -static int input() +#ifdef YY_USE_PROTOS +static int input(YY_ONLY_ARG) +#else +static int input(YY_ONLY_ARG) + YY_DECL_LAST_ARG +#endif #endif +/* %+ */ +/* %* */ { int c; - *yy_c_buf_p = yy_hold_char; + *YY_G(yy_c_buf_p) = YY_G(yy_hold_char); - if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + if ( *YY_G(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ - if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + if ( YY_G(yy_c_buf_p) < &YY_G(yy_current_buffer)->yy_ch_buf[YY_G(yy_n_chars)] ) /* This was really a NUL. */ - *yy_c_buf_p = '\0'; + *YY_G(yy_c_buf_p) = '\0'; else { /* need more input */ - int offset = yy_c_buf_p - yytext_ptr; - ++yy_c_buf_p; + int offset = YY_G(yy_c_buf_p) - YY_G(yytext_ptr); + ++YY_G(yy_c_buf_p); - switch ( yy_get_next_buffer() ) + switch ( yy_get_next_buffer( YY_CALL_ONLY_ARG ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ - yyrestart( yyin ); + yyrestart( yyin YY_CALL_LAST_ARG); /* fall through */ case EOB_ACT_END_OF_FILE: { - if ( yywrap() ) + if ( yywrap( YY_CALL_ONLY_ARG ) ) return EOF; - if ( ! yy_did_buffer_switch_on_eof ) + if ( ! YY_G(yy_did_buffer_switch_on_eof) ) YY_NEW_FILE; #ifdef __cplusplus - return yyinput(); + return yyinput(YY_CALL_ONLY_ARG); #else - return input(); + return input(YY_CALL_ONLY_ARG); #endif } case EOB_ACT_CONTINUE_SCAN: - yy_c_buf_p = yytext_ptr + offset; + YY_G(yy_c_buf_p) = YY_G(yytext_ptr) + offset; break; } } } - c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ - *yy_c_buf_p = '\0'; /* preserve yytext */ - yy_hold_char = *++yy_c_buf_p; + c = *(unsigned char *) YY_G(yy_c_buf_p); /* cast for 8-bit char's */ + *YY_G(yy_c_buf_p) = '\0'; /* preserve yytext */ + YY_G(yy_hold_char) = *++YY_G(yy_c_buf_p); +/* %% [19.0] update BOL and yylineno */ return c; } +/* %- */ +#endif /* ifndef YY_NO_INPUT */ +/* %* */ - +/* %- */ #ifdef YY_USE_PROTOS -void yyrestart( FILE *input_file ) +void yyrestart( FILE *input_file YY_LAST_ARG) #else -void yyrestart( input_file ) +void yyrestart( input_file YY_LAST_ARG) FILE *input_file; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - if ( ! yy_current_buffer ) - yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + if ( ! YY_G(yy_current_buffer) ) + YY_G(yy_current_buffer) = + yy_create_buffer( yyin, YY_BUF_SIZE YY_CALL_LAST_ARG); - yy_init_buffer( yy_current_buffer, input_file ); - yy_load_buffer_state(); + yy_init_buffer( YY_G(yy_current_buffer), input_file YY_CALL_LAST_ARG); + yy_load_buffer_state( YY_CALL_ONLY_ARG ); } +/* %- */ #ifdef YY_USE_PROTOS -void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer YY_LAST_ARG ) #else -void yy_switch_to_buffer( new_buffer ) +void yy_switch_to_buffer( new_buffer YY_LAST_ARG ) YY_BUFFER_STATE new_buffer; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - if ( yy_current_buffer == new_buffer ) + if ( YY_G(yy_current_buffer) == new_buffer ) return; - if ( yy_current_buffer ) + if ( YY_G(yy_current_buffer) ) { /* Flush out information for old buffer. */ - *yy_c_buf_p = yy_hold_char; - yy_current_buffer->yy_buf_pos = yy_c_buf_p; - yy_current_buffer->yy_n_chars = yy_n_chars; + *YY_G(yy_c_buf_p) = YY_G(yy_hold_char); + YY_G(yy_current_buffer)->yy_buf_pos = YY_G(yy_c_buf_p); + YY_G(yy_current_buffer)->yy_n_chars = YY_G(yy_n_chars); } - yy_current_buffer = new_buffer; - yy_load_buffer_state(); + YY_G(yy_current_buffer) = new_buffer; + yy_load_buffer_state( YY_CALL_ONLY_ARG ); /* We don't actually know whether we did this switch during * EOF (yywrap()) processing, but the only time this flag * is looked at is after yywrap() is called, so it's safe * to go ahead and always set it. */ - yy_did_buffer_switch_on_eof = 1; + YY_G(yy_did_buffer_switch_on_eof) = 1; } +/* %- */ #ifdef YY_USE_PROTOS -void yy_load_buffer_state( void ) +void yy_load_buffer_state( YY_ONLY_ARG ) #else -void yy_load_buffer_state() +void yy_load_buffer_state(YY_ONLY_ARG ) +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - yy_n_chars = yy_current_buffer->yy_n_chars; - yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; - yyin = yy_current_buffer->yy_input_file; - yy_hold_char = *yy_c_buf_p; + YY_G(yy_n_chars) = YY_G(yy_current_buffer)->yy_n_chars; + YY_G(yytext_ptr) = YY_G(yy_c_buf_p) = YY_G(yy_current_buffer)->yy_buf_pos; + yyin = YY_G(yy_current_buffer)->yy_input_file; + YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); } +/* %- */ #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size YY_LAST_ARG) #else -YY_BUFFER_STATE yy_create_buffer( file, size ) +YY_BUFFER_STATE yy_create_buffer( file, size YY_LAST_ARG) FILE *file; int size; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { YY_BUFFER_STATE b; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) YY_CALL_LAST_ARG ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 YY_CALL_LAST_ARG ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); b->yy_is_our_buffer = 1; - yy_init_buffer( b, file ); + yy_init_buffer( b, file YY_CALL_LAST_ARG); return b; } +/* %- */ #ifdef YY_USE_PROTOS -void yy_delete_buffer( YY_BUFFER_STATE b ) +void yy_delete_buffer( YY_BUFFER_STATE b YY_LAST_ARG) #else -void yy_delete_buffer( b ) +void yy_delete_buffer( b YY_LAST_ARG) YY_BUFFER_STATE b; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { if ( ! b ) return; - if ( b == yy_current_buffer ) - yy_current_buffer = (YY_BUFFER_STATE) 0; + if ( b == YY_G(yy_current_buffer) ) + YY_G(yy_current_buffer) = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) - yy_flex_free( (void *) b->yy_ch_buf ); + yy_flex_free( (void *) b->yy_ch_buf YY_CALL_LAST_ARG ); - yy_flex_free( (void *) b ); + yy_flex_free( (void *) b YY_CALL_LAST_ARG ); } +/* %- */ +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +#ifdef __cplusplus +extern "C" int isatty YY_PROTO(( int )); +#else +extern int isatty YY_PROTO(( int )); +#endif /* __cplusplus */ +#endif /* !YY_NEVER_INTERACTIVE */ +#endif /* !YY_ALWAYS_INTERACTIVE */ #ifdef YY_USE_PROTOS -void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file YY_LAST_ARG) #else -void yy_init_buffer( b, file ) +void yy_init_buffer( b, file YY_LAST_ARG) YY_BUFFER_STATE b; FILE *file; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - yy_flush_buffer( b ); + int oerrno = errno; + + yy_flush_buffer( b YY_CALL_LAST_ARG); b->yy_input_file = file; b->yy_fill_buffer = 1; +/* %- */ #if YY_ALWAYS_INTERACTIVE b->yy_is_interactive = 1; #else #if YY_NEVER_INTERACTIVE b->yy_is_interactive = 0; #else - -#ifdef _QTWIN_ - b->yy_is_interactive = file ? (_isatty( fileno(file) ) > 0) : 0; -#else b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; #endif - -#endif #endif +/* %+ */ +/* %* */ + errno = oerrno; } +/* %- */ #ifdef YY_USE_PROTOS -void yy_flush_buffer( YY_BUFFER_STATE b ) +void yy_flush_buffer( YY_BUFFER_STATE b YY_LAST_ARG ) #else -void yy_flush_buffer( b ) +void yy_flush_buffer( b YY_LAST_ARG ) YY_BUFFER_STATE b; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; - if ( b == yy_current_buffer ) - yy_load_buffer_state(); + if ( b == YY_G(yy_current_buffer) ) + yy_load_buffer_state( YY_CALL_ONLY_ARG ); } +/* %* */ #ifndef YY_NO_SCAN_BUFFER +/* %- */ #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size YY_LAST_ARG ) #else -YY_BUFFER_STATE yy_scan_buffer( base, size ) +YY_BUFFER_STATE yy_scan_buffer( base, size YY_LAST_ARG ) char *base; yy_size_t size; +YY_DECL_LAST_ARG #endif { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; - b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) YY_CALL_LAST_ARG ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; - yy_switch_to_buffer( b ); + yy_switch_to_buffer( b YY_CALL_LAST_ARG ); return b; } +/* %* */ #endif #ifndef YY_NO_SCAN_STRING +/* %- */ #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str YY_LAST_ARG ) #else -YY_BUFFER_STATE yy_scan_string( yy_str ) +YY_BUFFER_STATE yy_scan_string( yy_str YY_LAST_ARG) yyconst char *yy_str; +YY_DECL_LAST_ARG #endif { int len; for ( len = 0; yy_str[len]; ++len ) ; - return yy_scan_bytes( yy_str, len ); + return yy_scan_bytes( yy_str, len YY_CALL_LAST_ARG); } +/* %* */ #endif #ifndef YY_NO_SCAN_BYTES +/* %- */ #ifdef YY_USE_PROTOS -YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len YY_LAST_ARG) #else -YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +YY_BUFFER_STATE yy_scan_bytes( bytes, len YY_LAST_ARG) yyconst char *bytes; +YY_DECL_LAST_ARG int len; #endif { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = len + 2; - buf = (char *) yy_flex_alloc( n ); + buf = (char *) yy_flex_alloc( n YY_CALL_LAST_ARG ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); for ( i = 0; i < len; ++i ) buf[i] = bytes[i]; buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - b = yy_scan_buffer( buf, n ); + b = yy_scan_buffer( buf, n YY_CALL_LAST_ARG); if ( ! b ) YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } +/* %* */ #endif #ifndef YY_NO_PUSH_STATE +/* %- */ #ifdef YY_USE_PROTOS -static void yy_push_state( int new_state ) +static void yy_push_state( int new_state YY_LAST_ARG) #else -static void yy_push_state( new_state ) +static void yy_push_state( new_state YY_LAST_ARG) int new_state; +YY_DECL_LAST_ARG #endif +/* %+ */ +/* %* */ { - if ( yy_start_stack_ptr >= yy_start_stack_depth ) + if ( YY_G(yy_start_stack_ptr) >= YY_G(yy_start_stack_depth) ) { yy_size_t new_size; - yy_start_stack_depth += YY_START_STACK_INCR; - new_size = yy_start_stack_depth * sizeof( int ); + YY_G(yy_start_stack_depth) += YY_START_STACK_INCR; + new_size = YY_G(yy_start_stack_depth) * sizeof( int ); - if ( ! yy_start_stack ) - yy_start_stack = (int *) yy_flex_alloc( new_size ); + if ( ! YY_G(yy_start_stack) ) + YY_G(yy_start_stack) = (int *) yy_flex_alloc( new_size YY_CALL_LAST_ARG ); else - yy_start_stack = (int *) yy_flex_realloc( - (void *) yy_start_stack, new_size ); + YY_G(yy_start_stack) = (int *) yy_flex_realloc( + (void *) YY_G(yy_start_stack), new_size YY_CALL_LAST_ARG ); - if ( ! yy_start_stack ) + if ( ! YY_G(yy_start_stack) ) YY_FATAL_ERROR( "out of memory expanding start-condition stack" ); } - yy_start_stack[yy_start_stack_ptr++] = YY_START; + YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)++] = YY_START; BEGIN(new_state); } #endif #ifndef YY_NO_POP_STATE -static void yy_pop_state() +/* %- */ +#ifdef YY_USE_PROTOS +static void yy_pop_state( YY_ONLY_ARG ) +#else +static void yy_pop_state( YY_ONLY_ARG ) +YY_DECL_LAST_ARG +#endif +/* %+ */ +/* %* */ { - if ( --yy_start_stack_ptr < 0 ) + if ( --YY_G(yy_start_stack_ptr) < 0 ) YY_FATAL_ERROR( "start-condition stack underflow" ); - BEGIN(yy_start_stack[yy_start_stack_ptr]); + BEGIN(YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr)]); } #endif #ifndef YY_NO_TOP_STATE -static int yy_top_state() +/* %- */ +#ifdef YY_USE_PROTOS +static int yy_top_state( YY_ONLY_ARG ) +#else +static int yy_top_state( YY_ONLY_ARG ) +YY_DECL_LAST_ARG +#endif +/* %+ */ +/* %* */ { - return yy_start_stack[yy_start_stack_ptr - 1]; + return YY_G(yy_start_stack)[YY_G(yy_start_stack_ptr) - 1]; } #endif #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif -#ifdef YY_USE_PROTOS +/* %- */ static void yy_fatal_error( yyconst char msg[] ) -#else -static void yy_fatal_error( msg ) -char msg[]; -#endif { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } +/* %+ */ +/* %* */ /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ - yytext[yyleng] = yy_hold_char; \ - yy_c_buf_p = yytext + n; \ - yy_hold_char = *yy_c_buf_p; \ - *yy_c_buf_p = '\0'; \ + yytext[yyleng] = YY_G(yy_hold_char); \ + YY_G(yy_c_buf_p) = yytext + n; \ + YY_G(yy_hold_char) = *YY_G(yy_c_buf_p); \ + *YY_G(yy_c_buf_p) = '\0'; \ yyleng = n; \ } \ while ( 0 ) + +#ifdef YY_REENTRANT + +/* Accessor methods (get/set functions) to struct members. */ + +#ifndef YY_NO_GET_EXTRA +#ifdef YY_USE_PROTOS +YY_EXTRA_TYPE yyget_extra( YY_ONLY_ARG ) +#else +YY_EXTRA_TYPE yyget_extra( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yyextra; +} +#endif /* !YY_NO_GET_EXTRA */ + +#ifndef YY_NO_GET_LINENO +# ifdef YY_USE_PROTOS +int yyget_lineno( YY_ONLY_ARG ) +# else +int yyget_lineno( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +# endif +{ + return yylineno; +} +#endif /* !YY_NO_GET_LINENO */ + +#ifndef YY_NO_GET_IN +#ifdef YY_USE_PROTOS +FILE *yyget_in( YY_ONLY_ARG ) +#else +FILE *yyget_in( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yyin; +} +#endif /* !YY_NO_GET_IN */ + +#ifndef YY_NO_GET_OUT +#ifdef YY_USE_PROTOS +FILE *yyget_out( YY_ONLY_ARG ) +#else +FILE *yyget_out( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yyout; +} +#endif /* !YY_NO_GET_OUT */ + +#ifndef YY_NO_GET_LENG +#ifdef YY_USE_PROTOS +int yyget_leng( YY_ONLY_ARG ) +#else +int yyget_leng( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yyleng; +} +#endif /* !YY_NO_GET_LENG */ + +#ifndef YY_NO_GET_TEXT +#ifdef YY_USE_PROTOS +char *yyget_text( YY_ONLY_ARG ) +#else +char *yyget_text( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yytext; +} +#endif /* !YY_NO_GET_TEXT */ + +#ifndef YY_NO_SET_EXTRA +#ifdef YY_USE_PROTOS +void yyset_extra( YY_EXTRA_TYPE user_defined YY_LAST_ARG ) +#else +void yyset_extra( user_defined YY_LAST_ARG ) + YY_EXTRA_TYPE user_defined; + YY_DECL_LAST_ARG +#endif +{ + yyextra = user_defined ; +} +#endif /* !YY_NO_SET_EXTRA */ + +#ifndef YY_NO_SET_LINENO +# ifdef YY_USE_PROTOS +void yyset_lineno( int line_number YY_LAST_ARG ) +# else +void yyset_lineno( line_number YY_LAST_ARG ) + int line_number; + YY_DECL_LAST_ARG +# endif +{ + yylineno = line_number; +} +#endif /* !YY_NO_SET_LINENO */ + + +#ifndef YY_NO_SET_IN +#ifdef YY_USE_PROTOS +void yyset_in( FILE * in_str YY_LAST_ARG ) +#else +void yyset_in( in_str YY_LAST_ARG ) + FILE * in_str; + YY_DECL_LAST_ARG +#endif +{ + yyin = in_str ; +} +#endif /* !YY_NO_SET_IN */ + +#ifndef YY_NO_SET_OUT +#ifdef YY_USE_PROTOS +void yyset_out( FILE * out_str YY_LAST_ARG ) +#else +void yyset_out( out_str YY_LAST_ARG ) + FILE * out_str; + YY_DECL_LAST_ARG +#endif +{ + yyout = out_str ; +} +#endif /* !YY_NO_SET_OUT */ + +/* Accessor methods for yylval and yylloc */ + +#ifdef YY_REENTRANT_BISON_PURE +#ifndef YY_NO_GET_LVAL +#ifdef YY_USE_PROTOS +YYSTYPE * yyget_lval( YY_ONLY_ARG ) +#else +YYSTYPE * yyget_lval( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yylval; +} +#endif /* !YY_NO_GET_LVAL */ + +#ifndef YY_NO_SET_LVAL +#ifdef YY_USE_PROTOS +void yyset_lval( YYSTYPE * yylvalp YY_LAST_ARG ) +#else +void yyset_lval( yylvalp YY_LAST_ARG ) + YYSTYPE * yylvalp; + YY_DECL_LAST_ARG +#endif +{ + yylval = yylvalp; +} +#endif /* !YY_NO_SET_LVAL */ + +#ifdef YYLTYPE +#ifndef YY_NO_GET_LLOC +#ifdef YY_USE_PROTOS +YYLTYPE *yyget_lloc( YY_ONLY_ARG ) +#else +YYLTYPE *yyget_lloc( YY_ONLY_ARG ) + YY_DECL_LAST_ARG +#endif +{ + return yylloc; +} +#endif /* !YY_NO_GET_LLOC */ + +#ifndef YY_NO_SET_LLOC +#ifdef YY_USE_PROTOS +void yyset_lloc( YYLTYPE * yyllocp YY_LAST_ARG ) +#else +void yyset_lloc( yyllocp YY_LAST_ARG ) + YYLTYPE * yyllocp; + YY_DECL_LAST_ARG +#endif +{ + yylloc = yyllocp; +} +#endif /* !YY_NO_SET_LLOC */ + +#endif /* YYLTYPE */ +#endif /* YY_REENTRANT_BISON_PURE */ + + +#ifdef YY_USE_PROTOS +static int yy_init_globals( yyscan_t yy_globals) +#else +static int yy_init_globals( yy_globals ) + yyscan_t yy_globals; +#endif + { + /* Initialization is the same as for the non-reentrant scanner. + This function is called once per scanner lifetime. */ + + /* We do not touch yylineno unless the option is enabled. */ +#ifdef YY_USE_LINENO + yylineno = 1; +#endif + YY_G(yy_current_buffer) = 0; + YY_G(yy_c_buf_p) = (char *) 0; + YY_G(yy_init) = 1; + YY_G(yy_start) = 0; + YY_G(yy_start_stack_ptr) = 0; + YY_G(yy_start_stack_depth) = 0; + YY_G(yy_start_stack) = (int *) 0; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + return 0; + } + +/* User-visible API */ +#ifdef YY_USE_PROTOS +int yylex_init( yyscan_t* ptr_yy_globals) +#else +int yylex_init( ptr_yy_globals ) + yyscan_t* ptr_yy_globals; +#endif + { + *ptr_yy_globals = (yyscan_t) yy_flex_alloc ( sizeof( struct yy_globals_t ), NULL ); + yy_init_globals ( *ptr_yy_globals ); + return 0; + } + +#ifdef YY_USE_PROTOS +int yylex_destroy( yyscan_t yy_globals ) +#else +int yylex_destroy( yy_globals ) + yyscan_t yy_globals; +#endif + { + if( yy_globals ) + { + + /* Destroy the current (main) buffer. */ + yy_delete_buffer( YY_G(yy_current_buffer) YY_CALL_LAST_ARG ); + YY_G(yy_current_buffer) = NULL; + + /* Destroy the start condition stack. */ + if( YY_G(yy_start_stack) ) { + yy_flex_free( YY_G(yy_start_stack) YY_CALL_LAST_ARG ); + YY_G(yy_start_stack) = NULL; + } + + /* Destroy the main struct. */ + yy_flex_free ( yy_globals YY_CALL_LAST_ARG ); + } + return 0; + } + +#endif /* End YY_REENTRANT */ + /* Internal utility routines. */ #ifndef yytext_ptr #ifdef YY_USE_PROTOS -static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n YY_LAST_ARG) #else -static void yy_flex_strncpy( s1, s2, n ) +static void yy_flex_strncpy( s1, s2, n YY_LAST_ARG) char *s1; yyconst char *s2; int n; +YY_DECL_LAST_ARG #endif { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN #ifdef YY_USE_PROTOS -static int yy_flex_strlen( yyconst char *s ) +static int yy_flex_strlen( yyconst char *s YY_LAST_ARG) #else -static int yy_flex_strlen( s ) +static int yy_flex_strlen( s YY_LAST_ARG) yyconst char *s; +YY_DECL_LAST_ARG #endif { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif #ifdef YY_USE_PROTOS -static void *yy_flex_alloc( yy_size_t size ) +static void *yy_flex_alloc( yy_size_t size YY_LAST_ARG ) #else -static void *yy_flex_alloc( size ) +static void *yy_flex_alloc( size YY_LAST_ARG ) yy_size_t size; +YY_DECL_LAST_ARG #endif { return (void *) malloc( size ); } #ifdef YY_USE_PROTOS -static void *yy_flex_realloc( void *ptr, yy_size_t size ) +static void *yy_flex_realloc( void *ptr, yy_size_t size YY_LAST_ARG ) #else -static void *yy_flex_realloc( ptr, size ) +static void *yy_flex_realloc( ptr, size YY_LAST_ARG ) void *ptr; yy_size_t size; +YY_DECL_LAST_ARG #endif { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } #ifdef YY_USE_PROTOS -static void yy_flex_free( void *ptr ) +static void yy_flex_free( void *ptr YY_LAST_ARG ) #else -static void yy_flex_free( ptr ) +static void yy_flex_free( ptr YY_LAST_ARG ) void *ptr; +YY_DECL_LAST_ARG #endif { - free( ptr ); + free( (char *) ptr ); /* see yy_flex_realloc() for (char *) cast */ } #if YY_MAIN int main() { + +#ifdef YY_REENTRANT + yyscan_t lexer; + yylex_init(&lexer); + yylex( lexer ); + yylex_destroy( lexer); + +#else yylex(); +#endif + return 0; } #endif -#line 107 "icalsslexer.l" +/* %e */ +#endif /* !ssIN_HEADER */ +#line 111 "icalsslexer.l" +#ifndef ssIN_HEADER -int sswrap() +int yywrap(yyscan_t yy_globals) { return 1; } +#endif /* !ssIN_HEADER */ diff --git a/libical/src/libicalss/icalssyacc.c b/libical/src/libicalss/icalssyacc.c index 943123e..3d8cdc1 100644 --- a/libical/src/libicalss/icalssyacc.c +++ b/libical/src/libicalss/icalssyacc.c @@ -1,1381 +1,1399 @@ /* A Bison parser, made from icalssyacc.y - by GNU bison 1.35. */ + by GNU bison 1.34. */ #define YYBISON 1 /* Identify Bison output. */ #define yyparse ssparse #define yylex sslex #define yyerror sserror #define yylval sslval #define yychar sschar #define yydebug ssdebug #define yynerrs ssnerrs # define STRING 257 # define SELECT 258 # define FROM 259 # define WHERE 260 # define COMMA 261 # define QUOTE 262 # define EQUALS 263 # define NOTEQUALS 264 # define LESS 265 # define GREATER 266 # define LESSEQUALS 267 # define GREATEREQUALS 268 # define AND 269 # define OR 270 # define EOL 271 # define END 272 +# define IS 273 +# define NOT 274 +# define SQLNULL 275 -#line 1 "icalssyacc.y" +#line 3 "icalssyacc.y" /* -*- Mode: C -*- ====================================================================== FILE: icalssyacc.y CREATOR: eric 08 Aug 2000 DESCRIPTION: $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 ======================================================================*/ - +/*#define YYDEBUG 1*/ #include <stdlib.h> #include <string.h> /* for strdup() */ #include <limits.h> /* for SHRT_MAX*/ #include "ical.h" -#include "pvl.h" #include "icalgauge.h" #include "icalgaugeimpl.h" -extern struct icalgauge_impl *icalss_yy_gauge; - -void ssyacc_add_where(struct icalgauge_impl* impl, char* prop, - icalgaugecompare compare , char* value); -void ssyacc_add_select(struct icalgauge_impl* impl, char* str1); -void ssyacc_add_from(struct icalgauge_impl* impl, char* str1); -void set_logic(struct icalgauge_impl* impl,icalgaugelogic l); -void sserror(char *s); /* Don't know why I need this.... */ +#define YYPARSE_PARAM yy_globals +#define YYLEX_PARAM yy_globals +#define YY_EXTRA_TYPE icalgauge_impl* + /* ick...*/ +#define yyextra ((struct icalgauge_impl*)ssget_extra(yy_globals)) +static void ssyacc_add_where(struct icalgauge_impl* impl, char* prop, + icalgaugecompare compare , char* value); +static void ssyacc_add_select(struct icalgauge_impl* impl, char* str1); +static void ssyacc_add_from(struct icalgauge_impl* impl, char* str1); +static void set_logic(struct icalgauge_impl* impl,icalgaugelogic l); +void sserror(char *s); /* Don't know why I need this.... */ -#line 52 "icalssyacc.y" +#line 56 "icalssyacc.y" #ifndef YYSTYPE typedef union { char* v_string; } yystype; # define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 #endif #ifndef YYDEBUG # define YYDEBUG 0 #endif -#define YYFINAL 34 +#define YYFINAL 38 #define YYFLAG -32768 -#define YYNTBASE 19 +#define YYNTBASE 22 /* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ -#define YYTRANSLATE(x) ((unsigned)(x) <= 272 ? yytranslate[x] : 24) +#define YYTRANSLATE(x) ((unsigned)(x) <= 275 ? yytranslate[x] : 27) /* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ static const char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18 + 16, 17, 18, 19, 20, 21 }; #if YYDEBUG static const short yyprhs[] = { - 0, 0, 7, 9, 11, 15, 17, 21, 22, 26, - 30, 34, 38, 42, 46, 48, 52 + 0, 0, 7, 12, 14, 16, 20, 22, 26, 27, + 31, 35, 40, 44, 48, 52, 56, 60, 62, 66 }; static const short yyrhs[] = { - 4, 20, 5, 21, 6, 23, 0, 1, 0, 3, - 0, 20, 7, 3, 0, 3, 0, 21, 7, 3, - 0, 0, 3, 9, 3, 0, 3, 10, 3, 0, - 3, 11, 3, 0, 3, 12, 3, 0, 3, 13, - 3, 0, 3, 14, 3, 0, 22, 0, 23, 15, - 22, 0, 23, 16, 22, 0 + 4, 23, 5, 24, 6, 26, 0, 4, 23, 5, + 24, 0, 1, 0, 3, 0, 23, 7, 3, 0, + 3, 0, 24, 7, 3, 0, 0, 3, 9, 3, + 0, 3, 19, 21, 0, 3, 19, 20, 21, 0, + 3, 10, 3, 0, 3, 11, 3, 0, 3, 12, + 3, 0, 3, 13, 3, 0, 3, 14, 3, 0, + 25, 0, 26, 15, 25, 0, 26, 16, 25, 0 }; #endif #if YYDEBUG /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const short yyrline[] = { - 0, 63, 64, 70, 72, 76, 78, 81, 83, 85, - 86, 87, 88, 89, 92, 94, 95 + 0, 67, 68, 69, 75, 77, 81, 83, 86, 88, + 89, 90, 91, 92, 93, 94, 95, 98, 100, 101 }; #endif #if (YYDEBUG) || defined YYERROR_VERBOSE /* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ static const char *const yytname[] = { "$", "error", "$undefined.", "STRING", "SELECT", "FROM", "WHERE", "COMMA", "QUOTE", "EQUALS", "NOTEQUALS", "LESS", "GREATER", "LESSEQUALS", - "GREATEREQUALS", "AND", "OR", "EOL", "END", "query_min", "select_list", - "from_list", "where_clause", "where_list", 0 + "GREATEREQUALS", "AND", "OR", "EOL", "END", "IS", "NOT", "SQLNULL", + "query_min", "select_list", "from_list", "where_clause", "where_list", 0 }; #endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const short yyr1[] = { - 0, 19, 19, 20, 20, 21, 21, 22, 22, 22, - 22, 22, 22, 22, 23, 23, 23 + 0, 22, 22, 22, 23, 23, 24, 24, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 26, 26, 26 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const short yyr2[] = { - 0, 6, 1, 1, 3, 1, 3, 0, 3, 3, - 3, 3, 3, 3, 1, 3, 3 + 0, 6, 4, 1, 1, 3, 1, 3, 0, 3, + 3, 4, 3, 3, 3, 3, 3, 1, 3, 3 }; /* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const short yydefact[] = { - 0, 2, 0, 3, 0, 0, 0, 5, 0, 4, - 7, 0, 0, 14, 1, 6, 0, 0, 0, 0, - 0, 0, 7, 7, 8, 9, 10, 11, 12, 13, - 15, 16, 0, 0, 0 + 0, 3, 0, 4, 0, 0, 0, 6, 2, 5, + 8, 0, 0, 17, 1, 7, 0, 0, 0, 0, + 0, 0, 0, 8, 8, 9, 12, 13, 14, 15, + 16, 0, 10, 18, 19, 11, 0, 0, 0 }; static const short yydefgoto[] = { - 32, 4, 8, 13, 14 + 36, 4, 8, 13, 14 }; static const short yypact[] = { - 5,-32768, 4,-32768, 3, 8, 15,-32768, 6,-32768, - 16, 17, -9,-32768, -1,-32768, 18, 19, 20, 21, - 22, 23, 16, 16,-32768,-32768,-32768,-32768,-32768,-32768, - -32768,-32768, 27, 28,-32768 + 5,-32768, 9,-32768, 6, 17, 18,-32768, 1,-32768, + 19, 20, -9,-32768, -1,-32768, 21, 22, 23, 24, + 25, 26, -4, 19, 19,-32768,-32768,-32768,-32768,-32768, + -32768, 10,-32768,-32768,-32768,-32768, 30, 32,-32768 }; static const short yypgoto[] = { - -32768,-32768,-32768, -6,-32768 + -32768,-32768,-32768, -5,-32768 }; -#define YYLAST 28 +#define YYLAST 32 static const short yytable[] = { - 16, 17, 18, 19, 20, 21, 1, 3, 5, 2, - 6, 7, 10, 11, 22, 23, 30, 31, 9, 12, - 15, 24, 25, 26, 27, 28, 29, 33, 34 + 16, 17, 18, 19, 20, 21, 1, 10, 11, 2, + 22, 5, 3, 6, 23, 24, 31, 32, 33, 34, + 7, 9, 12, 15, 25, 26, 27, 28, 29, 30, + 37, 35, 38 }; static const short yycheck[] = { - 9, 10, 11, 12, 13, 14, 1, 3, 5, 4, - 7, 3, 6, 7, 15, 16, 22, 23, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 0, 0 + 9, 10, 11, 12, 13, 14, 1, 6, 7, 4, + 19, 5, 3, 7, 15, 16, 20, 21, 23, 24, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 0, 21, 0 }; +#define YYPURE 1 + /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison/bison.simple" +#line 3 "/usr/local/share/bison/bison.simple" /* Skeleton output parser for bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* This is the parser code that is written into each bison parser when the %semantic_parser declaration is not specified in the grammar. It was written by Richard Stallman by simplifying the hairy parser used when %semantic_parser is specified. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ #if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) /* The parser invokes alloca or malloc; define the necessary symbols. */ # if YYSTACK_USE_ALLOCA # define YYSTACK_ALLOC alloca # else # ifndef YYSTACK_USE_ALLOCA # if defined (alloca) || defined (_ALLOCA_H) # define YYSTACK_ALLOC alloca # else # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # else # if defined (__STDC__) || defined (__cplusplus) # include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif # define YYSTACK_ALLOC malloc # define YYSTACK_FREE free # endif -#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { short yyss; YYSTYPE yyvs; # if YYLSP_NEEDED YYLTYPE yyls; # endif }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # if YYLSP_NEEDED # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + 2 * YYSTACK_GAP_MAX) # else # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAX) # endif -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The +/* Relocate the TYPE STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack) \ +# define YYSTACK_RELOCATE(Type, Stack) \ do \ { \ YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ + yymemcpy ((char *) yyptr, (char *) (Stack), \ + yysize * (YYSIZE_T) sizeof (Type)); \ Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ + yynewbytes = yystacksize * sizeof (Type) + YYSTACK_GAP_MAX; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) -#endif +#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif #if ! defined (YYSIZE_T) && defined (size_t) # define YYSIZE_T size_t #endif #if ! defined (YYSIZE_T) # if defined (__STDC__) || defined (__cplusplus) # include <stddef.h> /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif #endif #if ! defined (YYSIZE_T) # define YYSIZE_T unsigned int #endif #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { \ yyerror ("syntax error: cannot back up"); \ YYERROR; \ } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). When YYLLOC_DEFAULT is run, CURRENT is set the location of the first token. By default, to implement support for ranges, extend its range to the last symbol. */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ Current.last_line = Rhs[N].last_line; \ Current.last_column = Rhs[N].last_column; #endif /* YYLEX -- calling `yylex' with the right arguments. */ #if YYPURE # if YYLSP_NEEDED # ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) # else # define YYLEX yylex (&yylval, &yylloc) # endif # else /* !YYLSP_NEEDED */ # ifdef YYLEX_PARAM # define YYLEX yylex (&yylval, YYLEX_PARAM) # else # define YYLEX yylex (&yylval) # endif # endif /* !YYLSP_NEEDED */ #else /* !YYPURE */ # define YYLEX yylex () #endif /* !YYPURE */ /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include <stdio.h> /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 # undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif +#if ! defined (yyoverflow) && ! defined (yymemcpy) +# if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ +# define yymemcpy __builtin_memcpy +# else /* not GNU C or C++ */ + +/* This is the most reliable way to avoid incompatibilities + in available built-in functions on various systems. */ +static void +# if defined (__STDC__) || defined (__cplusplus) +yymemcpy (char *yyto, const char *yyfrom, YYSIZE_T yycount) +# else +yymemcpy (yyto, yyfrom, yycount) + char *yyto; + const char *yyfrom; + YYSIZE_T yycount; +# endif +{ + register const char *yyf = yyfrom; + register char *yyt = yyto; + register YYSIZE_T yyi = yycount; + + while (yyi-- != 0) + *yyt++ = *yyf++; +} +# endif +#endif + #ifdef YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T # if defined (__STDC__) || defined (__cplusplus) yystrlen (const char *yystr) # else yystrlen (yystr) const char *yystr; # endif { register const char *yys = yystr; while (*yys++ != '\0') continue; return yys - yystr - 1; } # endif # endif # ifndef yystpcpy # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * # if defined (__STDC__) || defined (__cplusplus) yystpcpy (char *yydest, const char *yysrc) # else yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; # endif { register char *yyd = yydest; register const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif #endif -#line 315 "/usr/share/bison/bison.simple" +#line 319 "/usr/local/share/bison/bison.simple" /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) # define YYPARSE_PARAM_ARG void *YYPARSE_PARAM # define YYPARSE_PARAM_DECL # else # define YYPARSE_PARAM_ARG YYPARSE_PARAM # define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; # endif #else /* !YYPARSE_PARAM */ # define YYPARSE_PARAM_ARG # define YYPARSE_PARAM_DECL #endif /* !YYPARSE_PARAM */ /* Prevent warning if -Wstrict-prototypes. */ #ifdef __GNUC__ # ifdef YYPARSE_PARAM int yyparse (void *); # else int yyparse (void); # endif #endif /* YY_DECL_VARIABLES -- depending whether we use a pure parser, variables are global, or local to YYPARSE. */ #define YY_DECL_NON_LSP_VARIABLES \ /* The lookahead symbol. */ \ int yychar; \ \ /* The semantic value of the lookahead symbol. */ \ YYSTYPE yylval; \ \ /* Number of parse errors so far. */ \ int yynerrs; #if YYLSP_NEEDED # define YY_DECL_VARIABLES \ YY_DECL_NON_LSP_VARIABLES \ \ /* Location data for the lookahead symbol. */ \ YYLTYPE yylloc; #else # define YY_DECL_VARIABLES \ YY_DECL_NON_LSP_VARIABLES #endif /* If nonreentrant, generate the variables here. */ #if !YYPURE YY_DECL_VARIABLES #endif /* !YYPURE */ int yyparse (YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { /* If reentrant, generate the variables here. */ #if YYPURE YY_DECL_VARIABLES #endif /* !YYPURE */ register int yystate; register int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Lookahead token as an internal (translated) token number. */ int yychar1 = 0; /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; #if YYLSP_NEEDED /* The location stack. */ YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; #endif #if YYLSP_NEEDED # define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else # define YYPOPSTACK (yyvsp--, yyssp--) #endif YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; #if YYLSP_NEEDED YYLTYPE yyloc; #endif /* When reducing, the number of symbols on the RHS of the reduced rule. */ int yylen; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; #if YYLSP_NEEDED yylsp = yyls; #endif goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyssp >= yyss + yystacksize - 1) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. */ # if YYLSP_NEEDED YYLTYPE *yyls1 = yyls; /* This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yyls1, yysize * sizeof (*yylsp), &yystacksize); yyls = yyls1; # else yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); # endif yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) goto yyoverflowlab; yystacksize *= 2; if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; { short *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); + YYSTACK_RELOCATE (short, yyss); + YYSTACK_RELOCATE (YYSTYPE, yyvs); # if YYLSP_NEEDED - YYSTACK_RELOCATE (yyls); + YYSTACK_RELOCATE (YYLTYPE, yyls); # endif # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } -# endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; #if YYLSP_NEEDED yylsp = yyls + yysize - 1; #endif YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyssp >= yyss + yystacksize - 1) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* yychar is either YYEMPTY or YYEOF or a valid token in external form. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } /* Convert token to internal form (in yychar1) for indexing tables with */ if (yychar <= 0) /* This means end of input. */ { yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yychar1 = YYTRANSLATE (yychar); #if YYDEBUG /* We have to keep this `#if YYDEBUG', since we use variables which are defined only if `YYDEBUG' is set. */ if (yydebug) { YYFPRINTF (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); /* Give the individual parser a way to print the precise meaning of a token, for further debugging info. */ # ifdef YYPRINT YYPRINT (stderr, yychar, yylval); # endif YYFPRINTF (stderr, ")\n"); } #endif } yyn += yychar1; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; yyn = yytable[yyn]; /* yyn is what to do for this token type in this state. Negative => reduce, -yyn is rule number. Positive => shift, yyn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (yyn < 0) { if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ YYDPRINTF ((stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; #if YYLSP_NEEDED *++yylsp = yylloc; #endif /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to the semantic value of the lookahead token. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; #if YYLSP_NEEDED /* Similarly for the default location. Let the user run additional commands if for instance locations are ranges. */ yyloc = yylsp[1-yylen]; YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); #endif #if YYDEBUG /* We have to keep this `#if YYDEBUG', since we use variables which are defined only if `YYDEBUG' is set. */ if (yydebug) { int yyi; YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); } #endif switch (yyn) { -case 2: -#line 64 "icalssyacc.y" +case 3: +#line 69 "icalssyacc.y" { - icalparser_clear_flex_input(); yyclearin; + YYABORT; } break; -case 3: -#line 71 "icalssyacc.y" -{ssyacc_add_select(icalss_yy_gauge,yyvsp[0].v_string);} - break; case 4: -#line 72 "icalssyacc.y" -{ssyacc_add_select(icalss_yy_gauge,yyvsp[0].v_string);} +#line 76 "icalssyacc.y" +{ssyacc_add_select(yyextra,yyvsp[0].v_string);} break; case 5: #line 77 "icalssyacc.y" -{ssyacc_add_from(icalss_yy_gauge,yyvsp[0].v_string);} +{ssyacc_add_select(yyextra,yyvsp[0].v_string);} break; case 6: -#line 78 "icalssyacc.y" -{ssyacc_add_from(icalss_yy_gauge,yyvsp[0].v_string);} +#line 82 "icalssyacc.y" +{ssyacc_add_from(yyextra,yyvsp[0].v_string);} break; -case 8: +case 7: #line 83 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_EQUAL,yyvsp[0].v_string); } +{ssyacc_add_from(yyextra,yyvsp[0].v_string);} break; case 9: -#line 85 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_NOTEQUAL,yyvsp[0].v_string); } +#line 88 "icalssyacc.y" +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_EQUAL,yyvsp[0].v_string); } break; case 10: -#line 86 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_LESS,yyvsp[0].v_string); } +#line 89 "icalssyacc.y" +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_ISNULL,""); } break; case 11: -#line 87 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_GREATER,yyvsp[0].v_string); } +#line 90 "icalssyacc.y" +{ssyacc_add_where(yyextra,yyvsp[-3].v_string,ICALGAUGECOMPARE_ISNOTNULL,""); } break; case 12: -#line 88 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_LESSEQUAL,yyvsp[0].v_string); } +#line 91 "icalssyacc.y" +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_NOTEQUAL,yyvsp[0].v_string); } break; case 13: -#line 89 "icalssyacc.y" -{ssyacc_add_where(icalss_yy_gauge,yyvsp[-2].v_string,ICALGAUGECOMPARE_GREATEREQUAL,yyvsp[0].v_string); } +#line 92 "icalssyacc.y" +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_LESS,yyvsp[0].v_string); } break; case 14: #line 93 "icalssyacc.y" -{set_logic(icalss_yy_gauge,ICALGAUGELOGIC_NONE);} +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_GREATER,yyvsp[0].v_string); } break; case 15: #line 94 "icalssyacc.y" -{set_logic(icalss_yy_gauge,ICALGAUGELOGIC_AND);} +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_LESSEQUAL,yyvsp[0].v_string); } break; case 16: #line 95 "icalssyacc.y" -{set_logic(icalss_yy_gauge,ICALGAUGELOGIC_OR);} +{ssyacc_add_where(yyextra,yyvsp[-2].v_string,ICALGAUGECOMPARE_GREATEREQUAL,yyvsp[0].v_string); } + break; +case 17: +#line 99 "icalssyacc.y" +{set_logic(yyextra,ICALGAUGELOGIC_NONE);} + break; +case 18: +#line 100 "icalssyacc.y" +{set_logic(yyextra,ICALGAUGELOGIC_AND);} + break; +case 19: +#line 101 "icalssyacc.y" +{set_logic(yyextra,ICALGAUGELOGIC_OR);} break; } -#line 705 "/usr/share/bison/bison.simple" +#line 705 "/usr/local/share/bison/bison.simple" yyvsp -= yylen; yyssp -= yylen; #if YYLSP_NEEDED yylsp -= yylen; #endif #if YYDEBUG if (yydebug) { short *yyssp1 = yyss - 1; YYFPRINTF (stderr, "state stack now"); while (yyssp1 != yyssp) YYFPRINTF (stderr, " %d", *++yyssp1); YYFPRINTF (stderr, "\n"); } #endif *++yyvsp = yyval; #if YYLSP_NEEDED *++yylsp = yyloc; #endif /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTBASE] + *yyssp; if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) { YYSIZE_T yysize = 0; char *yymsg; int yyx, yycount; yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx) yysize += yystrlen (yytname[yyx]) + 15, yycount++; yysize += yystrlen ("parse error, unexpected ") + 1; yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); yymsg = (char *) YYSTACK_ALLOC (yysize); if (yymsg != 0) { char *yyp = yystpcpy (yymsg, "parse error, unexpected "); yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); if (yycount < 5) { yycount = 0; for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx) { const char *yyq = ! yycount ? ", expecting " : " or "; yyp = yystpcpy (yyp, yyq); yyp = yystpcpy (yyp, yytname[yyx]); yycount++; } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else yyerror ("parse error; also virtual memory exhausted"); } else #endif /* defined (YYERROR_VERBOSE) */ yyerror ("parse error"); } goto yyerrlab1; /*--------------------------------------------------. | yyerrlab1 -- error raised explicitly by an action | `--------------------------------------------------*/ yyerrlab1: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) YYABORT; YYDPRINTF ((stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1])); yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ yyerrstatus = 3; /* Each real token shifted decrements this */ goto yyerrhandle; /*-------------------------------------------------------------------. | yyerrdefault -- current state does not do anything special for the | | error token. | `-------------------------------------------------------------------*/ yyerrdefault: #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ /* If its default is to accept any token, ok. Otherwise pop it. */ yyn = yydefact[yystate]; if (yyn) goto yydefault; #endif /*---------------------------------------------------------------. | yyerrpop -- pop the current state because it cannot handle the | | error token | `---------------------------------------------------------------*/ yyerrpop: if (yyssp == yyss) YYABORT; yyvsp--; yystate = *--yyssp; #if YYLSP_NEEDED yylsp--; #endif #if YYDEBUG if (yydebug) { short *yyssp1 = yyss - 1; YYFPRINTF (stderr, "Error: state stack now"); while (yyssp1 != yyssp) YYFPRINTF (stderr, " %d", *++yyssp1); YYFPRINTF (stderr, "\n"); } #endif /*--------------. | yyerrhandle. | `--------------*/ yyerrhandle: yyn = yypact[yystate]; if (yyn == YYFLAG) goto yyerrdefault; yyn += YYTERROR; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) goto yyerrdefault; yyn = yytable[yyn]; if (yyn < 0) { if (yyn == YYFLAG) goto yyerrpop; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; #if YYLSP_NEEDED *++yylsp = yylloc; #endif yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; /*---------------------------------------------. | yyoverflowab -- parser overflow comes here. | `---------------------------------------------*/ yyoverflowlab: yyerror ("parser stack overflow"); yyresult = 2; /* Fall through. */ yyreturn: #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif return yyresult; } -#line 99 "icalssyacc.y" +#line 105 "icalssyacc.y" -void ssyacc_add_where(struct icalgauge_impl* impl, char* str1, +static void ssyacc_add_where(struct icalgauge_impl* impl, char* str1, icalgaugecompare compare , char* value_str) { struct icalgauge_where *where; char *compstr, *propstr, *c, *s,*l; if ( (where = malloc(sizeof(struct icalgauge_where))) ==0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return; } memset(where,0,sizeof(struct icalgauge_where)); where->logic = ICALGAUGELOGIC_NONE; where->compare = ICALGAUGECOMPARE_NONE; where->comp = ICAL_NO_COMPONENT; where->prop = ICAL_NO_PROPERTY; /* remove enclosing quotes */ s = value_str; if(*s == '\''){ s++; } l = s+strlen(s)-1; if(*l == '\''){ *l=0; } where->value = strdup(s); /* Is there a period in str1 ? If so, the string specified both a component and a property*/ if( (c = strrchr(str1,'.')) != 0){ compstr = str1; propstr = c+1; *c = '\0'; } else { compstr = 0; propstr = str1; } /* Handle the case where a component was specified */ if(compstr != 0){ where->comp = icalenum_string_to_component_kind(compstr); } else { where->comp = ICAL_NO_COMPONENT; } where->prop = icalenum_string_to_property_kind(propstr); where->compare = compare; if(where->value == 0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); free(where->value); return; } pvl_push(impl->where,where); } -void set_logic(struct icalgauge_impl* impl,icalgaugelogic l) +static void set_logic(struct icalgauge_impl* impl,icalgaugelogic l) { pvl_elem e = pvl_tail(impl->where); struct icalgauge_where *where = pvl_data(e); where->logic = l; } -void ssyacc_add_select(struct icalgauge_impl* impl, char* str1) +static void ssyacc_add_select(struct icalgauge_impl* impl, char* str1) { char *c, *compstr, *propstr; struct icalgauge_where *where; /* Uses only the prop and comp fields of the where structure */ if ( (where = malloc(sizeof(struct icalgauge_where))) ==0){ icalerror_set_errno(ICAL_NEWFAILED_ERROR); return; } memset(where,0,sizeof(struct icalgauge_where)); where->logic = ICALGAUGELOGIC_NONE; where->compare = ICALGAUGECOMPARE_NONE; where->comp = ICAL_NO_COMPONENT; where->prop = ICAL_NO_PROPERTY; /* Is there a period in str1 ? If so, the string specified both a component and a property*/ if( (c = strrchr(str1,'.')) != 0){ compstr = str1; propstr = c+1; *c = '\0'; } else { compstr = 0; propstr = str1; } /* Handle the case where a component was specified */ if(compstr != 0){ where->comp = icalenum_string_to_component_kind(compstr); } else { where->comp = ICAL_NO_COMPONENT; } /* If the property was '*', then accept all properties */ if(strcmp("*",propstr) == 0) { where->prop = ICAL_ANY_PROPERTY; } else { where->prop = icalenum_string_to_property_kind(propstr); } if(where->prop == ICAL_NO_PROPERTY){ - icalgauge_free(where); - icalerror_set_errno(ICAL_BADARG_ERROR); - return; + free(where); + icalerror_set_errno(ICAL_BADARG_ERROR); + return; } pvl_push(impl->select,where); } -void ssyacc_add_from(struct icalgauge_impl* impl, char* str1) +static void ssyacc_add_from(struct icalgauge_impl* impl, char* str1) { icalcomponent_kind ckind; ckind = icalenum_string_to_component_kind(str1); if(ckind == ICAL_NO_COMPONENT){ assert(0); } pvl_push(impl->from,(void*)ckind); } void sserror(char *s){ - fprintf(stderr,"Parse error \'%s\'\n", s); + fprintf(stderr,"Parse error \'%s\'\n", s); + icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); } diff --git a/libical/src/libicalss/icalssyacc.h b/libical/src/libicalss/icalssyacc.h index 7d42f3c..6d03a0f 100644 --- a/libical/src/libicalss/icalssyacc.h +++ b/libical/src/libicalss/icalssyacc.h @@ -1,31 +1,31 @@ -#ifndef BISON_ICALSSYACC_H -# define BISON_ICALSSYACC_H +#ifndef BISON_Y_TAB_H +# define BISON_Y_TAB_H #ifndef YYSTYPE typedef union { char* v_string; } yystype; # define YYSTYPE yystype -# define YYSTYPE_IS_TRIVIAL 1 #endif # define STRING 257 # define SELECT 258 # define FROM 259 # define WHERE 260 # define COMMA 261 # define QUOTE 262 # define EQUALS 263 # define NOTEQUALS 264 # define LESS 265 # define GREATER 266 # define LESSEQUALS 267 # define GREATEREQUALS 268 # define AND 269 # define OR 270 # define EOL 271 # define END 272 +# define IS 273 +# define NOT 274 +# define SQLNULL 275 -extern YYSTYPE sslval; - -#endif /* not BISON_ICALSSYACC_H */ +#endif /* not BISON_Y_TAB_H */ diff --git a/libical/src/libicalss/libicalss.pro b/libical/src/libicalss/libicalss.pro index a5cc80c..64b7094 100644 --- a/libical/src/libicalss/libicalss.pro +++ b/libical/src/libicalss/libicalss.pro @@ -1,43 +1,43 @@ -include(../../../variables.pri) +###################################################################### +# Automatically generated by qmake (1.07a) Sun Jun 27 23:03:36 2004 +###################################################################### + TEMPLATE = lib TARGET = icalss DESTDIR = ../../lib CONFIG += staticlib -win32: DEFINES += _WIN32 _QTWIN_ -HEADERS = icalcalendar.h \ - icalclassify.h \ - icalcstp.h \ - icalcstpclient.h \ - icalcstpserver.h \ - icaldirset.h \ - icaldirsetimpl.h \ - icalfileset.h \ - icalfilesetimpl.h \ - icalgauge.h \ - icalgaugeimpl.h \ - icalmessage.h \ - icalset.h \ - icalspanlist.h \ - icalssyacc.h \ - config.h - -SOURCES = icalclassify.c \ - icalcstp.c \ - icalcstpclient.c \ - icalcstpserver.c \ - icaldirset.c \ - icalfileset.c \ - icalgauge.c \ - icalmessage.c \ - icalset.c \ - icalspanlist.c \ - icalsslexer.c \ - icalssyacc.c - -INTERFACES = -INCLUDEPATH += ../libical +INCLUDEPATH += . ../libical +# Input +win32 { +DEFINES += YY_NO_UNISTD_H -DEFINES += HAVE_CONFIG_H +} +HEADERS += icalcalendar.h \ + icalclassify.h \ + icalcluster.h \ + icalclusterimpl.h \ + icaldirset.h \ + icaldirsetimpl.h \ + icalfileset.h \ + icalfilesetimpl.h \ + icalgauge.h \ + icalgaugeimpl.h \ + icalmessage.h \ + icalset.h \ + icalspanlist.h \ + icalss.h \ + icalssyacc.h +SOURCES += icalcalendar.c \ + icalclassify.c \ + icalcluster.c \ + icaldirset.c \ + icalfileset.c \ + icalgauge.c \ + icalmessage.c \ + icalset.c \ + icalspanlist.c \ + icalsslexer.c \ + icalssyacc.c diff --git a/libical/src/libicalss/libicalssE.pro b/libical/src/libicalss/libicalssE.pro index 57d60bd..84ccf47 100644 --- a/libical/src/libicalss/libicalssE.pro +++ b/libical/src/libicalss/libicalssE.pro @@ -1,45 +1,41 @@ -TEMPLATE = lib -CONFIG += warn_on staticlib -INCLUDEPATH += ../libical -INCLUDEPATH += . -DEFINES += HAVE_CONFIG_H -OBJECTS_DIR = obj/$(PLATFORM) -MOC_DIR = moc/$(PLATFORM) -DESTDIR=../../lib/$(PLATFORM) -TARGET = icalss +###################################################################### +# Automatically generated by qmake (1.07a) Sun Jun 27 23:03:36 2004 +###################################################################### -INTERFACES = \ -HEADERS = \ - config.h \ - icalcalendar.h \ - icalclassify.h \ - icalcstp.h \ - icalcstpclient.h \ - icalcstpserver.h \ - icaldirset.h \ - icaldirsetimpl.h \ - icalfileset.h \ - icalfilesetimpl.h \ - icalgauge.h \ - icalgaugeimpl.h \ - icalmessage.h \ - icalset.h \ - icalspanlist.h \ - icalss.h \ - icalssyacc.h \ +TEMPLATE = lib -SOURCES = \ - icalclassify.c \ - icalcstp.c \ - icalcstpclient.c \ - icalcstpserver.c \ - icaldirset.c \ - icalfileset.c \ - icalgauge.c \ - icalmessage.c \ - icalset.c \ - icalspanlist.c \ - icalsslexer.c \ - icalssyacc.c \ +TARGET = icalss +CONFIG += staticlib +OBJECTS_DIR = obj/$(PLATFORM) +MOC_DIR = moc/$(PLATFORM) +DESTDIR=../../lib/$(PLATFORM) +INCLUDEPATH += . ../libical +# Input +HEADERS += icalcalendar.h \ + icalclassify.h \ + icalcluster.h \ + icalclusterimpl.h \ + icaldirset.h \ + icaldirsetimpl.h \ + icalfileset.h \ + icalfilesetimpl.h \ + icalgauge.h \ + icalgaugeimpl.h \ + icalmessage.h \ + icalset.h \ + icalspanlist.h \ + icalss.h \ + icalssyacc.h +SOURCES += icalcalendar.c \ + icalclassify.c \ + icalcluster.c \ + icaldirset.c \ + icalfileset.c \ + icalgauge.c \ + icalmessage.c \ + icalset.c \ + icalspanlist.c \ + icalsslexer.c \ + icalssyacc.c diff --git a/libkcal/calendar.h b/libkcal/calendar.h index 7a85e74..7d23619 100644 --- a/libkcal/calendar.h +++ b/libkcal/calendar.h @@ -1,349 +1,350 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef CALENDAR_H #define CALENDAR_H #include <qobject.h> #include <qstring.h> #include <qdatetime.h> #include <qptrlist.h> #include <qdict.h> #include "customproperties.h" #include "event.h" #include "todo.h" #include "journal.h" #define _TIME_ZONE "-0500" /* hardcoded, overridden in config file. */ class KConfig; namespace KCal { class CalFilter; /** This is the main "calendar" object class for KOrganizer. It holds information like all appointments/events, user information, etc. etc. one calendar is associated with each CalendarView (@see calendarview.h). This is an abstract base class defining the interface to a calendar. It is implemented by subclasses like @see CalendarLocal, which use different methods to store and access the data. Ownership of events etc. is handled by the following policy: As soon as an event (or any other subclass of IncidenceBase) object is added to the Calendar by addEvent() it is owned by the Calendar object. The Calendar takes care of deleting it. All Events returned by the query functions are returned as pointers, that means all changes to the returned events are immediately visible in the Calendar. You shouldn't delete any Event object you get from Calendar. */ class Calendar : public QObject, public CustomProperties, public IncidenceBase::Observer { Q_OBJECT public: Calendar(); Calendar(const QString &timeZoneId); virtual ~Calendar(); void deleteIncidence(Incidence *in); /** Clears out the current calendar, freeing all used memory etc. */ virtual void close() = 0; /** Sync changes in memory to persistant storage. */ virtual void save() = 0; virtual bool isSaving() { return false; } /** Return the owner of the calendar's full name. */ const QString &getOwner() const; /** Set the owner of the calendar. Should be owner's full name. */ void setOwner( const QString &os ); /** Return the email address of the calendar owner. */ const QString &getEmail(); /** Set the email address of the calendar owner. */ void setEmail( const QString & ); /** Set time zone from a timezone string (e.g. -2:00) */ void setTimeZone( const QString &tz ); /** Set time zone from a minutes value (e.g. -60) */ void setTimeZone( int tz ); /** Return time zone as offest in minutes. */ int getTimeZone() const; /** Compute an ISO 8601 format string from the time zone. */ QString getTimeZoneStr() const; /** Set time zone id (see /usr/share/zoneinfo/zone.tab for list of legal values). */ void setTimeZoneId( const QString & ); /** Return time zone id. */ QString timeZoneId() const; /** Use local time, not UTC or a time zone. */ void setLocalTime(); /** Return whether local time is being used. */ bool isLocalTime() const; /** Add an incidence to calendar. @return true on success, false on error. */ virtual bool addIncidence( Incidence * ); /** Return filtered list of all incidences of this calendar. */ virtual QPtrList<Incidence> incidences(); /** Return unfiltered list of all incidences of this calendar. */ virtual QPtrList<Incidence> rawIncidences(); /** Adds a Event to this calendar object. @param anEvent a pointer to the event to add @return true on success, false on error. */ virtual bool addEventNoDup( Event *event ) = 0; + virtual bool addAnniversaryNoDup( Event *event ) = 0; virtual bool addEvent( Event *anEvent ) = 0; /** Delete event from calendar. */ virtual void deleteEvent( Event * ) = 0; /** Retrieves an event on the basis of the unique string ID. */ virtual Event *event( const QString &UniqueStr ) = 0; virtual Event *event( int ) = 0; /** Builds and then returns a list of all events that match for the date specified. useful for dayView, etc. etc. The calendar filter is applied. */ QPtrList<Event> events( const QDate &date, bool sorted = false); /** Get events, which occur on the given date. The calendar filter is applied. */ QPtrList<Event> events( const QDateTime &qdt ); /** Get events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. The calendar filter is applied. */ QPtrList<Event> events( const QDate &start, const QDate &end, bool inclusive = false); /** Return filtered list of all events in calendar. */ virtual QPtrList<Event> events(); /** Return unfiltered list of all events in calendar. */ virtual QPtrList<Event> rawEvents() = 0; /** Add a todo to the todolist. @return true on success, false on error. */ virtual bool addTodo( Todo *todo ) = 0; virtual bool addTodoNoDup( Todo *todo ) = 0; /** Remove a todo from the todolist. */ virtual void deleteTodo( Todo * ) = 0; virtual void deleteJournal( Journal * ) = 0; /** Return filterd list of todos. */ virtual QPtrList<Todo> todos(); /** Searches todolist for an event with this unique string identifier, returns a pointer or null. */ virtual Todo *todo( const QString &uid ) = 0; virtual Todo *todo( int ) = 0; /** Returns list of todos due on the specified date. */ virtual QPtrList<Todo> todos( const QDate &date ) = 0; /** Return unfiltered list of todos. */ virtual QPtrList<Todo> rawTodos() = 0; /** Add a Journal entry to calendar. @return true on success, false on error. */ virtual bool addJournal( Journal * ) = 0; /** Return Journal for given date. */ virtual Journal *journal( const QDate & ) = 0; /** Return Journal with given UID. */ virtual Journal *journal( const QString &UID ) = 0; /** Return list of all Journal entries. */ virtual QPtrList<Journal> journals() = 0; /** Searches all incidence types for an incidence with this unique string identifier, returns a pointer or null. */ Incidence* incidence( const QString&UID ); /** Setup relations for an incidence. */ virtual void setupRelations( Incidence * ); /** Remove all relations to an incidence */ virtual void removeRelations( Incidence * ); /** Set calendar filter, which filters events for the events() functions. The Filter object is owned by the caller. */ void setFilter( CalFilter * ); /** Return calendar filter. */ CalFilter *filter(); virtual QDateTime nextAlarm( int daysTo ) = 0; virtual QString nextSummary( ) const = 0; virtual void reInitAlarmSettings() = 0; virtual QDateTime nextAlarmEventDateTime() const = 0; virtual void checkAlarmForIncidence( Incidence *, bool ) = 0; /** Return all alarms, which ocur in the given time interval. */ virtual Alarm::List alarms( const QDateTime &from, const QDateTime &to ) = 0; class Observer { public: virtual void calendarModified( bool, Calendar * ) = 0; }; void registerObserver( Observer * ); void setModified( bool ); /** Set product id returned by loadedProductId(). This function is only useful for the calendar loading code. */ void setLoadedProductId( const QString & ); /** Return product id taken from file that has been loaded. Returns QString::null, if no calendar has been loaded. */ QString loadedProductId(); signals: void calendarChanged(); void calendarSaved(); void calendarLoaded(); void addAlarm(const QDateTime &qdt, const QString ¬i ); void removeAlarm(const QDateTime &qdt, const QString ¬i ); protected: /** Get unfiltered events, which occur on the given date. */ virtual QPtrList<Event> rawEventsForDate( const QDateTime &qdt ) = 0; /** Get unfiltered events, which occur on the given date. */ virtual QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false ) = 0; /** Get events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. */ virtual QPtrList<Event> rawEvents( const QDate &start, const QDate &end, bool inclusive = false ) = 0; Incidence *mNextAlarmIncidence; private: void init(); QString mOwner; // who the calendar belongs to QString mOwnerEmail; // email address of the owner int mTimeZone; // timezone OFFSET from GMT (MINUTES) bool mLocalTime; // use local time, not UTC or a time zone CalFilter *mFilter; CalFilter *mDefaultFilter; QString mTimeZoneId; Observer *mObserver; bool mNewObserver; bool mModified; QString mLoadedProductId; // This list is used to put together related todos QDict<Incidence> mOrphans; QDict<Incidence> mOrphanUids; }; } #endif diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp index 8ff8b14..3c572f0 100644 --- a/libkcal/calendarlocal.cpp +++ b/libkcal/calendarlocal.cpp @@ -1,655 +1,686 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <kdebug.h> #include <kconfig.h> #include <kglobal.h> #include <klocale.h> #include "vcaldrag.h" #include "vcalformat.h" #include "icalformat.h" #include "exceptions.h" #include "incidence.h" #include "journal.h" #include "filestorage.h" #include "calfilter.h" #include "calendarlocal.h" // #ifndef DESKTOP_VERSION // #include <qtopia/alarmserver.h> // #endif using namespace KCal; CalendarLocal::CalendarLocal() : Calendar() { init(); } CalendarLocal::CalendarLocal(const QString &timeZoneId) : Calendar(timeZoneId) { init(); } void CalendarLocal::init() { mNextAlarmIncidence = 0; } CalendarLocal::~CalendarLocal() { close(); } bool CalendarLocal::load( const QString &fileName ) { FileStorage storage( this, fileName ); return storage.load(); } bool CalendarLocal::save( const QString &fileName, CalFormat *format ) { FileStorage storage( this, fileName, format ); return storage.save(); } void CalendarLocal::close() { mEventList.setAutoDelete( true ); mTodoList.setAutoDelete( true ); mJournalList.setAutoDelete( false ); mEventList.clear(); mTodoList.clear(); mJournalList.clear(); mEventList.setAutoDelete( false ); mTodoList.setAutoDelete( false ); mJournalList.setAutoDelete( false ); setModified( false ); } + +bool CalendarLocal::addAnniversaryNoDup( Event *event ) +{ + QString cat; + bool isBirthday = true; + if( event->categoriesStr() == i18n( "Anniversary" ) ) { + isBirthday = false; + cat = i18n( "Anniversary" ); + } else if( event->categoriesStr() == i18n( "Birthday" ) ) { + isBirthday = true; + cat = i18n( "Birthday" ); + } else { + qDebug("addAnniversaryNoDup called without fitting category! "); + return false; + } + Event * eve; + for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) { + if ( !(eve->categories().contains( cat ) )) + continue; + // now we have an event with fitting category + if ( eve->dtStart().date() != event->dtStart().date() ) + continue; + // now we have an event with fitting category+date + if ( eve->summary() != event->summary() ) + continue; + // now we have an event with fitting category+date+summary + return false; + } + return addEvent( event ); + +} bool CalendarLocal::addEventNoDup( Event *event ) { Event * eve; for ( eve = mEventList.first(); eve ; eve = mEventList.next() ) { if ( *eve == *event ) { //qDebug("CalendarLocal::Duplicate event found! Not inserted! "); return false; } } return addEvent( event ); } bool CalendarLocal::addEvent( Event *event ) { insertEvent( event ); event->registerObserver( this ); setModified( true ); return true; } void CalendarLocal::deleteEvent( Event *event ) { if ( mEventList.removeRef( event ) ) { setModified( true ); } } Event *CalendarLocal::event( const QString &uid ) { Event *event; for ( event = mEventList.first(); event; event = mEventList.next() ) { if ( event->uid() == uid ) { return event; } } return 0; } bool CalendarLocal::addTodoNoDup( Todo *todo ) { Todo * eve; for ( eve = mTodoList.first(); eve ; eve = mTodoList.next() ) { if ( *eve == *todo ) { //qDebug("duplicate todo found! not inserted! "); return false; } } return addTodo( todo ); } bool CalendarLocal::addTodo( Todo *todo ) { mTodoList.append( todo ); todo->registerObserver( this ); // Set up subtask relations setupRelations( todo ); setModified( true ); return true; } void CalendarLocal::deleteTodo( Todo *todo ) { // Handle orphaned children removeRelations( todo ); if ( mTodoList.removeRef( todo ) ) { setModified( true ); } } QPtrList<Todo> CalendarLocal::rawTodos() { return mTodoList; } Todo *CalendarLocal::todo( int id ) { Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( todo->zaurusId() == id ) return todo; } return 0; } Event *CalendarLocal::event( int id ) { Event *todo; for ( todo = mEventList.first(); todo; todo = mEventList.next() ) { if ( todo->zaurusId() == id ) return todo; } return 0; } Todo *CalendarLocal::todo( const QString &uid ) { Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( todo->uid() == uid ) return todo; } return 0; } QString CalendarLocal::nextSummary() const { return mNextSummary; } QDateTime CalendarLocal::nextAlarmEventDateTime() const { return mNextAlarmEventDateTime; } void CalendarLocal::checkAlarmForIncidence( Incidence * incidence, bool deleted) { //mNextAlarmIncidence //mNextAlarmDateTime //return mNextSummary; //return mNextAlarmEventDateTime; bool newNextAlarm = false; bool computeNextAlarm = false; bool ok; int offset; QDateTime nextA; // QString nextSum; //QDateTime nextEvent; if ( mNextAlarmIncidence == 0 || incidence == 0 ) { computeNextAlarm = true; } else { if ( ! deleted ) { nextA = incidence->getNextAlarmDateTime(& ok, &offset ) ; if ( ok ) { if ( nextA < mNextAlarmDateTime ) { deRegisterAlarm(); mNextAlarmDateTime = nextA; mNextSummary = incidence->summary(); mNextAlarmEventDateTime = nextA.addSecs(offset ) ; mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); newNextAlarm = true; mNextAlarmIncidence = incidence; } else { if ( incidence == mNextAlarmIncidence ) { computeNextAlarm = true; } } } else { if ( mNextAlarmIncidence == incidence ) { computeNextAlarm = true; } } } else { // deleted if ( incidence == mNextAlarmIncidence ) { computeNextAlarm = true; } } } if ( computeNextAlarm ) { deRegisterAlarm(); nextA = nextAlarm( 1000 ); if (! mNextAlarmIncidence ) { return; } newNextAlarm = true; } if ( newNextAlarm ) registerAlarm(); } QString CalendarLocal:: getAlarmNotification() { QString ret; // this should not happen if (! mNextAlarmIncidence ) return "cal_alarm"+ mNextSummary.left( 25 )+"\n"+mNextAlarmEventDateTimeString; Alarm* alarm = mNextAlarmIncidence->alarms().first(); if ( alarm->type() == Alarm::Procedure ) { ret = "proc_alarm" + alarm->programFile()+"+++"; } else { ret = "audio_alarm" +alarm->audioFile() +"+++"; } ret += "cal_alarm"+ mNextSummary.left( 25 ); if ( mNextSummary.length() > 25 ) ret += "\n" + mNextSummary.mid(25, 25 ); ret+= "\n"+mNextAlarmEventDateTimeString; return ret; } void CalendarLocal::registerAlarm() { mLastAlarmNotificationString = getAlarmNotification(); // qDebug("++ register Alarm %s %s",mNextAlarmDateTime.toString().latin1(), mLastAlarmNotificationString.latin1() ); emit addAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); // #ifndef DESKTOP_VERSION // AlarmServer::addAlarm ( mNextAlarmDateTime,"koalarm", mLastAlarmNotificationString.latin1() ); // #endif } void CalendarLocal::deRegisterAlarm() { if ( mLastAlarmNotificationString.isNull() ) return; //qDebug("-- deregister Alarm %s ", mLastAlarmNotificationString.latin1() ); emit removeAlarm ( mNextAlarmDateTime, mLastAlarmNotificationString ); // #ifndef DESKTOP_VERSION // AlarmServer::deleteAlarm (mNextAlarmDateTime ,"koalarm" ,mLastAlarmNotificationString.latin1() ); // #endif } QPtrList<Todo> CalendarLocal::todos( const QDate &date ) { QPtrList<Todo> todos; Todo *todo; for ( todo = mTodoList.first(); todo; todo = mTodoList.next() ) { if ( todo->hasDueDate() && todo->dtDue().date() == date ) { todos.append( todo ); } } filter()->apply( &todos ); return todos; } void CalendarLocal::reInitAlarmSettings() { if ( !mNextAlarmIncidence ) { nextAlarm( 1000 ); } deRegisterAlarm(); mNextAlarmIncidence = 0; checkAlarmForIncidence( 0, false ); } QDateTime CalendarLocal::nextAlarm( int daysTo ) { QDateTime nextA = QDateTime::currentDateTime().addDays( daysTo ); QDateTime start = QDateTime::currentDateTime().addSecs( 30 ); QDateTime next; Event *e; bool ok; bool found = false; int offset; mNextAlarmIncidence = 0; for( e = mEventList.first(); e; e = mEventList.next() ) { next = e->getNextAlarmDateTime(& ok, &offset ) ; if ( ok ) { if ( next < nextA ) { nextA = next; found = true; mNextSummary = e->summary(); mNextAlarmEventDateTime = next.addSecs(offset ) ; mNextAlarmIncidence = (Incidence *) e; } } } Todo *t; for( t = mTodoList.first(); t; t = mTodoList.next() ) { next = t->getNextAlarmDateTime(& ok, &offset ) ; if ( ok ) { if ( next < nextA ) { nextA = next; found = true; mNextSummary = t->summary(); mNextAlarmEventDateTime = next.addSecs(offset ); mNextAlarmIncidence = (Incidence *) t; } } } if ( mNextAlarmIncidence ) { mNextAlarmEventDateTimeString = KGlobal::locale()->formatDateTime(mNextAlarmEventDateTime); mNextAlarmDateTime = nextA; } return nextA; } Alarm::List CalendarLocal::alarmsTo( const QDateTime &to ) { return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to ); } Alarm::List CalendarLocal::alarms( const QDateTime &from, const QDateTime &to ) { kdDebug(5800) << "CalendarLocal::alarms(" << from.toString() << " - " << to.toString() << ")\n"; Alarm::List alarms; Event *e; for( e = mEventList.first(); e; e = mEventList.next() ) { if ( e->doesRecur() ) appendRecurringAlarms( alarms, e, from, to ); else appendAlarms( alarms, e, from, to ); } Todo *t; for( t = mTodoList.first(); t; t = mTodoList.next() ) { appendAlarms( alarms, t, from, to ); } return alarms; } void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ) { QPtrList<Alarm> alarmList = incidence->alarms(); Alarm *alarm; for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { // kdDebug(5800) << "CalendarLocal::appendAlarms() '" << alarm->text() // << "': " << alarm->time().toString() << " - " << alarm->enabled() << endl; if ( alarm->enabled() ) { if ( alarm->time() >= from && alarm->time() <= to ) { kdDebug(5800) << "CalendarLocal::appendAlarms() '" << incidence->summary() << "': " << alarm->time().toString() << endl; alarms.append( alarm ); } } } } void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ) { QPtrList<Alarm> alarmList = incidence->alarms(); Alarm *alarm; QDateTime qdt; for( alarm = alarmList.first(); alarm; alarm = alarmList.next() ) { if (incidence->recursOn(from.date())) { qdt.setTime(alarm->time().time()); qdt.setDate(from.date()); } else qdt = alarm->time(); // qDebug("1 %s %s %s", qdt.toString().latin1(), from.toString().latin1(), to.toString().latin1()); if ( alarm->enabled() ) { if ( qdt >= from && qdt <= to ) { alarms.append( alarm ); } } } } /****************************** PROTECTED METHODS ****************************/ // after changes are made to an event, this should be called. void CalendarLocal::update( IncidenceBase *incidence ) { incidence->setSyncStatus( Event::SYNCMOD ); incidence->setLastModified( QDateTime::currentDateTime() ); // we should probably update the revision number here, // or internally in the Event itself when certain things change. // need to verify with ical documentation. setModified( true ); } void CalendarLocal::insertEvent( Event *event ) { if ( mEventList.findRef( event ) < 0 ) mEventList.append( event ); } QPtrList<Event> CalendarLocal::rawEventsForDate( const QDate &qd, bool sorted ) { QPtrList<Event> eventList; Event *event; for( event = mEventList.first(); event; event = mEventList.next() ) { if ( event->doesRecur() ) { if ( event->isMultiDay() ) { int extraDays = event->dtStart().date().daysTo( event->dtEnd().date() ); int i; for ( i = 0; i <= extraDays; i++ ) { if ( event->recursOn( qd.addDays( -i ) ) ) { eventList.append( event ); break; } } } else { if ( event->recursOn( qd ) ) eventList.append( event ); } } else { if ( event->dtStart().date() <= qd && event->dtEnd().date() >= qd ) { eventList.append( event ); } } } if ( !sorted ) { return eventList; } // kdDebug(5800) << "Sorting events for date\n" << endl; // now, we have to sort it based on dtStart.time() QPtrList<Event> eventListSorted; Event *sortEvent; for ( event = eventList.first(); event; event = eventList.next() ) { sortEvent = eventListSorted.first(); int i = 0; while ( sortEvent && event->dtStart().time()>=sortEvent->dtStart().time() ) { i++; sortEvent = eventListSorted.next(); } eventListSorted.insert( i, event ); } return eventListSorted; } QPtrList<Event> CalendarLocal::rawEvents( const QDate &start, const QDate &end, bool inclusive ) { Event *event = 0; QPtrList<Event> eventList; // Get non-recurring events for( event = mEventList.first(); event; event = mEventList.next() ) { if ( event->doesRecur() ) { QDate rStart = event->dtStart().date(); bool found = false; if ( inclusive ) { if ( rStart >= start && rStart <= end ) { // Start date of event is in range. Now check for end date. // if duration is negative, event recurs forever, so do not include it. if ( event->recurrence()->duration() == 0 ) { // End date set QDate rEnd = event->recurrence()->endDate(); if ( rEnd >= start && rEnd <= end ) { // End date within range found = true; } } else if ( event->recurrence()->duration() > 0 ) { // Duration set // TODO: Calculate end date from duration. Should be done in Event // For now exclude all events with a duration. } } } else { bool founOne; QDate next = event->getNextOccurence( start, &founOne ).date(); if ( founOne ) { if ( next <= end ) { found = true; } } /* // crap !!! if ( rStart <= end ) { // Start date not after range if ( rStart >= start ) { // Start date within range found = true; } else if ( event->recurrence()->duration() == -1 ) { // Recurs forever found = true; } else if ( event->recurrence()->duration() == 0 ) { // End date set QDate rEnd = event->recurrence()->endDate(); if ( rEnd >= start && rEnd <= end ) { // End date within range found = true; } } else { // Duration set // TODO: Calculate end date from duration. Should be done in Event // For now include all events with a duration. found = true; } } */ } if ( found ) eventList.append( event ); } else { QDate s = event->dtStart().date(); QDate e = event->dtEnd().date(); if ( inclusive ) { if ( s >= start && e <= end ) { eventList.append( event ); } } else { if ( ( s >= start && s <= end ) || ( e >= start && e <= end ) ) { eventList.append( event ); } } } } return eventList; } QPtrList<Event> CalendarLocal::rawEventsForDate( const QDateTime &qdt ) { return rawEventsForDate( qdt.date() ); } QPtrList<Event> CalendarLocal::rawEvents() { return mEventList; } bool CalendarLocal::addJournal(Journal *journal) { if ( journal->dtStart().isValid()) kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl; else kdDebug(5800) << "Adding Journal without a DTSTART" << endl; mJournalList.append(journal); journal->registerObserver( this ); setModified( true ); return true; } void CalendarLocal::deleteJournal( Journal *journal ) { if ( mJournalList.removeRef(journal) ) { setModified( true ); } } Journal *CalendarLocal::journal( const QDate &date ) { // kdDebug(5800) << "CalendarLocal::journal() " << date.toString() << endl; for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->dtStart().date() == date ) return it; return 0; } Journal *CalendarLocal::journal( const QString &uid ) { for ( Journal *it = mJournalList.first(); it; it = mJournalList.next() ) if ( it->uid() == uid ) return it; return 0; } QPtrList<Journal> CalendarLocal::journals() { return mJournalList; } diff --git a/libkcal/calendarlocal.h b/libkcal/calendarlocal.h index a17cf11..a2e50e3 100644 --- a/libkcal/calendarlocal.h +++ b/libkcal/calendarlocal.h @@ -1,216 +1,217 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brown Copyright (c) 2001,2003 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef KCAL_CALENDARLOCAL_H #define KCAL_CALENDARLOCAL_H #include "calendar.h" namespace KCal { class CalFormat; /** This class provides a calendar stored as a local file. */ class CalendarLocal : public Calendar { public: /** Constructs a new calendar, with variables initialized to sane values. */ CalendarLocal(); /** Constructs a new calendar, with variables initialized to sane values. */ CalendarLocal( const QString &timeZoneId ); ~CalendarLocal(); /** Loads a calendar on disk in vCalendar or iCalendar format into the current calendar. Any information already present is lost. @return true, if successfull, false on error. @param fileName the name of the calendar on disk. */ bool load( const QString &fileName ); /** Writes out the calendar to disk in the specified \a format. CalendarLocal takes ownership of the CalFormat object. @return true, if successfull, false on error. @param fileName the name of the file */ bool save( const QString &fileName, CalFormat *format = 0 ); /** Clears out the current calendar, freeing all used memory etc. etc. */ void close(); void save() {} /** Add Event to calendar. */ + bool addAnniversaryNoDup( Event *event ); bool addEventNoDup( Event *event ); bool addEvent( Event *event ); /** Deletes an event from this calendar. */ void deleteEvent( Event *event ); /** Retrieves an event on the basis of the unique string ID. */ Event *event( const QString &uid ); /** Return unfiltered list of all events in calendar. */ QPtrList<Event> rawEvents(); /** Add a todo to the todolist. */ bool addTodo( Todo *todo ); bool addTodoNoDup( Todo *todo ); /** Remove a todo from the todolist. */ void deleteTodo( Todo * ); /** Searches todolist for an event with this unique string identifier, returns a pointer or null. */ Todo *todo( const QString &uid ); /** Return list of all todos. */ QPtrList<Todo> rawTodos(); /** Returns list of todos due on the specified date. */ QPtrList<Todo> todos( const QDate &date ); /** Return list of all todos. Workaround because compiler does not recognize function of base class. */ QPtrList<Todo> todos() { return Calendar::todos(); } /** Add a Journal entry to calendar. */ bool addJournal( Journal * ); /** Remove a Journal from the calendar. */ void deleteJournal( Journal * ); /** Return Journal for given date. */ Journal *journal( const QDate & ); /** Return Journal with given UID. */ Journal *journal( const QString &uid ); /** Return list of all Journals stored in calendar. */ QPtrList<Journal> journals(); /** Return all alarms, which ocur in the given time interval. */ Alarm::List alarms( const QDateTime &from, const QDateTime &to ); /** Return all alarms, which ocur before given date. */ Alarm::List alarmsTo( const QDateTime &to ); QDateTime nextAlarm( int daysTo ) ; QDateTime nextAlarmEventDateTime() const; void checkAlarmForIncidence( Incidence *, bool deleted ) ; void registerAlarm(); void deRegisterAlarm(); QString getAlarmNotification(); QString nextSummary() const ; /** This method should be called whenever a Event is modified directly via it's pointer. It makes sure that the calendar is internally consistent. */ void update( IncidenceBase *incidence ); /** Builds and then returns a list of all events that match for the date specified. useful for dayView, etc. etc. */ QPtrList<Event> rawEventsForDate( const QDate &date, bool sorted = false ); /** Get unfiltered events for date \a qdt. */ QPtrList<Event> rawEventsForDate( const QDateTime &qdt ); /** Get unfiltered events in a range of dates. If inclusive is set to true, only events are returned, which are completely included in the range. */ QPtrList<Event> rawEvents( const QDate &start, const QDate &end, bool inclusive = false ); Todo *CalendarLocal::todo( int uid ); Event *CalendarLocal::event( int uid ); protected: // Event* mNextAlarmEvent; QString mNextSummary; QString mNextAlarmEventDateTimeString; QString mLastAlarmNotificationString; QDateTime mNextAlarmEventDateTime; QDateTime mNextAlarmDateTime; void reInitAlarmSettings(); /** Notification function of IncidenceBase::Observer. */ void incidenceUpdated( IncidenceBase *i ) { update( i ); } /** inserts an event into its "proper place" in the calendar. */ void insertEvent( Event *event ); /** Append alarms of incidence in interval to list of alarms. */ void appendAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ); /** Append alarms of recurring events in interval to list of alarms. */ void appendRecurringAlarms( Alarm::List &alarms, Incidence *incidence, const QDateTime &from, const QDateTime &to ); private: void init(); QPtrList<Event> mEventList; QPtrList<Todo> mTodoList; QPtrList<Journal> mJournalList; }; } #endif diff --git a/libkcal/icalformat.cpp b/libkcal/icalformat.cpp index 5893db5..f2e7dfc 100644 --- a/libkcal/icalformat.cpp +++ b/libkcal/icalformat.cpp @@ -1,478 +1,480 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <qregexp.h> #include <qclipboard.h> #include <qfile.h> #include <qtextstream.h> #include <qtextcodec.h> #include <stdlib.h> #include <kdebug.h> #include <kglobal.h> #include <klocale.h> extern "C" { #include <ical.h> #include <icalss.h> #include <icalparser.h> #include <icalrestriction.h> } #include "calendar.h" #include "calendarlocal.h" #include "journal.h" #include "icalformat.h" #include "icalformatimpl.h" #define _ICAL_VERSION "2.0" using namespace KCal; ICalFormat::ICalFormat(bool quick ) { mQuicksave = false; //quick; mImpl = new ICalFormatImpl( this ); tzOffsetMin = 0; //qDebug("new ICalFormat() "); } ICalFormat::~ICalFormat() { delete mImpl; //qDebug("delete ICalFormat "); } bool ICalFormat::load( Calendar *calendar, const QString &fileName) { clearException(); QFile file( fileName ); if (!file.open( IO_ReadOnly ) ) { setException(new ErrorFormat(ErrorFormat::LoadError)); return false; } QTextStream ts( &file ); QString text; #if 0 if ( !mQuicksave ) { qDebug("KO: No quickload!"); ts.setEncoding( QTextStream::Latin1 ); text = ts.read(); } else { ts.setCodec( QTextCodec::codecForName("utf8") ); text = ts.read(); } #endif ts.setEncoding( QTextStream::Latin1 ); text = ts.read(); file.close(); return fromString( calendar, text ); } //#include <qdatetime.h> bool ICalFormat::save( Calendar *calendar, const QString &fileName ) { //kdDebug(5800) << "ICalFormat::save(): " << fileName << endl; //qDebug("ICalFormat::save "); clearException(); QString text = toString( calendar ); //return false; // qDebug("to string takes ms: %d ",is.elapsed() ); if ( text.isNull() ) return false; // TODO: write backup file //is.restart(); QFile file( fileName ); if (!file.open( IO_WriteOnly ) ) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("Could not open file '%1'").arg(fileName))); return false; } QTextStream ts( &file ); // #ifdef DESKTOP_VERSION // mQuicksave = false; // #endif // if ( mQuicksave ) { // ts << text.utf8(); // } else { // ts.setEncoding( QTextStream::Latin1 ); // ts << text; // //ts << text.latin1(); // } ts.setEncoding( QTextStream::Latin1 ); ts << text; file.close(); //qDebug("saving file takes ms: %d ", is.elapsed() ); return true; } bool ICalFormat::fromString( Calendar *cal, const QString &text ) { setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); // qDebug("ICalFormat::fromString tz: %s ", cal->timeZoneId().latin1()); // Get first VCALENDAR component. // TODO: Handle more than one VCALENDAR or non-VCALENDAR top components icalcomponent *calendar; //calendar = icalcomponent_new_from_string( text.local8Bit().data()); // good calendar = icalcomponent_new_from_string( text.utf8().data()); calendar = icalcomponent_new_from_string( (char*)text.latin1()); if (!calendar) { setException(new ErrorFormat(ErrorFormat::ParseErrorIcal)); return false; } bool success = true; if (icalcomponent_isa(calendar) != ICAL_VCALENDAR_COMPONENT) { setException(new ErrorFormat(ErrorFormat::NoCalendar)); success = false; } else { // put all objects into their proper places if ( !mImpl->populate( cal, calendar ) ) { if ( !exception() ) { setException(new ErrorFormat(ErrorFormat::ParseErrorKcal)); } success = false; } else mLoadedProductId = mImpl->loadedProductId(); } icalcomponent_free( calendar ); return success; } Incidence *ICalFormat::fromString( const QString &text ) { CalendarLocal cal( mTimeZoneId ); fromString(&cal, text); Incidence *ical = 0; QPtrList<Event> elist = cal.events(); if ( elist.count() > 0 ) { ical = elist.first(); } else { QPtrList<Todo> tlist = cal.todos(); if ( tlist.count() > 0 ) { ical = tlist.first(); } else { QPtrList<Journal> jlist = cal.journals(); if ( jlist.count() > 0 ) { ical = jlist.first(); } } } return ical; } #include <qapp.h> QString ICalFormat::toString( Calendar *cal ) { setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); icalcomponent *calendar = mImpl->createCalendarComponent(cal); icalcomponent *component; // todos QPtrList<Todo> todoList = cal->rawTodos(); QPtrListIterator<Todo> qlt(todoList); for (; qlt.current(); ++qlt) { component = mImpl->writeTodo(qlt.current()); icalcomponent_add_component(calendar,component); //qDebug(" todos "); qApp->processEvents(); } // events QPtrList<Event> events = cal->rawEvents(); Event *ev; for(ev=events.first();ev;ev=events.next()) { component = mImpl->writeEvent(ev); icalcomponent_add_component(calendar,component); //qDebug("events "); qApp->processEvents(); } // journals QPtrList<Journal> journals = cal->journals(); Journal *j; for(j=journals.first();j;j=journals.next()) { component = mImpl->writeJournal(j); icalcomponent_add_component(calendar,component); //qDebug("journals "); qApp->processEvents(); } const char *text; QString ret =""; text = icalcomponent_as_ical_string( calendar ); qApp->processEvents(); // text = "BEGIN:VCALENDAR\nPRODID\n :-//K Desktop Environment//NONSGML libkcal 3.1//EN\nVERSION\n :2.0\nBEGIN:VEVENT\nDTSTAMP\n :20031231T213514Z\nORGANIZER\n :MAILTO:lutz@putz.de\nCREATED\n :20031231T213513Z\nUID\n :libkcal-1295166342.120\nSEQUENCE\n :0\nLAST-MODIFIED\n :20031231T213513Z\nSUMMARY\n :test1\nCLASS\n :PUBLIC\nPRIORITY\n :3\nDTSTART\n :20040101T090000Z\nDTEND\n :20040101T110000Z\nTRANSP\n :OPAQUE\nEND:VEVENT\nEND:VCALENDAR\n"; if ( text ) { ret = QString ( text ); } icalcomponent_free( calendar ); if (!text) { setException(new ErrorFormat(ErrorFormat::SaveError, i18n("libical error"))); return QString::null; } return ret; } QString ICalFormat::toICalString( Incidence *incidence ) { CalendarLocal cal( mTimeZoneId ); cal.addIncidence( incidence->clone() ); return toString( &cal ); } QString ICalFormat::toString( Incidence *incidence ) { icalcomponent *component; component = mImpl->writeIncidence( incidence ); const char *text = icalcomponent_as_ical_string( component ); icalcomponent_free( component ); return QString::fromLocal8Bit( text ); } QString ICalFormat::toString( Recurrence *recurrence ) { icalproperty *property; property = mImpl->writeRecurrenceRule( recurrence ); const char *text = icalproperty_as_ical_string( property ); icalproperty_free( property ); return QString::fromLocal8Bit( text ); } /* bool ICalFormat::fromString( Recurrence * recurrence, const QString& rrule ) { bool success = true; icalerror_clear_errno(); struct icalrecurrencetype recur = icalrecurrencetype_from_string( rrule ); if ( icalerrno != ICAL_NO_ERROR ) { kdDebug() << "Recurrence parsing error: " << icalerror_strerror( icalerrno ) << endl; success = false; } if ( success ) { mImpl->readRecurrence( recur, recurrence ); } return success; } */ QString ICalFormat::createScheduleMessage(IncidenceBase *incidence, Scheduler::Method method) { icalcomponent *message = mImpl->createScheduleComponent(incidence,method); QString messageText = icalcomponent_as_ical_string(message); return messageText; } ScheduleMessage *ICalFormat::parseScheduleMessage( Calendar *cal, const QString &messageText ) { setTimeZone( cal->timeZoneId(), !cal->isLocalTime() ); clearException(); if (messageText.isEmpty()) return 0; icalcomponent *message; message = icalparser_parse_string(messageText.local8Bit()); if (!message) return 0; icalproperty *m = icalcomponent_get_first_property(message, ICAL_METHOD_PROPERTY); if (!m) return 0; icalcomponent *c; IncidenceBase *incidence = 0; c = icalcomponent_get_first_component(message,ICAL_VEVENT_COMPONENT); if (c) { incidence = mImpl->readEvent(c); } if (!incidence) { c = icalcomponent_get_first_component(message,ICAL_VTODO_COMPONENT); if (c) { incidence = mImpl->readTodo(c); } } if (!incidence) { c = icalcomponent_get_first_component(message,ICAL_VFREEBUSY_COMPONENT); if (c) { incidence = mImpl->readFreeBusy(c); } } if (!incidence) { kdDebug() << "ICalFormat:parseScheduleMessage: object is not a freebusy, event or todo" << endl; return 0; } kdDebug(5800) << "ICalFormat::parseScheduleMessage() getting method..." << endl; icalproperty_method icalmethod = icalproperty_get_method(m); Scheduler::Method method; switch (icalmethod) { case ICAL_METHOD_PUBLISH: method = Scheduler::Publish; break; case ICAL_METHOD_REQUEST: method = Scheduler::Request; break; case ICAL_METHOD_REFRESH: method = Scheduler::Refresh; break; case ICAL_METHOD_CANCEL: method = Scheduler::Cancel; break; case ICAL_METHOD_ADD: method = Scheduler::Add; break; case ICAL_METHOD_REPLY: method = Scheduler::Reply; break; case ICAL_METHOD_COUNTER: method = Scheduler::Counter; break; case ICAL_METHOD_DECLINECOUNTER: method = Scheduler::Declinecounter; break; default: method = Scheduler::NoMethod; kdDebug(5800) << "ICalFormat::parseScheduleMessage(): Unknow method" << endl; break; } if (!icalrestriction_check(message)) { setException(new ErrorFormat(ErrorFormat::Restriction, Scheduler::translatedMethodName(method) + ": " + mImpl->extractErrorProperty(c))); return 0; } icalcomponent *calendarComponent = mImpl->createCalendarComponent(cal); Incidence *existingIncidence = cal->event(incidence->uid()); if (existingIncidence) { // TODO: check, if cast is required, or if it can be done by virtual funcs. if (existingIncidence->type() == "Todo") { Todo *todo = static_cast<Todo *>(existingIncidence); icalcomponent_add_component(calendarComponent, mImpl->writeTodo(todo)); } if (existingIncidence->type() == "Event") { Event *event = static_cast<Event *>(existingIncidence); icalcomponent_add_component(calendarComponent, mImpl->writeEvent(event)); } } else { calendarComponent = 0; } - + qDebug("icalclassify commented out "); + ScheduleMessage::Status status; +#if 0 icalclass result = icalclassify(message,calendarComponent,(char *)""); - ScheduleMessage::Status status; switch (result) { case ICAL_PUBLISH_NEW_CLASS: status = ScheduleMessage::PublishNew; break; case ICAL_OBSOLETE_CLASS: status = ScheduleMessage::Obsolete; break; case ICAL_REQUEST_NEW_CLASS: status = ScheduleMessage::RequestNew; break; case ICAL_REQUEST_UPDATE_CLASS: status = ScheduleMessage::RequestUpdate; break; case ICAL_UNKNOWN_CLASS: default: status = ScheduleMessage::Unknown; break; } - +#endif + status = ScheduleMessage::RequestUpdate; return new ScheduleMessage(incidence,method,status); } void ICalFormat::setTimeZone( const QString &id, bool utc ) { mTimeZoneId = id; mUtc = utc; tzOffsetMin = KGlobal::locale()->timezoneOffset(mTimeZoneId); //qDebug("ICalFormat::setTimeZoneOffset %s %d ",mTimeZoneId.latin1(), tzOffsetMin); } QString ICalFormat::timeZoneId() const { return mTimeZoneId; } bool ICalFormat::utc() const { return mUtc; } int ICalFormat::timeOffset() { return tzOffsetMin; } const char *ICalFormat::tzString() { const char* ret = (const char* ) mTzString; return ret; } diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp index e5c27a0..32a1337 100644 --- a/libkcal/icalformatimpl.cpp +++ b/libkcal/icalformatimpl.cpp @@ -1,2173 +1,2170 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <qfile.h> #include <kdebug.h> #include <klocale.h> #include <kglobal.h> extern "C" { #include <ical.h> #include <icalss.h> #include <icalparser.h> #include <icalrestriction.h> } #include "calendar.h" #include "journal.h" #include "icalformat.h" #include "icalformatimpl.h" #include "compat.h" #define _ICAL_VERSION "2.0" using namespace KCal; const int gSecondsPerMinute = 60; const int gSecondsPerHour = gSecondsPerMinute * 60; const int gSecondsPerDay = gSecondsPerHour * 24; const int gSecondsPerWeek = gSecondsPerDay * 7; ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) : mParent( parent ), mCalendarVersion( 0 ) { mCompat = new Compat; } ICalFormatImpl::~ICalFormatImpl() { delete mCompat; } class ToStringVisitor : public Incidence::Visitor { public: ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {} bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; } bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; } bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; } icalcomponent *component() { return mComponent; } private: ICalFormatImpl *mImpl; icalcomponent *mComponent; }; icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence) { ToStringVisitor v( this ); incidence->accept(v); return v.component(); } icalcomponent *ICalFormatImpl::writeTodo(Todo *todo) { QString tmpStr; QStringList tmpStrList; icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT); writeIncidence(vtodo,todo); // due date if (todo->hasDueDate()) { icaltimetype due; if (todo->doesFloat()) { due = writeICalDate(todo->dtDue().date()); } else { due = writeICalDateTime(todo->dtDue()); } icalcomponent_add_property(vtodo,icalproperty_new_due(due)); } // start time if (todo->hasStartDate()) { icaltimetype start; if (todo->doesFloat()) { // kdDebug(5800) << "§§ Incidence " << todo->summary() << " floats." << endl; start = writeICalDate(todo->dtStart().date()); } else { // kdDebug(5800) << "§§ incidence " << todo->summary() << " has time." << endl; start = writeICalDateTime(todo->dtStart()); } icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start)); } // completion date if (todo->isCompleted()) { if (!todo->hasCompletedDate()) { // If todo was created by KOrganizer <2.2 it has no correct completion // date. Set it to now. todo->setCompleted(QDateTime::currentDateTime()); } icaltimetype completed = writeICalDateTime(todo->completed()); icalcomponent_add_property(vtodo,icalproperty_new_completed(completed)); } icalcomponent_add_property(vtodo, icalproperty_new_percentcomplete(todo->percentComplete())); return vtodo; } icalcomponent *ICalFormatImpl::writeEvent(Event *event) { kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid() << ")" << endl; QString tmpStr; QStringList tmpStrList; icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT); writeIncidence(vevent,event); // start time icaltimetype start; if (event->doesFloat()) { // kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; start = writeICalDate(event->dtStart().date()); } else { // kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; start = writeICalDateTime(event->dtStart()); } icalcomponent_add_property(vevent,icalproperty_new_dtstart(start)); if (event->hasEndDate()) { // end time icaltimetype end; if (event->doesFloat()) { // kdDebug(5800) << "§§ Event " << event->summary() << " floats." << endl; // +1 day because end date is non-inclusive. end = writeICalDate( event->dtEnd().date().addDays( 1 ) ); } else { // kdDebug(5800) << "§§ Event " << event->summary() << " has time." << endl; end = writeICalDateTime(event->dtEnd()); } icalcomponent_add_property(vevent,icalproperty_new_dtend(end)); } // TODO: attachments, resources #if 0 // attachments tmpStrList = anEvent->attachments(); for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) addPropValue(vevent, VCAttachProp, (*it).utf8()); // resources tmpStrList = anEvent->resources(); tmpStr = tmpStrList.join(";"); if (!tmpStr.isEmpty()) addPropValue(vevent, VCResourcesProp, tmpStr.utf8()); #endif // Transparency switch( event->transparency() ) { case Event::Transparent: - icalcomponent_add_property(vevent, icalproperty_new_transp("TRANSPARENT")); + icalcomponent_add_property(vevent, icalproperty_new_transp(ICAL_TRANSP_TRANSPARENT)); break; case Event::Opaque: - icalcomponent_add_property(vevent, icalproperty_new_transp("OPAQUE")); + icalcomponent_add_property(vevent, icalproperty_new_transp(ICAL_TRANSP_OPAQUE)); break; } return vevent; } icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy, Scheduler::Method method) { #if QT_VERSION >= 300 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: " << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: " << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl; #endif icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); writeIncidenceBase(vfreebusy,freebusy); icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart( writeICalDateTime(freebusy->dtStart()))); icalcomponent_add_property(vfreebusy, icalproperty_new_dtend( writeICalDateTime(freebusy->dtEnd()))); if (method == Scheduler::Request) { icalcomponent_add_property(vfreebusy,icalproperty_new_uid( freebusy->uid().utf8())); } //Loops through all the periods in the freebusy object QValueList<Period> list = freebusy->busyPeriods(); QValueList<Period>::Iterator it; icalperiodtype period; for (it = list.begin(); it!= list.end(); ++it) { period.start = writeICalDateTime((*it).start()); period.end = writeICalDateTime((*it).end()); icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) ); } return vfreebusy; } icalcomponent *ICalFormatImpl::writeJournal(Journal *journal) { icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT); writeIncidence(vjournal,journal); // start time if (journal->dtStart().isValid()) { icaltimetype start; if (journal->doesFloat()) { // kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; start = writeICalDate(journal->dtStart().date()); } else { // kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; start = writeICalDateTime(journal->dtStart()); } icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start)); } return vjournal; } void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence) { // pilot sync stuff // TODO: move this application-specific code to kpilot if (incidence->pilotId()) { incidence->setNonKDECustomProperty("X-PILOTID", QString::number(incidence->pilotId())); incidence->setNonKDECustomProperty("X-PILOTSTAT", QString::number(incidence->syncStatus())); } if (incidence->zaurusId() >= 0) { incidence->setNonKDECustomProperty("X-ZAURUSID", QString::number(incidence->zaurusId())); } if (incidence->zaurusUid() > 0) { incidence->setNonKDECustomProperty("X-ZAURUSUID", QString::number(incidence->zaurusUid())); } if (incidence->zaurusStat() > 0) { incidence->setNonKDECustomProperty("X-ZAURUSSTAT", QString::number(incidence->zaurusStat())); } writeIncidenceBase(parent,incidence); if (incidence->cancelled()) { icalcomponent_add_property(parent,icalproperty_new_status(ICAL_STATUS_CANCELLED)); } // creation date icalcomponent_add_property(parent,icalproperty_new_created( writeICalDateTime(incidence->created()))); // unique id icalcomponent_add_property(parent,icalproperty_new_uid( incidence->uid().utf8())); // revision icalcomponent_add_property(parent,icalproperty_new_sequence( incidence->revision())); // last modification date icalcomponent_add_property(parent,icalproperty_new_lastmodified( writeICalDateTime(incidence->lastModified()))); // description if (!incidence->description().isEmpty()) { icalcomponent_add_property(parent,icalproperty_new_description( incidence->description().utf8())); } // summary if (!incidence->summary().isEmpty()) { icalcomponent_add_property(parent,icalproperty_new_summary( incidence->summary().utf8())); } // location if (!incidence->location().isEmpty()) { icalcomponent_add_property(parent,icalproperty_new_location( incidence->location().utf8())); } // TODO: // status // addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8()); // secrecy - const char *classStr; + enum icalproperty_class classInt; switch (incidence->secrecy()) { case Incidence::SecrecyPublic: - classStr = "PUBLIC"; + classInt = ICAL_CLASS_PUBLIC; break; case Incidence::SecrecyConfidential: - classStr = "CONFIDENTIAL"; + classInt = ICAL_CLASS_CONFIDENTIAL; break; case Incidence::SecrecyPrivate: + classInt =ICAL_CLASS_PRIVATE ; default: - classStr = "PRIVATE"; + classInt =ICAL_CLASS_PRIVATE ; break; } - icalcomponent_add_property(parent,icalproperty_new_class(classStr)); + icalcomponent_add_property(parent,icalproperty_new_class(classInt)); // priority icalcomponent_add_property(parent,icalproperty_new_priority( incidence->priority())); // categories QStringList categories = incidence->categories(); QStringList::Iterator it; for(it = categories.begin(); it != categories.end(); ++it ) { icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8())); } // TODO: Ensure correct concatenation of categories properties. /* // categories tmpStrList = incidence->getCategories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); icalcomponent_add_property(parent,icalproperty_new_categories( writeText(incidence->getCategories().join(";")))); } */ // related event if (incidence->relatedTo()) { icalcomponent_add_property(parent,icalproperty_new_relatedto( incidence->relatedTo()->uid().utf8())); } // recurrence rule stuff Recurrence *recur = incidence->recurrence(); if (recur->doesRecur()) { icalcomponent_add_property(parent,writeRecurrenceRule(recur)); } // recurrence excpetion dates DateList dateList = incidence->exDates(); DateList::ConstIterator exIt; for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) { icalcomponent_add_property(parent,icalproperty_new_exdate( writeICalDate(*exIt))); } // attachments QPtrList<Attachment> attachments = incidence->attachments(); for (Attachment *at = attachments.first(); at; at = attachments.next()) icalcomponent_add_property(parent,writeAttachment(at)); // alarms QPtrList<Alarm> alarms = incidence->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { kdDebug(5800) << "Write alarm for " << incidence->summary() << endl; icalcomponent_add_component(parent,writeAlarm(alarm)); } } // duration // turned off as it always is set to PTS0 (and must not occur together with DTEND // if (incidence->hasDuration()) { // icaldurationtype duration; // duration = writeICalDuration(incidence->duration()); // icalcomponent_add_property(parent,icalproperty_new_duration(duration)); // } } void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) { icalcomponent_add_property(parent,icalproperty_new_dtstamp( writeICalDateTime(QDateTime::currentDateTime()))); // organizer stuff icalcomponent_add_property(parent,icalproperty_new_organizer( ("MAILTO:" + incidenceBase->organizer()).utf8())); // attendees if (incidenceBase->attendeeCount() != 0) { QPtrList<Attendee> al = incidenceBase->attendees(); QPtrListIterator<Attendee> ai(al); for (; ai.current(); ++ai) { icalcomponent_add_property(parent,writeAttendee(ai.current())); } } // custom properties writeCustomProperties(parent, incidenceBase); } void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties) { QMap<QCString, QString> custom = properties->customProperties(); for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { icalproperty *p = icalproperty_new_x(c.data().utf8()); icalproperty_set_x_name(p,c.key()); icalcomponent_add_property(parent,p); } } icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee) { icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8()); if (!attendee->name().isEmpty()) { icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8())); } icalproperty_add_parameter(p,icalparameter_new_rsvp( attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE )); icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION; switch (attendee->status()) { default: case Attendee::NeedsAction: status = ICAL_PARTSTAT_NEEDSACTION; break; case Attendee::Accepted: status = ICAL_PARTSTAT_ACCEPTED; break; case Attendee::Declined: status = ICAL_PARTSTAT_DECLINED; break; case Attendee::Tentative: status = ICAL_PARTSTAT_TENTATIVE; break; case Attendee::Delegated: status = ICAL_PARTSTAT_DELEGATED; break; case Attendee::Completed: status = ICAL_PARTSTAT_COMPLETED; break; case Attendee::InProcess: status = ICAL_PARTSTAT_INPROCESS; break; } icalproperty_add_parameter(p,icalparameter_new_partstat(status)); icalparameter_role role = ICAL_ROLE_REQPARTICIPANT; switch (attendee->role()) { case Attendee::Chair: role = ICAL_ROLE_CHAIR; break; default: case Attendee::ReqParticipant: role = ICAL_ROLE_REQPARTICIPANT; break; case Attendee::OptParticipant: role = ICAL_ROLE_OPTPARTICIPANT; break; case Attendee::NonParticipant: role = ICAL_ROLE_NONPARTICIPANT; break; } icalproperty_add_parameter(p,icalparameter_new_role(role)); if (!attendee->uid().isEmpty()) { icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8()); icalparameter_set_xname(icalparameter_uid,"X-UID"); icalproperty_add_parameter(p,icalparameter_uid); } return p; } icalproperty *ICalFormatImpl::writeAttachment(Attachment *att) { - icalattachtype* attach = icalattachtype_new(); +#if 0 + icalattachtype* attach = icalattachtype_new(); if (att->isURI()) icalattachtype_set_url(attach, att->uri().utf8().data()); else icalattachtype_set_base64(attach, att->data(), 0); - +#endif + icalattach *attach; + if (att->isURI()) + attach = icalattach_new_from_url( att->uri().utf8().data()); + else + attach = icalattach_new_from_data ( (unsigned char *)att->data(), 0, 0); icalproperty *p = icalproperty_new_attach(attach); - if (!att->mimeType().isEmpty()) icalproperty_add_parameter(p,icalparameter_new_fmttype(att->mimeType().utf8().data())); if (att->isBinary()) { icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY)); icalproperty_add_parameter(p,icalparameter_new_encoding(ICAL_ENCODING_BASE64)); } return p; } icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur) { // kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl; icalrecurrencetype r; icalrecurrencetype_clear(&r); int index = 0; int index2 = 0; QPtrList<Recurrence::rMonthPos> tmpPositions; QPtrList<int> tmpDays; int *tmpDay; Recurrence::rMonthPos *tmpPos; bool datetime = false; int day; int i; switch(recur->doesRecur()) { case Recurrence::rMinutely: r.freq = ICAL_MINUTELY_RECURRENCE; datetime = true; break; case Recurrence::rHourly: r.freq = ICAL_HOURLY_RECURRENCE; datetime = true; break; case Recurrence::rDaily: r.freq = ICAL_DAILY_RECURRENCE; break; case Recurrence::rWeekly: r.freq = ICAL_WEEKLY_RECURRENCE; r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1); for (i = 0; i < 7; i++) { if (recur->days().testBit(i)) { day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 r.by_day[index++] = icalrecurrencetype_day_day_of_week(day); } } // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; break; case Recurrence::rMonthlyPos: r.freq = ICAL_MONTHLY_RECURRENCE; tmpPositions = recur->monthPositions(); for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) { day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 day += tmpPos->rPos*8; if (tmpPos->negative) day = -day; r.by_day[index++] = day; } } } // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; break; case Recurrence::rMonthlyDay: r.freq = ICAL_MONTHLY_RECURRENCE; tmpDays = recur->monthDays(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay); } // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; break; case Recurrence::rYearlyMonth: case Recurrence::rYearlyPos: r.freq = ICAL_YEARLY_RECURRENCE; tmpDays = recur->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_month[index++] = *tmpDay; } // r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX; if (recur->doesRecur() == Recurrence::rYearlyPos) { tmpPositions = recur->monthPositions(); for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) { day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 day += tmpPos->rPos*8; if (tmpPos->negative) day = -day; r.by_day[index2++] = day; } } } // r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX; } break; case Recurrence::rYearlyDay: r.freq = ICAL_YEARLY_RECURRENCE; tmpDays = recur->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { r.by_year_day[index++] = *tmpDay; } // r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX; break; default: r.freq = ICAL_NO_RECURRENCE; kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl; break; } r.interval = recur->frequency(); if (recur->duration() > 0) { r.count = recur->duration(); } else if (recur->duration() == -1) { r.count = 0; } else { if (datetime) r.until = writeICalDateTime(recur->endDateTime()); else r.until = writeICalDate(recur->endDate()); } // Debug output #if 0 const char *str = icalrecurrencetype_as_string(&r); if (str) { kdDebug(5800) << " String: " << str << endl; } else { kdDebug(5800) << " No String" << endl; } #endif return icalproperty_new_rrule(r); } icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm) { icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT); icalproperty_action action; - icalattachtype *attach = 0; + icalattach *attach = 0; switch (alarm->type()) { case Alarm::Procedure: action = ICAL_ACTION_PROCEDURE; - attach = icalattachtype_new(); - icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data()); + attach = icalattach_new_from_url( QFile::encodeName(alarm->programFile()).data() ); icalcomponent_add_property(a,icalproperty_new_attach(attach)); - icalattachtype_free(attach); if (!alarm->programArguments().isEmpty()) { icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8())); } break; case Alarm::Audio: action = ICAL_ACTION_AUDIO; if (!alarm->audioFile().isEmpty()) { - attach = icalattachtype_new(); - icalattachtype_set_url(attach,QFile::encodeName( alarm->audioFile() ).data()); + attach = icalattach_new_from_url(QFile::encodeName( alarm->audioFile() ).data()); icalcomponent_add_property(a,icalproperty_new_attach(attach)); - icalattachtype_free(attach); } break; case Alarm::Email: { action = ICAL_ACTION_EMAIL; QValueList<Person> addresses = alarm->mailAddresses(); for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) { icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8()); if (!(*ad).name().isEmpty()) { icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8())); } icalcomponent_add_property(a,p); } icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8())); icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); QStringList attachments = alarm->mailAttachments(); if (attachments.count() > 0) { for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) { - attach = icalattachtype_new(); - icalattachtype_set_url(attach,QFile::encodeName( *at ).data()); + attach = icalattach_new_from_url(QFile::encodeName( *at ).data()); icalcomponent_add_property(a,icalproperty_new_attach(attach)); - icalattachtype_free(attach); } } break; } case Alarm::Display: action = ICAL_ACTION_DISPLAY; icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); break; case Alarm::Invalid: default: kdDebug(5800) << "Unknown type of alarm" << endl; action = ICAL_ACTION_NONE; break; } icalcomponent_add_property(a,icalproperty_new_action(action)); // Trigger time icaltriggertype trigger; if ( alarm->hasTime() ) { trigger.time = writeICalDateTime(alarm->time()); trigger.duration = icaldurationtype_null_duration(); } else { trigger.time = icaltime_null_time(); Duration offset; if ( alarm->hasStartOffset() ) offset = alarm->startOffset(); else offset = alarm->endOffset(); trigger.duration = icaldurationtype_from_int( offset.asSeconds() ); } icalproperty *p = icalproperty_new_trigger(trigger); if ( alarm->hasEndOffset() ) icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END)); icalcomponent_add_property(a,p); // Repeat count and duration if (alarm->repeatCount()) { icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount())); icalcomponent_add_property(a,icalproperty_new_duration( icaldurationtype_from_int(alarm->snoozeTime()*60))); } // Custom properties QMap<QCString, QString> custom = alarm->customProperties(); for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { icalproperty *p = icalproperty_new_x(c.data().utf8()); icalproperty_set_x_name(p,c.key()); icalcomponent_add_property(a,p); } return a; } Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo) { Todo *todo = new Todo; readIncidence(vtodo,todo); icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY); // int intvalue; icaltimetype icaltime; QStringList categories; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_DUE_PROPERTY: // due date icaltime = icalproperty_get_due(p); if (icaltime.is_date) { todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0))); todo->setFloats(true); } else { todo->setDtDue(readICalDateTime(icaltime)); todo->setFloats(false); } todo->setHasDueDate(true); break; case ICAL_COMPLETED_PROPERTY: // completion date icaltime = icalproperty_get_completed(p); todo->setCompleted(readICalDateTime(icaltime)); break; case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed todo->setPercentComplete(icalproperty_get_percentcomplete(p)); break; case ICAL_RELATEDTO_PROPERTY: // related todo (parent) todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); mTodosRelate.append(todo); break; case ICAL_DTSTART_PROPERTY: // Flag that todo has start date. Value is read in by readIncidence(). todo->setHasStartDate(true); break; default: // kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY); } return todo; } Event *ICalFormatImpl::readEvent(icalcomponent *vevent) { Event *event = new Event; event->setFloats(false); readIncidence(vevent,event); icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY); // int intvalue; icaltimetype icaltime; QStringList categories; QString transparency; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_DTEND_PROPERTY: // start date and time icaltime = icalproperty_get_dtend(p); if (icaltime.is_date) { event->setFloats( true ); // End date is non-inclusive QDate endDate = readICalDate( icaltime ).addDays( -1 ); mCompat->fixFloatingEnd( endDate ); if ( endDate < event->dtStart().date() ) { endDate = event->dtStart().date(); } event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) ); } else { event->setDtEnd(readICalDateTime(icaltime)); } break; // TODO: // at this point, there should be at least a start or end time. // fix up for events that take up no time but have a time associated #if 0 if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) anEvent->setDtStart(anEvent->dtEnd()); if (!(vo = isAPropertyOf(vevent, VCDTendProp))) anEvent->setDtEnd(anEvent->dtStart()); #endif // TODO: exdates #if 0 // recurrence exceptions if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } #endif #if 0 // secrecy if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else anEvent->setSecrecy("PUBLIC"); // attachments tmpStrList.clear(); initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttachProp) == 0) { tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } } anEvent->setAttachments(tmpStrList); // resources if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { QString resources = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStrList.clear(); index1 = 0; index2 = 0; QString resource; while ((index2 = resources.find(';', index1)) != -1) { resource = resources.mid(index1, (index2 - index1)); tmpStrList.append(resource); index1 = index2; } anEvent->setResources(tmpStrList); } #endif case ICAL_RELATEDTO_PROPERTY: // releated event (parent) event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); mEventsRelate.append(event); break; - case ICAL_TRANSP_PROPERTY: // Transparency - transparency = QString::fromUtf8(icalproperty_get_transp(p)); - if( transparency == "TRANSPARENT" ) + if(icalproperty_get_transp(p) == ICAL_TRANSP_TRANSPARENT ) event->setTransparency( Event::Transparent ); else event->setTransparency( Event::Opaque ); break; default: // kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY); } QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT"); if (!msade.isNull()) { bool floats = (msade == QString::fromLatin1("TRUE")); kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl; event->setFloats(floats); if (floats) { QDateTime endDate = event->dtEnd(); event->setDtEnd(endDate.addDays(-1)); } } // some stupid vCal exporters ignore the standard and use Description // instead of Summary for the default field. Correct for this. if (event->summary().isEmpty() && !(event->description().isEmpty())) { QString tmpStr = event->description().simplifyWhiteSpace(); event->setDescription(""); event->setSummary(tmpStr); } return event; } FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy) { FreeBusy *freebusy = new FreeBusy; readIncidenceBase(vfreebusy,freebusy); icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY); icaltimetype icaltime; icalperiodtype icalperiod; QDateTime period_start, period_end; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_DTSTART_PROPERTY: // start date and time icaltime = icalproperty_get_dtstart(p); freebusy->setDtStart(readICalDateTime(icaltime)); break; case ICAL_DTEND_PROPERTY: // start End Date and Time icaltime = icalproperty_get_dtend(p); freebusy->setDtEnd(readICalDateTime(icaltime)); break; case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times icalperiod = icalproperty_get_freebusy(p); period_start = readICalDateTime(icalperiod.start); period_end = readICalDateTime(icalperiod.end); freebusy->addPeriod(period_start, period_end); break; default: kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind << endl; break; } p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY); } return freebusy; } Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal) { Journal *journal = new Journal; readIncidence(vjournal,journal); return journal; } Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee) { icalparameter *p = 0; QString email = QString::fromUtf8(icalproperty_get_attendee(attendee)); QString name; QString uid = QString::null; p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER); if (p) { name = QString::fromUtf8(icalparameter_get_cn(p)); } else { } bool rsvp=false; p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER); if (p) { icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p); if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true; } Attendee::PartStat status = Attendee::NeedsAction; p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER); if (p) { icalparameter_partstat partStatParameter = icalparameter_get_partstat(p); switch(partStatParameter) { default: case ICAL_PARTSTAT_NEEDSACTION: status = Attendee::NeedsAction; break; case ICAL_PARTSTAT_ACCEPTED: status = Attendee::Accepted; break; case ICAL_PARTSTAT_DECLINED: status = Attendee::Declined; break; case ICAL_PARTSTAT_TENTATIVE: status = Attendee::Tentative; break; case ICAL_PARTSTAT_DELEGATED: status = Attendee::Delegated; break; case ICAL_PARTSTAT_COMPLETED: status = Attendee::Completed; break; case ICAL_PARTSTAT_INPROCESS: status = Attendee::InProcess; break; } } Attendee::Role role = Attendee::ReqParticipant; p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER); if (p) { icalparameter_role roleParameter = icalparameter_get_role(p); switch(roleParameter) { case ICAL_ROLE_CHAIR: role = Attendee::Chair; break; default: case ICAL_ROLE_REQPARTICIPANT: role = Attendee::ReqParticipant; break; case ICAL_ROLE_OPTPARTICIPANT: role = Attendee::OptParticipant; break; case ICAL_ROLE_NONPARTICIPANT: role = Attendee::NonParticipant; break; } } p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER); uid = icalparameter_get_xvalue(p); // This should be added, but there seems to be a libical bug here. /*while (p) { // if (icalparameter_get_xname(p) == "X-UID") { uid = icalparameter_get_xvalue(p); p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER); } */ return new Attendee( name, email, rsvp, status, role, uid ); } Attachment *ICalFormatImpl::readAttachment(icalproperty *attach) { - icalattachtype *a = icalproperty_get_attach(attach); + icalattach *a = icalproperty_get_attach(attach); icalparameter_value v = ICAL_VALUE_NONE; icalparameter_encoding e = ICAL_ENCODING_NONE; Attachment *attachment = 0; - + /* icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER); if (vp) v = icalparameter_get_value(vp); icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER); if (ep) e = icalparameter_get_encoding(ep); - - if (v == ICAL_VALUE_BINARY && e == ICAL_ENCODING_BASE64) - attachment = new Attachment(icalattachtype_get_base64(a)); - else if ((v == ICAL_VALUE_NONE || v == ICAL_VALUE_URI) && (e == ICAL_ENCODING_NONE || e == ICAL_ENCODING_8BIT)) { - attachment = new Attachment(QString(icalattachtype_get_url(a))); - } else { - kdWarning(5800) << "Unsupported attachment format, discarding it!" << endl; - return 0; + */ + int isurl = icalattach_get_is_url (a); + if (isurl == 0) + attachment = new Attachment((const char*)icalattach_get_data(a)); + else { + attachment = new Attachment(QString(icalattach_get_url(a))); } icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER); if (p) attachment->setMimeType(QString(icalparameter_get_fmttype(p))); return attachment; } #include <qtextcodec.h> void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence) { readIncidenceBase(parent,incidence); icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); bool readrec = false; const char *text; int intvalue; icaltimetype icaltime; icaldurationtype icalduration; struct icalrecurrencetype rectype; QStringList categories; while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_CREATED_PROPERTY: icaltime = icalproperty_get_created(p); incidence->setCreated(readICalDateTime(icaltime)); break; case ICAL_SEQUENCE_PROPERTY: // sequence intvalue = icalproperty_get_sequence(p); incidence->setRevision(intvalue); break; case ICAL_LASTMODIFIED_PROPERTY: // last modification date icaltime = icalproperty_get_lastmodified(p); incidence->setLastModified(readICalDateTime(icaltime)); break; case ICAL_DTSTART_PROPERTY: // start date and time icaltime = icalproperty_get_dtstart(p); if (icaltime.is_date) { incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0))); incidence->setFloats(true); } else { incidence->setDtStart(readICalDateTime(icaltime)); } break; case ICAL_DURATION_PROPERTY: // start date and time icalduration = icalproperty_get_duration(p); incidence->setDuration(readICalDuration(icalduration)); break; case ICAL_DESCRIPTION_PROPERTY: // description text = icalproperty_get_description(p); incidence->setDescription(QString::fromUtf8(text)); break; case ICAL_SUMMARY_PROPERTY: // summary { text = icalproperty_get_summary(p); incidence->setSummary(QString::fromUtf8(text)); } break; case ICAL_STATUS_PROPERTY: // summary { if ( ICAL_STATUS_CANCELLED == icalproperty_get_status(p) ) incidence->setCancelled( true ); } break; case ICAL_LOCATION_PROPERTY: // location text = icalproperty_get_location(p); incidence->setLocation(QString::fromUtf8(text)); break; #if 0 // status if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) { incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else incidence->setStatus("NEEDS ACTION"); #endif case ICAL_PRIORITY_PROPERTY: // priority intvalue = icalproperty_get_priority(p); incidence->setPriority(intvalue); break; case ICAL_CATEGORIES_PROPERTY: // categories text = icalproperty_get_categories(p); categories.append(QString::fromUtf8(text)); break; //******************************************* case ICAL_RRULE_PROPERTY: // we do need (maybe )start datetime of incidence for recurrence // such that we can read recurrence only after we read incidence completely readrec = true; rectype = icalproperty_get_rrule(p); break; case ICAL_EXDATE_PROPERTY: icaltime = icalproperty_get_exdate(p); incidence->addExDate(readICalDate(icaltime)); break; - case ICAL_CLASS_PROPERTY: - text = icalproperty_get_class(p); - if (strcmp(text,"PUBLIC") == 0) { + case ICAL_CLASS_PROPERTY: { + int inttext = icalproperty_get_class(p); + if (inttext == ICAL_CLASS_PUBLIC ) { incidence->setSecrecy(Incidence::SecrecyPublic); - } else if (strcmp(text,"CONFIDENTIAL") == 0) { + } else if (inttext == ICAL_CLASS_CONFIDENTIAL ) { incidence->setSecrecy(Incidence::SecrecyConfidential); } else { incidence->setSecrecy(Incidence::SecrecyPrivate); } + } break; case ICAL_ATTACH_PROPERTY: // attachments incidence->addAttachment(readAttachment(p)); break; default: // kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind // << endl; break; } p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); } if ( readrec ) { readRecurrenceRule(rectype,incidence); } // kpilot stuff // TODO: move this application-specific code to kpilot QString kp = incidence->nonKDECustomProperty("X-PILOTID"); if (!kp.isNull()) { incidence->setPilotId(kp.toInt()); } kp = incidence->nonKDECustomProperty("X-PILOTSTAT"); if (!kp.isNull()) { incidence->setSyncStatus(kp.toInt()); } kp = incidence->nonKDECustomProperty("X-ZAURUSID"); if (!kp.isNull()) { incidence->setZaurusId(kp.toInt()); } kp = incidence->nonKDECustomProperty("X-ZAURUSUID"); if (!kp.isNull()) { incidence->setZaurusUid(kp.toInt()); } kp = incidence->nonKDECustomProperty("X-ZAURUSSTAT"); if (!kp.isNull()) { incidence->setZaurusStat(kp.toInt()); } // Cancel backwards compatibility mode for subsequent changes by the application incidence->recurrence()->setCompatVersion(); // add categories incidence->setCategories(categories); // iterate through all alarms for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT); alarm; alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) { readAlarm(alarm,incidence); } } void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) { icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_UID_PROPERTY: // unique id incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p))); break; case ICAL_ORGANIZER_PROPERTY: // organizer incidenceBase->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p))); break; case ICAL_ATTENDEE_PROPERTY: // attendee incidenceBase->addAttendee(readAttendee(p)); break; default: break; } p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); } // custom properties readCustomProperties(parent, incidenceBase); } void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties) { QMap<QCString, QString> customProperties; icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY); while (p) { - QString value = QString::fromUtf8(icalproperty_get_x(p)); - customProperties[icalproperty_get_name(p)] = value; + customProperties[icalproperty_get_x_name(p)] = value; + //qDebug("ICalFormatImpl::readCustomProperties %s %s",value.latin1(), icalproperty_get_x_name(p) ); p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY); } properties->setCustomProperties(customProperties); } void ICalFormatImpl::readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *incidence) { // kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl; Recurrence *recur = incidence->recurrence(); recur->setCompatVersion(mCalendarVersion); recur->unsetRecurs(); struct icalrecurrencetype r = rrule; dumpIcalRecurrence(r); readRecurrence( r, recur, incidence); } void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur, Incidence *incidence) { int wkst; int index = 0; short day = 0; QBitArray qba(7); int frequ = r.freq; int interv = r.interval; // preprocessing for odd recurrence definitions if ( r.freq == ICAL_MONTHLY_RECURRENCE ) { if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { interv = 12; } } if ( r.freq == ICAL_YEARLY_RECURRENCE ) { if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX && r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) { frequ = ICAL_MONTHLY_RECURRENCE; interv = 12; } } switch (frequ) { case ICAL_MINUTELY_RECURRENCE: if (!icaltime_is_null_time(r.until)) { recur->setMinutely(interv,readICalDateTime(r.until)); } else { if (r.count == 0) recur->setMinutely(interv,-1); else recur->setMinutely(interv,r.count); } break; case ICAL_HOURLY_RECURRENCE: if (!icaltime_is_null_time(r.until)) { recur->setHourly(interv,readICalDateTime(r.until)); } else { if (r.count == 0) recur->setHourly(interv,-1); else recur->setHourly(interv,r.count); } break; case ICAL_DAILY_RECURRENCE: if (!icaltime_is_null_time(r.until)) { recur->setDaily(interv,readICalDate(r.until)); } else { if (r.count == 0) recur->setDaily(interv,-1); else recur->setDaily(interv,r.count); } break; case ICAL_WEEKLY_RECURRENCE: // kdDebug(5800) << "WEEKLY_RECURRENCE" << endl; wkst = (r.week_start + 5)%7 + 1; if (!icaltime_is_null_time(r.until)) { recur->setWeekly(interv,qba,readICalDate(r.until),wkst); } else { if (r.count == 0) recur->setWeekly(interv,qba,-1,wkst); else recur->setWeekly(interv,qba,r.count,wkst); } if ( r.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) { int wday = incidence->dtStart().date().dayOfWeek ()-1; //qDebug("weekly error found "); qba.setBit(wday); } else { while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug(5800) << " " << day << endl; qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 } } break; case ICAL_MONTHLY_RECURRENCE: if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { if (!icaltime_is_null_time(r.until)) { recur->setMonthly(Recurrence::rMonthlyPos,interv, readICalDate(r.until)); } else { if (r.count == 0) recur->setMonthly(Recurrence::rMonthlyPos,interv,-1); else recur->setMonthly(Recurrence::rMonthlyPos,interv,r.count); } bool useSetPos = false; short pos = 0; while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug(5800) << "----a " << index << ": " << day << endl; pos = icalrecurrencetype_day_position(day); if (pos) { day = icalrecurrencetype_day_day_of_week(day); QBitArray ba(7); // don't wipe qba ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 recur->addMonthlyPos(pos,ba); } else { qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 useSetPos = true; } } if (useSetPos) { if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { recur->addMonthlyPos(r.by_set_pos[0],qba); } } } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { if (!icaltime_is_null_time(r.until)) { recur->setMonthly(Recurrence::rMonthlyDay,interv, readICalDate(r.until)); } else { if (r.count == 0) recur->setMonthly(Recurrence::rMonthlyDay,interv,-1); else recur->setMonthly(Recurrence::rMonthlyDay,interv,r.count); } while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug(5800) << "----b " << day << endl; recur->addMonthlyDay(day); } } break; case ICAL_YEARLY_RECURRENCE: if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { if (!icaltime_is_null_time(r.until)) { recur->setYearly(Recurrence::rYearlyDay,interv, readICalDate(r.until)); } else { if (r.count == 0) recur->setYearly(Recurrence::rYearlyDay,interv,-1); else recur->setYearly(Recurrence::rYearlyDay,interv,r.count); } while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { recur->addYearlyNum(day); } } else if ( true /*r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX*/) { if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { if (!icaltime_is_null_time(r.until)) { recur->setYearly(Recurrence::rYearlyPos,interv, readICalDate(r.until)); } else { if (r.count == 0) recur->setYearly(Recurrence::rYearlyPos,interv,-1); else recur->setYearly(Recurrence::rYearlyPos,interv,r.count); } bool useSetPos = false; short pos = 0; while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { // kdDebug(5800) << "----a " << index << ": " << day << endl; pos = icalrecurrencetype_day_position(day); if (pos) { day = icalrecurrencetype_day_day_of_week(day); QBitArray ba(7); // don't wipe qba ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 recur->addYearlyMonthPos(pos,ba); } else { qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 useSetPos = true; } } if (useSetPos) { if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { recur->addYearlyMonthPos(r.by_set_pos[0],qba); } } } else { if (!icaltime_is_null_time(r.until)) { recur->setYearly(Recurrence::rYearlyMonth,interv, readICalDate(r.until)); } else { if (r.count == 0) recur->setYearly(Recurrence::rYearlyMonth,interv,-1); else recur->setYearly(Recurrence::rYearlyMonth,interv,r.count); } } if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX ) { index = 0; while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { recur->addYearlyNum(day); } } else { recur->addYearlyNum(incidence->dtStart().date().month()); } } break; default: ; break; } } void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence) { //kdDebug(5800) << "Read alarm for " << incidence->summary() << endl; Alarm* ialarm = incidence->newAlarm(); ialarm->setRepeatCount(0); ialarm->setEnabled(true); // Determine the alarm's action type icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY); if ( !p ) { return; } icalproperty_action action = icalproperty_get_action(p); Alarm::Type type = Alarm::Display; switch ( action ) { case ICAL_ACTION_DISPLAY: type = Alarm::Display; break; case ICAL_ACTION_AUDIO: type = Alarm::Audio; break; case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break; case ICAL_ACTION_EMAIL: type = Alarm::Email; break; default: ; return; } ialarm->setType(type); p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY); while (p) { icalproperty_kind kind = icalproperty_isa(p); switch (kind) { case ICAL_TRIGGER_PROPERTY: { icaltriggertype trigger = icalproperty_get_trigger(p); if (icaltime_is_null_time(trigger.time)) { if (icaldurationtype_is_null_duration(trigger.duration)) { kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl; } else { Duration duration = icaldurationtype_as_int( trigger.duration ); icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER); if (param && icalparameter_get_related(param) == ICAL_RELATED_END) ialarm->setEndOffset(duration); else ialarm->setStartOffset(duration); } } else { ialarm->setTime(readICalDateTime(trigger.time)); } break; } case ICAL_DURATION_PROPERTY: { icaldurationtype duration = icalproperty_get_duration(p); ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60); break; } case ICAL_REPEAT_PROPERTY: ialarm->setRepeatCount(icalproperty_get_repeat(p)); break; // Only in DISPLAY and EMAIL and PROCEDURE alarms case ICAL_DESCRIPTION_PROPERTY: { QString description = QString::fromUtf8(icalproperty_get_description(p)); switch ( action ) { case ICAL_ACTION_DISPLAY: ialarm->setText( description ); break; case ICAL_ACTION_PROCEDURE: ialarm->setProgramArguments( description ); break; case ICAL_ACTION_EMAIL: ialarm->setMailText( description ); break; default: break; } break; } // Only in EMAIL alarm case ICAL_SUMMARY_PROPERTY: ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p))); break; // Only in EMAIL alarm case ICAL_ATTENDEE_PROPERTY: { QString email = QString::fromUtf8(icalproperty_get_attendee(p)); QString name; icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER); if (param) { name = QString::fromUtf8(icalparameter_get_cn(param)); } ialarm->addMailAddress(Person(name, email)); break; } // Only in AUDIO and EMAIL and PROCEDURE alarms case ICAL_ATTACH_PROPERTY: { - icalattachtype *attach = icalproperty_get_attach(p); - QString url = QFile::decodeName(icalattachtype_get_url(attach)); + icalattach *attach = icalproperty_get_attach(p); + QString url = QFile::decodeName(icalattach_get_url(attach)); switch ( action ) { case ICAL_ACTION_AUDIO: ialarm->setAudioFile( url ); break; case ICAL_ACTION_PROCEDURE: ialarm->setProgramFile( url ); break; case ICAL_ACTION_EMAIL: ialarm->addMailAttachment( url ); break; default: break; } break; } default: break; } p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY); } // custom properties readCustomProperties(alarm, ialarm); // TODO: check for consistency of alarm properties } icaltimetype ICalFormatImpl::writeICalDate(const QDate &date) { icaltimetype t; t.year = date.year(); t.month = date.month(); t.day = date.day(); t.hour = 0; t.minute = 0; t.second = 0; t.is_date = 1; t.is_utc = 0; t.zone = 0; return t; } icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt ) { icaltimetype t; t.is_date = 0; t.zone = 0; QDateTime datetime; if ( mParent->utc() ) { int offset = KGlobal::locale()->localTimeOffset( dt ); datetime = dt.addSecs ( -offset*60); t.is_utc = 1; } else { datetime = dt; t.is_utc = 0; } t.year = datetime.date().year(); t.month = datetime.date().month(); t.day = datetime.date().day(); t.hour = datetime.time().hour(); t.minute = datetime.time().minute(); t.second = datetime.time().second(); //qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); // if ( mParent->utc() ) { // datetime = KGlobal::locale()->localTime( dt ); // qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); // if (mParent->timeZoneId().isEmpty()) // t = icaltime_as_utc(t, 0); // else // t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit()); // } return t; } QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t) { QDateTime dt (QDate(t.year,t.month,t.day), QTime(t.hour,t.minute,t.second) ); if (t.is_utc) { int offset = KGlobal::locale()->localTimeOffset( dt ); dt = dt.addSecs ( offset*60); } return dt; } QDate ICalFormatImpl::readICalDate(icaltimetype t) { return QDate(t.year,t.month,t.day); } icaldurationtype ICalFormatImpl::writeICalDuration(int seconds) { icaldurationtype d; d.weeks = seconds % gSecondsPerWeek; seconds -= d.weeks * gSecondsPerWeek; d.days = seconds % gSecondsPerDay; seconds -= d.days * gSecondsPerDay; d.hours = seconds % gSecondsPerHour; seconds -= d.hours * gSecondsPerHour; d.minutes = seconds % gSecondsPerMinute; seconds -= d.minutes * gSecondsPerMinute; d.seconds = seconds; d.is_neg = 0; return d; } int ICalFormatImpl::readICalDuration(icaldurationtype d) { int result = 0; result += d.weeks * gSecondsPerWeek; result += d.days * gSecondsPerDay; result += d.hours * gSecondsPerHour; result += d.minutes * gSecondsPerMinute; result += d.seconds; if (d.is_neg) result *= -1; return result; } icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal) { icalcomponent *calendar; // Root component calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); icalproperty *p; // Product Identifier p = icalproperty_new_prodid(CalFormat::productId().utf8()); icalcomponent_add_property(calendar,p); // TODO: Add time zone // iCalendar version (2.0) p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION)); icalcomponent_add_property(calendar,p); // Custom properties if( cal != 0 ) writeCustomProperties(calendar, cal); return calendar; } // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. // and break it down from its tree-like format into the dictionary format // that is used internally in the ICalFormatImpl. bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar) { // this function will populate the caldict dictionary and other event // lists. It turns vevents into Events and then inserts them. if (!calendar) return false; // TODO: check for METHOD #if 0 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { char *methodType = 0; methodType = fakeCString(vObjectUStringZValue(curVO)); if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This calendar is an iTIP transaction of type \"%1\".") .arg(methodType), i18n("%1: iTIP Transaction").arg(CalFormat::application())); delete methodType; } #endif icalproperty *p; p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY); if (!p) { // TODO: does no PRODID really matter? // mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); // return false; mLoadedProductId = ""; mCalendarVersion = 0; } else { mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p)); mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId); delete mCompat; mCompat = CompatFactory::createCompat( mLoadedProductId ); } // TODO: check for unknown PRODID #if 0 if (!mCalendarVersion && CalFormat::productId() != mLoadedProductId) { // warn the user that we might have trouble reading non-known calendar. if (mEnableDialogs) KMessageBox::information(mTopWidget, i18n("This vCalendar file was not created by KOrganizer " "or any other product we support. Loading anyway..."), i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application())); } #endif p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY); if (!p) { mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return false; } else { const char *version = icalproperty_get_version(p); if (strcmp(version,"1.0") == 0) { mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1, i18n("Expected iCalendar format"))); return false; } else if (strcmp(version,"2.0") != 0) { mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return false; } } // TODO: check for calendar format version #if 0 // warn the user we might have trouble reading this unknown version. if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); if (strcmp(_VCAL_VERSION, s) != 0) if (mEnableDialogs) KMessageBox::sorry(mTopWidget, i18n("This vCalendar file has version %1.\n" "We only support %2.") .arg(s).arg(_VCAL_VERSION), i18n("%1: Unknown vCalendar Version").arg(CalFormat::application())); deleteStr(s); } #endif // custom properties readCustomProperties(calendar, cal); // TODO: set time zone #if 0 // set the time zone if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); cal->setTimeZone(s); deleteStr(s); } #endif // Store all events with a relatedTo property in a list for post-processing mEventsRelate.clear(); mTodosRelate.clear(); // TODO: make sure that only actually added ecvens go to this lists. icalcomponent *c; // Iterate through all todos c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT); while (c) { // kdDebug(5800) << "----Todo found" << endl; Todo *todo = readTodo(c); if (!cal->todo(todo->uid())) cal->addTodo(todo); c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT); } // Iterate through all events c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT); while (c) { // kdDebug(5800) << "----Event found" << endl; Event *event = readEvent(c); if (!cal->event(event->uid())) cal->addEvent(event); c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT); } // Iterate through all journals c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT); while (c) { // kdDebug(5800) << "----Journal found" << endl; Journal *journal = readJournal(c); if (!cal->journal(journal->uid())) cal->addJournal(journal); c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT); } #if 0 initPropIterator(&i, vcal); // go through all the vobjects in the vcal while (moreIteration(&i)) { curVO = nextVObject(&i); /************************************************************************/ // now, check to see that the object is an event or todo. if (strcmp(vObjectName(curVO), VCEventProp) == 0) { if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { char *s; s = fakeCString(vObjectUStringZValue(curVOProp)); // check to see if event was deleted by the kpilot conduit if (atoi(s) == Event::SYNCDEL) { deleteStr(s); goto SKIP; } deleteStr(s); } // this code checks to see if we are trying to read in an event // that we already find to be in the calendar. If we find this // to be the case, we skip the event. if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVOProp)); QString tmpStr(s); deleteStr(s); if (cal->event(tmpStr)) { goto SKIP; } if (cal->todo(tmpStr)) { goto SKIP; } } if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; goto SKIP; } anEvent = VEventToEvent(curVO); // we now use addEvent instead of insertEvent so that the // signal/slot get connected. if (anEvent) cal->addEvent(anEvent); else { // some sort of error must have occurred while in translation. goto SKIP; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { anEvent = VTodoToEvent(curVO); cal->addTodo(anEvent); } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { // do nothing, we know these properties and we want to skip them. // we have either already processed them or are ignoring them. ; } else { ; } SKIP: ; } // while #endif // Post-Process list of events with relations, put Event objects in relation Event *ev; for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { ev->setRelatedTo(cal->event(ev->relatedToUid())); } Todo *todo; for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { todo->setRelatedTo(cal->todo(todo->relatedToUid())); } return true; } QString ICalFormatImpl::extractErrorProperty(icalcomponent *c) { // kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " // << icalcomponent_as_ical_string(c) << endl; QString errorMessage; icalproperty *error; error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY); while(error) { errorMessage += icalproperty_get_xlicerror(error); errorMessage += "\n"; error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY); } // kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl; return errorMessage; } void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r) { int i; if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Day: "; while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } } if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Month Day: "; while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } } if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Year Day: "; while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } } if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Month: "; while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } } if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { int index = 0; QString out = " By Set Pos: "; while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { out.append(QString::number(i) + " "); } } } icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence, Scheduler::Method method) { icalcomponent *message = createCalendarComponent(); icalproperty_method icalmethod = ICAL_METHOD_NONE; switch (method) { case Scheduler::Publish: icalmethod = ICAL_METHOD_PUBLISH; break; case Scheduler::Request: icalmethod = ICAL_METHOD_REQUEST; break; case Scheduler::Refresh: icalmethod = ICAL_METHOD_REFRESH; break; case Scheduler::Cancel: icalmethod = ICAL_METHOD_CANCEL; break; case Scheduler::Add: icalmethod = ICAL_METHOD_ADD; break; case Scheduler::Reply: icalmethod = ICAL_METHOD_REPLY; break; case Scheduler::Counter: icalmethod = ICAL_METHOD_COUNTER; break; case Scheduler::Declinecounter: icalmethod = ICAL_METHOD_DECLINECOUNTER; break; default: return message; } icalcomponent_add_property(message,icalproperty_new_method(icalmethod)); // TODO: check, if dynamic cast is required if(incidence->type() == "Todo") { Todo *todo = static_cast<Todo *>(incidence); icalcomponent_add_component(message,writeTodo(todo)); } if(incidence->type() == "Event") { Event *event = static_cast<Event *>(incidence); icalcomponent_add_component(message,writeEvent(event)); } if(incidence->type() == "FreeBusy") { FreeBusy *freebusy = static_cast<FreeBusy *>(incidence); icalcomponent_add_component(message,writeFreeBusy(freebusy, method)); } return message; } diff --git a/libkcal/icalformatimpl.h b/libkcal/icalformatimpl.h index 2f32365..203c302 100644 --- a/libkcal/icalformatimpl.h +++ b/libkcal/icalformatimpl.h @@ -1,109 +1,109 @@ /* This file is part of libkcal. Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifndef ICALFORMATIMPL_H #define ICALFORMATIMPL_H #include <qstring.h> #include "scheduler.h" #include "freebusy.h" extern "C" { #include <ical.h> #include <icalss.h> } namespace KCal { class Compat; /** This class provides the libical dependent functions for ICalFormat. */ class ICalFormatImpl { public: /** Create new iCal format for calendar object */ ICalFormatImpl( ICalFormat *parent ); virtual ~ICalFormatImpl(); bool populate( Calendar *, icalcomponent *fs); icalcomponent *writeIncidence(Incidence *incidence); icalcomponent *writeTodo(Todo *todo); icalcomponent *writeEvent(Event *event); icalcomponent *writeFreeBusy(FreeBusy *freebusy, Scheduler::Method method); icalcomponent *writeJournal(Journal *journal); void writeIncidence(icalcomponent *parent,Incidence *incidence); icalproperty *writeAttendee(Attendee *attendee); icalproperty *writeAttachment(Attachment *attach); icalproperty *writeRecurrenceRule(Recurrence *); - icalproperty *writeAlarm(Alarm *alarm); + icalcomponent *writeAlarm(Alarm *alarm); QString extractErrorProperty(icalcomponent *); Todo *readTodo(icalcomponent *vtodo); Event *readEvent(icalcomponent *vevent); FreeBusy *readFreeBusy(icalcomponent *vfreebusy); Journal *readJournal(icalcomponent *vjournal); Attendee *readAttendee(icalproperty *attendee); Attachment *readAttachment(icalproperty *attach); void readIncidence(icalcomponent *parent,Incidence *incidence); void readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *event); void readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur,Incidence *event ); void readAlarm(icalcomponent *alarm,Incidence *incidence); /** Return the PRODID string loaded from calendar file */ const QString &loadedProductId() { return mLoadedProductId; } icaltimetype writeICalDate(const QDate &); QDate readICalDate(icaltimetype); icaltimetype writeICalDateTime(const QDateTime &); QDateTime readICalDateTime(icaltimetype); icaldurationtype writeICalDuration(int seconds); int readICalDuration(icaldurationtype); icalcomponent *createCalendarComponent(Calendar * = 0); icalcomponent *createScheduleComponent(IncidenceBase *,Scheduler::Method); private: void writeIncidenceBase(icalcomponent *parent,IncidenceBase *); void readIncidenceBase(icalcomponent *parent,IncidenceBase *); void writeCustomProperties(icalcomponent *parent,CustomProperties *); void readCustomProperties(icalcomponent *parent,CustomProperties *); void dumpIcalRecurrence(icalrecurrencetype); ICalFormat *mParent; Calendar *mCalendar; QString mLoadedProductId; // PRODID string loaded from calendar file int mCalendarVersion; // determines backward compatibility mode on read QPtrList<Event> mEventsRelate; // events with relations QPtrList<Todo> mTodosRelate; // todos with relations static const int mSecondsPerWeek; static const int mSecondsPerDay; static const int mSecondsPerHour; static const int mSecondsPerMinute; Compat *mCompat; }; } #endif diff --git a/libkcal/vcalformat.cpp b/libkcal/vcalformat.cpp index 59030d5..72a781a 100644 --- a/libkcal/vcalformat.cpp +++ b/libkcal/vcalformat.cpp @@ -1,1678 +1,1678 @@ /* This file is part of libkcal. Copyright (c) 1998 Preston Brwon Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include <qapplication.h> #include <qdatetime.h> #include <qstring.h> #include <qptrlist.h> #include <qregexp.h> #include <qclipboard.h> #include <qdialog.h> #include <qfile.h> #include <kdebug.h> #include <kmessagebox.h> #include <kiconloader.h> #include <klocale.h> #include "vcc.h" #include "vobject.h" #include "vcaldrag.h" #include "calendar.h" #include "vcalformat.h" using namespace KCal; VCalFormat::VCalFormat() { } VCalFormat::~VCalFormat() { } bool VCalFormat::load(Calendar *calendar, const QString &fileName) { mCalendar = calendar; clearException(); kdDebug(5800) << "VCalFormat::load() " << fileName << endl; VObject *vcal = 0; // this is not necessarily only 1 vcal. Could be many vcals, or include // a vcard... vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data())); if (!vcal) { setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); return FALSE; } // any other top-level calendar stuff should be added/initialized here // put all vobjects into their proper places populate(vcal); // clean up from vcal API stuff cleanVObjects(vcal); cleanStrTbl(); return true; } bool VCalFormat::save(Calendar *calendar, const QString &fileName) { mCalendar = calendar; QString tmpStr; VObject *vcal, *vo; kdDebug(5800) << "VCalFormat::save(): " << fileName << endl; vcal = newVObject(VCCalProp); // addPropValue(vcal,VCLocationProp, "0.0"); addPropValue(vcal,VCProdIdProp, productId()); tmpStr = mCalendar->getTimeZoneStr(); //qDebug("mCalendar->getTimeZoneStr() %s",tmpStr.latin1() ); addPropValue(vcal,VCTimeZoneProp, tmpStr.local8Bit()); addPropValue(vcal,VCVersionProp, _VCAL_VERSION); // TODO STUFF QPtrList<Todo> todoList = mCalendar->rawTodos(); QPtrListIterator<Todo> qlt(todoList); for (; qlt.current(); ++qlt) { vo = eventToVTodo(qlt.current()); addVObjectProp(vcal, vo); } // EVENT STUFF QPtrList<Event> events = mCalendar->rawEvents(); Event *ev; for(ev=events.first();ev;ev=events.next()) { vo = eventToVEvent(ev); addVObjectProp(vcal, vo); } writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal); cleanVObjects(vcal); cleanStrTbl(); if (QFile::exists(fileName)) { kdDebug(5800) << "No error" << endl; return true; } else { kdDebug(5800) << "Error" << endl; return false; // error } } bool VCalFormat::fromString( Calendar *calendar, const QString &text ) { // TODO: Factor out VCalFormat::fromString() QCString data = text.utf8(); if ( !data.size() ) return false; VObject *vcal = Parse_MIME( data.data(), data.size()); if ( !vcal ) return false; VObjectIterator i; VObject *curvo; initPropIterator( &i, vcal ); // we only take the first object. TODO: parse all incidences. do { curvo = nextVObject( &i ); } while ( strcmp( vObjectName( curvo ), VCEventProp ) && strcmp( vObjectName( curvo ), VCTodoProp ) ); if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) { Event *event = VEventToEvent( curvo ); calendar->addEvent( event ); } else { kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl; deleteVObject( vcal ); return false; } deleteVObject( vcal ); return true; } QString VCalFormat::toString( Calendar *calendar ) { // TODO: Factor out VCalFormat::asString() VObject *vcal = newVObject(VCCalProp); addPropValue( vcal, VCProdIdProp, CalFormat::productId() ); QString tmpStr = mCalendar->getTimeZoneStr(); addPropValue( vcal, VCTimeZoneProp, tmpStr.local8Bit() ); addPropValue( vcal, VCVersionProp, _VCAL_VERSION ); // TODO: Use all data. QPtrList<Event> events = calendar->events(); Event *event = events.first(); if ( !event ) return QString::null; VObject *vevent = eventToVEvent( event ); addVObjectProp( vcal, vevent ); char *buf = writeMemVObject( 0, 0, vcal ); QString result( buf ); cleanVObject( vcal ); return result; } VObject *VCalFormat::eventToVTodo(const Todo *anEvent) { VObject *vtodo; QString tmpStr; QStringList tmpStrList; vtodo = newVObject(VCTodoProp); // due date if (anEvent->hasDueDate()) { tmpStr = qDateTimeToISO(anEvent->dtDue(), !anEvent->doesFloat()); addPropValue(vtodo, VCDueProp, tmpStr.local8Bit()); } // start date if (anEvent->hasStartDate()) { tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vtodo, VCUniqueStringProp, anEvent->uid().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit()); // organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit()); // attendees if (anEvent->attendeeCount() != 0) { QPtrList<Attendee> al = anEvent->attendees(); QPtrListIterator<Attendee> ai(al); Attendee *curAttendee; for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE"); addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // description BL: if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vtodo, VCDescriptionProp, anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit()); if (!anEvent->location().isEmpty()) addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit()); // completed // status // backward compatibility, KOrganizer used to interpret only these two values addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : "NEEDS_ACTION"); // completion date if (anEvent->hasCompletedDate()) { tmpStr = qDateTimeToISO(anEvent->completed()); addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit()); } // priority tmpStr.sprintf("%i",anEvent->priority()); addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vtodo, VCRelatedToProp, anEvent->relatedTo()->uid().local8Bit()); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit()); } // alarm stuff kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl; QPtrList<Alarm> alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a = addProp(vtodo, VCDAlarmProp); tmpStr = qDateTimeToISO(alarm->time()); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); if (alarm->type() == Alarm::Audio) { a = addProp(vtodo, VCAAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } else if (alarm->type() == Alarm::Procedure) { a = addProp(vtodo, VCPAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } } } if (anEvent->pilotId()) { // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); - addPropValue(vtodo, KPilotIdProp, tmpStr.local8Bit()); + addPropValue(vtodo, XPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); - addPropValue(vtodo, KPilotStatusProp, tmpStr.local8Bit()); + addPropValue(vtodo, XPilotStatusProp, tmpStr.local8Bit()); } return vtodo; } VObject* VCalFormat::eventToVEvent(const Event *anEvent) { VObject *vevent; QString tmpStr; QStringList tmpStrList; vevent = newVObject(VCEventProp); // start and end time tmpStr = qDateTimeToISO(anEvent->dtStart(), !anEvent->doesFloat()); addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit()); // events that have time associated but take up no time should // not have both DTSTART and DTEND. if (anEvent->dtStart() != anEvent->dtEnd()) { tmpStr = qDateTimeToISO(anEvent->dtEnd(), !anEvent->doesFloat()); addPropValue(vevent, VCDTendProp, tmpStr.local8Bit()); } // creation date tmpStr = qDateTimeToISO(anEvent->created()); addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit()); // unique id addPropValue(vevent, VCUniqueStringProp, anEvent->uid().local8Bit()); // revision tmpStr.sprintf("%i", anEvent->revision()); addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit()); // last modification date tmpStr = qDateTimeToISO(anEvent->lastModified()); addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit()); // attendee and organizer stuff tmpStr = "MAILTO:" + anEvent->organizer(); addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit()); if (anEvent->attendeeCount() != 0) { QPtrList<Attendee> al = anEvent->attendees(); QPtrListIterator<Attendee> ai(al); Attendee *curAttendee; // TODO: Put this functionality into Attendee class for (; ai.current(); ++ai) { curAttendee = ai.current(); if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + ">"; else if (curAttendee->name().isEmpty()) tmpStr = "MAILTO: " + curAttendee->email(); else if (curAttendee->email().isEmpty()) tmpStr = "MAILTO: " + curAttendee->name(); else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl; VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit()); addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");; addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status())); } } // recurrence rule stuff if (anEvent->recurrence()->doesRecur()) { // some more variables QPtrList<Recurrence::rMonthPos> tmpPositions; QPtrList<int> tmpDays; int *tmpDay; Recurrence::rMonthPos *tmpPos; QString tmpStr2; int i; switch(anEvent->recurrence()->doesRecur()) { case Recurrence::rDaily: tmpStr.sprintf("D%i ",anEvent->recurrence()->frequency()); // if (anEvent->rDuration > 0) // tmpStr += "#"; break; case Recurrence::rWeekly: tmpStr.sprintf("W%i ",anEvent->recurrence()->frequency()); for (i = 0; i < 7; i++) { if (anEvent->recurrence()->days().testBit(i)) tmpStr += dayFromNum(i); } break; case Recurrence::rMonthlyPos: tmpStr.sprintf("MP%i ", anEvent->recurrence()->frequency()); // write out all rMonthPos's tmpPositions = anEvent->recurrence()->monthPositions(); for (tmpPos = tmpPositions.first(); tmpPos; tmpPos = tmpPositions.next()) { tmpStr2.sprintf("%i", tmpPos->rPos); if (tmpPos->negative) tmpStr2 += "- "; else tmpStr2 += "+ "; tmpStr += tmpStr2; for (i = 0; i < 7; i++) { if (tmpPos->rDays.testBit(i)) tmpStr += dayFromNum(i); } } // loop for all rMonthPos's break; case Recurrence::rMonthlyDay: tmpStr.sprintf("MD%i ", anEvent->recurrence()->frequency()); // write out all rMonthDays; tmpDays = anEvent->recurrence()->monthDays(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyMonth: tmpStr.sprintf("YM%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; case Recurrence::rYearlyDay: tmpStr.sprintf("YD%i ", anEvent->recurrence()->frequency()); // write out all the rYearNums; tmpDays = anEvent->recurrence()->yearNums(); for (tmpDay = tmpDays.first(); tmpDay; tmpDay = tmpDays.next()) { tmpStr2.sprintf("%i ", *tmpDay); tmpStr += tmpStr2; } break; default: kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl; break; } // switch if (anEvent->recurrence()->duration() > 0) { tmpStr2.sprintf("#%i",anEvent->recurrence()->duration()); tmpStr += tmpStr2; } else if (anEvent->recurrence()->duration() == -1) { tmpStr += "#0"; // defined as repeat forever } else { tmpStr += qDateTimeToISO(anEvent->recurrence()->endDate(), FALSE); } addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit()); } // event repeats // exceptions to recurrence DateList dateList = anEvent->exDates(); DateList::ConstIterator it; QString tmpStr2; for (it = dateList.begin(); it != dateList.end(); ++it) { tmpStr = qDateToISO(*it) + ";"; tmpStr2 += tmpStr; } if (!tmpStr2.isEmpty()) { tmpStr2.truncate(tmpStr2.length()-1); - addPropValue(vevent, VCExDateProp, tmpStr2.local8Bit()); + addPropValue(vevent, VCExpDateProp, tmpStr2.local8Bit()); } // description if (!anEvent->description().isEmpty()) { VObject *d = addPropValue(vevent, VCDescriptionProp, anEvent->description().local8Bit()); if (anEvent->description().find('\n') != -1) addProp(d, VCQuotedPrintableProp); } // summary if (!anEvent->summary().isEmpty()) addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit()); if (!anEvent->location().isEmpty()) addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit()); // status // TODO: define Event status // addPropValue(vevent, VCStatusProp, anEvent->statusStr().local8Bit()); // secrecy const char *text = 0; switch (anEvent->secrecy()) { case Incidence::SecrecyPublic: text = "PUBLIC"; break; case Incidence::SecrecyPrivate: text = "PRIVATE"; break; case Incidence::SecrecyConfidential: text = "CONFIDENTIAL"; break; } if (text) { addPropValue(vevent, VCClassProp, text); } // categories tmpStrList = anEvent->categories(); tmpStr = ""; QString catStr; for ( QStringList::Iterator it = tmpStrList.begin(); it != tmpStrList.end(); ++it ) { catStr = *it; if (catStr[0] == ' ') tmpStr += catStr.mid(1); else tmpStr += catStr; // this must be a ';' character as the vCalendar specification requires! // vcc.y has been hacked to translate the ';' to a ',' when the vcal is // read in. tmpStr += ";"; } if (!tmpStr.isEmpty()) { tmpStr.truncate(tmpStr.length()-1); addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit()); } // attachments // TODO: handle binary attachments! QPtrList<Attachment> attachments = anEvent->attachments(); for ( Attachment *at = attachments.first(); at; at = attachments.next() ) addPropValue(vevent, VCAttachProp, at->uri().local8Bit()); // resources tmpStrList = anEvent->resources(); tmpStr = tmpStrList.join(";"); if (!tmpStr.isEmpty()) addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit()); // alarm stuff QPtrList<Alarm> alarms = anEvent->alarms(); Alarm* alarm; for (alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { VObject *a = addProp(vevent, VCDAlarmProp); tmpStr = qDateTimeToISO(alarm->time()); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCDisplayStringProp, "beep!"); if (alarm->type() == Alarm::Audio) { a = addProp(vevent, VCAAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile())); } if (alarm->type() == Alarm::Procedure) { a = addProp(vevent, VCPAlarmProp); addPropValue(a, VCRunTimeProp, tmpStr.local8Bit()); addPropValue(a, VCRepeatCountProp, "1"); addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile())); } } } // priority tmpStr.sprintf("%i",anEvent->priority()); addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit()); // transparency tmpStr.sprintf("%i",anEvent->transparency()); addPropValue(vevent, VCTranspProp, tmpStr.local8Bit()); // related event if (anEvent->relatedTo()) { addPropValue(vevent, VCRelatedToProp, anEvent->relatedTo()->uid().local8Bit()); } if (anEvent->pilotId()) { // pilot sync stuff tmpStr.sprintf("%i",anEvent->pilotId()); - addPropValue(vevent, KPilotIdProp, tmpStr.local8Bit()); + addPropValue(vevent, XPilotIdProp, tmpStr.local8Bit()); tmpStr.sprintf("%i",anEvent->syncStatus()); - addPropValue(vevent, KPilotStatusProp, tmpStr.local8Bit()); + addPropValue(vevent, XPilotStatusProp, tmpStr.local8Bit()); } return vevent; } Todo *VCalFormat::VTodoToEvent(VObject *vtodo) { VObject *vo; VObjectIterator voi; char *s; Todo *anEvent = new Todo; // creation date if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vtodo, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // last modification date if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // attendees. initPropIterator(&voi, vtodo); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // description for todo if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setDescription(QString::fromLocal8Bit(s)); deleteStr(s); } // summary if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setSummary(QString::fromLocal8Bit(s)); deleteStr(s); } if ((vo = isAPropertyOf(vtodo, VCLocationProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setLocation(QString::fromLocal8Bit(s)); deleteStr(s); } // completed // was: status if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (strcmp(s,"COMPLETED") == 0) { anEvent->setCompleted(true); } else { anEvent->setCompleted(false); } deleteStr(s); } else anEvent->setCompleted(false); // completion date if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) { anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // priority if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) { anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // due date if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) { anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); anEvent->setHasDueDate(true); } else { anEvent->setHasDueDate(false); } // start time if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); anEvent->setHasStartDate(true); } else { anEvent->setHasStartDate(false); } /* alarm stuff */ //kdDebug(5800) << "vcalformat::VTodoToEvent called" << endl; if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) { Alarm* alarm = anEvent->newAlarm(); VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } alarm->setEnabled(true); if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setProcedureAlarm(QFile::decodeName(s)); deleteStr(s); } } if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setAudioAlarm(QFile::decodeName(s)); deleteStr(s); } } } // related todo if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) { anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); mTodosRelate.append(anEvent); } // categories QStringList tmpStrList; int index1 = 0; int index2 = 0; if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); QString categories = QString::fromLocal8Bit(s); deleteStr(s); //const char* category; QString category; while ((index2 = categories.find(',', index1)) != -1) { //category = (const char *) categories.mid(index1, (index2 - index1)); category = categories.mid(index1, (index2 - index1)); tmpStrList.append(category); index1 = index2+1; } // get last category category = categories.mid(index1, (categories.length()-index1)); tmpStrList.append(category); anEvent->setCategories(tmpStrList); } /* PILOT SYNC STUFF */ - if ((vo = isAPropertyOf(vtodo, KPilotIdProp))) { + if ((vo = isAPropertyOf(vtodo, XPilotIdProp))) { anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setPilotId(0); - if ((vo = isAPropertyOf(vtodo, KPilotStatusProp))) { + if ((vo = isAPropertyOf(vtodo, XPilotStatusProp))) { anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setSyncStatus(Event::SYNCMOD); return anEvent; } Event* VCalFormat::VEventToEvent(VObject *vevent) { VObject *vo; VObjectIterator voi; char *s; Event *anEvent = new Event; // creation date if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) { anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // unique id vo = isAPropertyOf(vevent, VCUniqueStringProp); // while the UID property is preferred, it is not required. We'll use the // default Event UID if none is given. if (vo) { anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } // revision // again NSCAL doesn't give us much to work with, so we improvise... if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) { anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setRevision(0); // last modification date if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) { anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setLastModified(QDateTime(QDate::currentDate(), QTime::currentTime())); // organizer // if our extension property for the event's ORGANIZER exists, add it. if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) { anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); } else { anEvent->setOrganizer(mCalendar->getEmail()); } // deal with attendees. initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) { Attendee *a; VObject *vp; s = fakeCString(vObjectUStringZValue(vo)); QString tmpStr = QString::fromLocal8Bit(s); deleteStr(s); tmpStr = tmpStr.simplifyWhiteSpace(); int emailPos1, emailPos2; if ((emailPos1 = tmpStr.find('<')) > 0) { // both email address and name emailPos2 = tmpStr.findRev('>'); a = new Attendee(tmpStr.left(emailPos1 - 1), tmpStr.mid(emailPos1 + 1, emailPos2 - (emailPos1 + 1))); } else if (tmpStr.find('@') > 0) { // just an email address a = new Attendee(0, tmpStr); } else { // just a name QString email = tmpStr.replace( QRegExp(" "), "." ); a = new Attendee(tmpStr,email); } // is there an RSVP property? if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) a->setRSVP(vObjectStringZValue(vp)); // is there a status property? if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) a->setStatus(readStatus(vObjectStringZValue(vp))); // add the attendee anEvent->addAttendee(a); } } // This isn't strictly true. An event that doesn't have a start time // or an end time doesn't "float", it has an anchor in time but it doesn't // "take up" any time. /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) || (isAPropertyOf(vevent, VCDTendProp) == 0)) { anEvent->setFloats(TRUE); } else { }*/ anEvent->setFloats(FALSE); // start time if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) { anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); // kdDebug(5800) << "s is " << // s << ", ISO is " << ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))).toString() << endl; deleteStr(s); if (anEvent->dtStart().time().isNull()) anEvent->setFloats(TRUE); } // stop time if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) { anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); if (anEvent->dtEnd().time().isNull()) anEvent->setFloats(TRUE); } // at this point, there should be at least a start or end time. // fix up for events that take up no time but have a time associated if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) anEvent->setDtStart(anEvent->dtEnd()); if (!(vo = isAPropertyOf(vevent, VCDTendProp))) anEvent->setDtEnd(anEvent->dtStart()); /////////////////////////////////////////////////////////////////////////// // repeat stuff if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) { QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStr.simplifyWhiteSpace(); tmpStr = tmpStr.upper(); /********************************* DAILY ******************************/ if (tmpStr.left(1) == "D") { int index = tmpStr.find(' '); int rFreq = tmpStr.mid(1, (index-1)).toInt(); index = tmpStr.findRev(' ') + 1; // advance to last field if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setDaily(rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) // VEvents set this to 0 forever, we use -1 anEvent->recurrence()->setDaily(rFreq, -1); else anEvent->recurrence()->setDaily(rFreq, rDuration); } } /********************************* WEEKLY ******************************/ else if (tmpStr.left(1) == "W") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(1, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); QString dayStr; if( index == last ) { // e.g. W1 #0 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); } else { // e.g. W1 SU #0 while (index < last) { dayStr = tmpStr.mid(index, 3); int dayNum = numFromDay(dayStr); qba.setBit(dayNum); index += 3; // advance to next day, or possibly "#" } } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setWeekly(rFreq, qba, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setWeekly(rFreq, qba, -1); else anEvent->recurrence()->setWeekly(rFreq, qba, rDuration); } } /**************************** MONTHLY-BY-POS ***************************/ else if (tmpStr.left(2) == "MP") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; // advance to beginning of stuff after freq QBitArray qba(7); short tmpPos; if( index == last ) { // e.g. MP1 #0 tmpPos = anEvent->dtStart().date().day()/7 + 1; if( tmpPos == 5 ) tmpPos = -1; qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1); anEvent->recurrence()->addMonthlyPos(tmpPos, qba); } else { // e.g. MP1 1+ SU #0 while (index < last) { tmpPos = tmpStr.mid(index,1).toShort(); index += 1; if (tmpStr.mid(index,1) == "-") // convert tmpPos to negative tmpPos = 0 - tmpPos; index += 2; // advance to day(s) while (numFromDay(tmpStr.mid(index,3)) >= 0) { int dayNum = numFromDay(tmpStr.mid(index,3)); qba.setBit(dayNum); index += 3; // advance to next day, or possibly pos or "#" } anEvent->recurrence()->addMonthlyPos(tmpPos, qba); qba.detach(); qba.fill(FALSE); // clear out } // while != "#" } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length() - index))).date(); anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, -1); else anEvent->recurrence()->setMonthly(Recurrence::rMonthlyPos, rFreq, rDuration); } } /**************************** MONTHLY-BY-DAY ***************************/ else if (tmpStr.left(2) == "MD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. MD1 #0 tmpDay = anEvent->dtStart().date().day(); anEvent->recurrence()->addMonthlyDay(tmpDay); } else { // e.g. MD1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2-1; if (tmpStr.mid(index, 1) == "-") tmpDay = 0 - tmpDay; index += 2; // advance the index; anEvent->recurrence()->addMonthlyDay(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, -1); else anEvent->recurrence()->setMonthly(Recurrence::rMonthlyDay, rFreq, rDuration); } } /*********************** YEARLY-BY-MONTH *******************************/ else if (tmpStr.left(2) == "YM") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpMonth; if( index == last ) { // e.g. YM1 #0 tmpMonth = anEvent->dtStart().date().month(); anEvent->recurrence()->addYearlyNum(tmpMonth); } else { // e.g. YM1 3 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpMonth = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->recurrence()->addYearlyNum(tmpMonth); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, -1); else anEvent->recurrence()->setYearly(Recurrence::rYearlyMonth, rFreq, rDuration); } } /*********************** YEARLY-BY-DAY *********************************/ else if (tmpStr.left(2) == "YD") { int index = tmpStr.find(' '); int last = tmpStr.findRev(' ') + 1; int rFreq = tmpStr.mid(2, (index-1)).toInt(); index += 1; short tmpDay; if( index == last ) { // e.g. YD1 #0 tmpDay = anEvent->dtStart().date().dayOfYear(); anEvent->recurrence()->addYearlyNum(tmpDay); } else { // e.g. YD1 123 #0 while (index < last) { int index2 = tmpStr.find(' ', index); tmpDay = tmpStr.mid(index, (index2-index)).toShort(); index = index2+1; anEvent->recurrence()->addYearlyNum(tmpDay); } // while != # } index = last; if (tmpStr.mid(index,1) == "#") index++; if (tmpStr.find('T', index) != -1) { QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date(); anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rEndDate); } else { int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt(); if (rDuration == 0) anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, -1); else anEvent->recurrence()->setYearly(Recurrence::rYearlyDay, rFreq, rDuration); } } else { kdDebug(5800) << "we don't understand this type of recurrence!" << endl; } // if } // repeats // recurrence exceptions - if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { + if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); QStringList exDates = QStringList::split(",",s); QStringList::ConstIterator it; for(it = exDates.begin(); it != exDates.end(); ++it ) { anEvent->addExDate(ISOToQDate(*it)); } deleteStr(s); } // summary if ((vo = isAPropertyOf(vevent, VCSummaryProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setSummary(QString::fromLocal8Bit(s)); deleteStr(s); } if ((vo = isAPropertyOf(vevent, VCLocationProp))) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->setLocation(QString::fromLocal8Bit(s)); deleteStr(s); } // description if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (!anEvent->description().isEmpty()) { anEvent->setDescription(anEvent->description() + "\n" + QString::fromLocal8Bit(s)); } else { anEvent->setDescription(QString::fromLocal8Bit(s)); } deleteStr(s); } // some stupid vCal exporters ignore the standard and use Description // instead of Summary for the default field. Correct for this. if (anEvent->summary().isEmpty() && !(anEvent->description().isEmpty())) { QString tmpStr = anEvent->description().simplifyWhiteSpace(); anEvent->setDescription(""); anEvent->setSummary(tmpStr); } #if 0 // status if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) { QString tmpStr(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); // TODO: Define Event status // anEvent->setStatus(tmpStr); } else // anEvent->setStatus("NEEDS ACTION"); #endif // secrecy int secrecy = Incidence::SecrecyPublic; if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); if (strcmp(s,"PRIVATE") == 0) { secrecy = Incidence::SecrecyPrivate; } else if (strcmp(s,"CONFIDENTIAL") == 0) { secrecy = Incidence::SecrecyConfidential; } deleteStr(s); } anEvent->setSecrecy(secrecy); // categories QStringList tmpStrList; int index1 = 0; int index2 = 0; if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) { s = fakeCString(vObjectUStringZValue(vo)); QString categories = QString::fromLocal8Bit(s); deleteStr(s); //const char* category; QString category; while ((index2 = categories.find(',', index1)) != -1) { //category = (const char *) categories.mid(index1, (index2 - index1)); category = categories.mid(index1, (index2 - index1)); tmpStrList.append(category); index1 = index2+1; } // get last category category = categories.mid(index1, (categories.length()-index1)); tmpStrList.append(category); anEvent->setCategories(tmpStrList); } // attachments tmpStrList.clear(); initPropIterator(&voi, vevent); while (moreIteration(&voi)) { vo = nextVObject(&voi); if (strcmp(vObjectName(vo), VCAttachProp) == 0) { s = fakeCString(vObjectUStringZValue(vo)); anEvent->addAttachment(new Attachment(QString(s))); deleteStr(s); } } // resources if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { QString resources = (s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); tmpStrList.clear(); index1 = 0; index2 = 0; QString resource; while ((index2 = resources.find(';', index1)) != -1) { resource = resources.mid(index1, (index2 - index1)); tmpStrList.append(resource); index1 = index2; } anEvent->setResources(tmpStrList); } /* alarm stuff */ if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) { Alarm* alarm = anEvent->newAlarm(); VObject *a; if ((a = isAPropertyOf(vo, VCRunTimeProp))) { alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a)))); deleteStr(s); } alarm->setEnabled(true); if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) { if ((a = isAPropertyOf(vo, VCProcedureNameProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setProcedureAlarm(QFile::decodeName(s)); deleteStr(s); } } if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) { if ((a = isAPropertyOf(vo, VCAudioContentProp))) { s = fakeCString(vObjectUStringZValue(a)); alarm->setAudioAlarm(QFile::decodeName(s)); deleteStr(s); } } } // priority if ((vo = isAPropertyOf(vevent, VCPriorityProp))) { anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } // transparency if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) { int i = atoi(s = fakeCString(vObjectUStringZValue(vo))); anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque ); deleteStr(s); } // related event if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) { anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo))); deleteStr(s); mEventsRelate.append(anEvent); } /* PILOT SYNC STUFF */ - if ((vo = isAPropertyOf(vevent, KPilotIdProp))) { + if ((vo = isAPropertyOf(vevent, XPilotIdProp))) { anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setPilotId(0); - if ((vo = isAPropertyOf(vevent, KPilotStatusProp))) { + if ((vo = isAPropertyOf(vevent, XPilotStatusProp))) { anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo)))); deleteStr(s); } else anEvent->setSyncStatus(Event::SYNCMOD); return anEvent; } QString VCalFormat::qDateToISO(const QDate &qd) { QString tmpStr; ASSERT(qd.isValid()); tmpStr.sprintf("%.2d%.2d%.2d", qd.year(), qd.month(), qd.day()); return tmpStr; } QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu) { QString tmpStr; ASSERT(qdt.date().isValid()); ASSERT(qdt.time().isValid()); if (zulu) { QDateTime tmpDT(qdt); tmpDT = tmpDT.addSecs(60*(-mCalendar->getTimeZone())); // correct to GMT. tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2dZ", tmpDT.date().year(), tmpDT.date().month(), tmpDT.date().day(), tmpDT.time().hour(), tmpDT.time().minute(), tmpDT.time().second()); } else { tmpStr.sprintf("%.2d%.2d%.2dT%.2d%.2d%.2d", qdt.date().year(), qdt.date().month(), qdt.date().day(), qdt.time().hour(), qdt.time().minute(), qdt.time().second()); } return tmpStr; } QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr) { QDate tmpDate; QTime tmpTime; QString tmpStr; int year, month, day, hour, minute, second; tmpStr = dtStr; year = tmpStr.left(4).toInt(); month = tmpStr.mid(4,2).toInt(); day = tmpStr.mid(6,2).toInt(); hour = tmpStr.mid(9,2).toInt(); minute = tmpStr.mid(11,2).toInt(); second = tmpStr.mid(13,2).toInt(); tmpDate.setYMD(year, month, day); tmpTime.setHMS(hour, minute, second); ASSERT(tmpDate.isValid()); ASSERT(tmpTime.isValid()); QDateTime tmpDT(tmpDate, tmpTime); // correct for GMT if string is in Zulu format if (dtStr.at(dtStr.length()-1) == 'Z') tmpDT = tmpDT.addSecs(60*mCalendar->getTimeZone()); return tmpDT; } QDate VCalFormat::ISOToQDate(const QString &dateStr) { int year, month, day; year = dateStr.left(4).toInt(); month = dateStr.mid(4,2).toInt(); day = dateStr.mid(6,2).toInt(); return(QDate(year, month, day)); } // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. // and break it down from it's tree-like format into the dictionary format // that is used internally in the VCalFormat. void VCalFormat::populate(VObject *vcal) { // this function will populate the caldict dictionary and other event // lists. It turns vevents into Events and then inserts them. VObjectIterator i; VObject *curVO, *curVOProp; Event *anEvent; if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { char *methodType = 0; methodType = fakeCString(vObjectUStringZValue(curVO)); kdDebug() << "This calendar is an iTIP transaction of type '" << methodType << "'" << endl; delete methodType; } // warn the user that we might have trouble reading non-known calendar. if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); if (strcmp(productId().local8Bit(), s) != 0) kdDebug() << "This vCalendar file was not created by KOrganizer " "or any other product we support. Loading anyway..." << endl; mLoadedProductId = s; deleteStr(s); } // warn the user we might have trouble reading this unknown version. if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); if (strcmp(_VCAL_VERSION, s) != 0) kdDebug() << "This vCalendar file has version " << s << "We only support " << _VCAL_VERSION << endl; deleteStr(s); } // set the time zone if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVO)); mCalendar->setTimeZone(s); deleteStr(s); } // Store all events with a relatedTo property in a list for post-processing mEventsRelate.clear(); mTodosRelate.clear(); initPropIterator(&i, vcal); // go through all the vobjects in the vcal while (moreIteration(&i)) { curVO = nextVObject(&i); /************************************************************************/ // now, check to see that the object is an event or todo. if (strcmp(vObjectName(curVO), VCEventProp) == 0) { - if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { + if ((curVOProp = isAPropertyOf(curVO, XPilotStatusProp)) != 0) { char *s; s = fakeCString(vObjectUStringZValue(curVOProp)); // check to see if event was deleted by the kpilot conduit if (atoi(s) == Event::SYNCDEL) { deleteStr(s); kdDebug(5800) << "skipping pilot-deleted event" << endl; goto SKIP; } deleteStr(s); } // this code checks to see if we are trying to read in an event // that we already find to be in the calendar. If we find this // to be the case, we skip the event. if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { char *s = fakeCString(vObjectUStringZValue(curVOProp)); QString tmpStr(s); deleteStr(s); if (mCalendar->event(tmpStr)) { goto SKIP; } if (mCalendar->todo(tmpStr)) { goto SKIP; } } if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; goto SKIP; } anEvent = VEventToEvent(curVO); // we now use addEvent instead of insertEvent so that the // signal/slot get connected. if (anEvent) { if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) { kdDebug() << "VCalFormat::populate(): Event has invalid dates." << endl; } else { mCalendar->addEvent(anEvent); } } else { // some sort of error must have occurred while in translation. goto SKIP; } } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { Todo *aTodo = VTodoToEvent(curVO); mCalendar->addTodo(aTodo); } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { // do nothing, we know these properties and we want to skip them. // we have either already processed them or are ignoring them. ; } else { kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl; } SKIP: ; } // while // Post-Process list of events with relations, put Event objects in relation Event *ev; for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { ev->setRelatedTo(mCalendar->event(ev->relatedToUid())); } Todo *todo; for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { todo->setRelatedTo(mCalendar->todo(todo->relatedToUid())); } } const char *VCalFormat::dayFromNum(int day) { const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " }; return days[day]; } int VCalFormat::numFromDay(const QString &day) { if (day == "MO ") return 0; if (day == "TU ") return 1; if (day == "WE ") return 2; if (day == "TH ") return 3; if (day == "FR ") return 4; if (day == "SA ") return 5; if (day == "SU ") return 6; return -1; // something bad happened. :) } Attendee::PartStat VCalFormat::readStatus(const char *s) const { QString statStr = s; statStr = statStr.upper(); Attendee::PartStat status; if (statStr == "X-ACTION") status = Attendee::NeedsAction; else if (statStr == "NEEDS ACTION") status = Attendee::NeedsAction; else if (statStr== "ACCEPTED") status = Attendee::Accepted; else if (statStr== "SENT") status = Attendee::NeedsAction; else if (statStr== "TENTATIVE") status = Attendee::Tentative; else if (statStr== "CONFIRMED") status = Attendee::Accepted; else if (statStr== "DECLINED") status = Attendee::Declined; else if (statStr== "COMPLETED") status = Attendee::Completed; else if (statStr== "DELEGATED") status = Attendee::Delegated; else { kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl; status = Attendee::NeedsAction; } return status; } QCString VCalFormat::writeStatus(Attendee::PartStat status) const { switch(status) { default: case Attendee::NeedsAction: return "NEEDS ACTION"; break; case Attendee::Accepted: return "ACCEPTED"; break; case Attendee::Declined: return "DECLINED"; break; case Attendee::Tentative: return "TENTATIVE"; break; case Attendee::Delegated: return "DELEGATED"; break; case Attendee::Completed: return "COMPLETED"; break; case Attendee::InProcess: return "NEEDS ACTION"; break; } } diff --git a/libkcal/versit/port.h b/libkcal/versit/port.h index afc16dd..1768bee 100644 --- a/libkcal/versit/port.h +++ b/libkcal/versit/port.h @@ -1,75 +1,88 @@ /*************************************************************************** -(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International -Business Machines Corporation and Siemens Rolm Communications Inc. - -For purposes of this license notice, the term Licensors shall mean, -collectively, Apple Computer, Inc., AT&T Corp., International -Business Machines Corporation and Siemens Rolm Communications Inc. -The term Licensor shall mean any of the Licensors. - -Subject to acceptance of the following conditions, permission is hereby -granted by Licensors without the need for written agreement and without -license or royalty fees, to use, copy, modify and distribute this -software for any purpose. - -The above copyright notice and the following four paragraphs must be -reproduced in all copies of this software and any software including -this software. - -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE -ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR -MODIFICATIONS. - -IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, -INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT -OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. - -The software is provided with RESTRICTED RIGHTS. Use, duplication, or -disclosure by the government are subject to restrictions set forth in -DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. +(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International +Business Machines Corporation and Siemens Rolm Communications Inc. + +For purposes of this license notice, the term Licensors shall mean, +collectively, Apple Computer, Inc., AT&T Corp., International +Business Machines Corporation and Siemens Rolm Communications Inc. +The term Licensor shall mean any of the Licensors. + +Subject to acceptance of the following conditions, permission is hereby +granted by Licensors without the need for written agreement and without +license or royalty fees, to use, copy, modify and distribute this +software for any purpose. + +The above copyright notice and the following four paragraphs must be +reproduced in all copies of this software and any software including +this software. + +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE +ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR +MODIFICATIONS. + +IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, +INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT +OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + +The software is provided with RESTRICTED RIGHTS. Use, duplication, or +disclosure by the government are subject to restrictions set forth in +DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ #ifndef __PORT_H__ #define __PORT_H__ 1 + #if defined(__CPLUSPLUS__) || defined(__cplusplus) extern "C" { #endif - -#define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" -#define vCalendarClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCalendar" - -/* The above strings vCardClipboardFormat and vCalendarClipboardFormat -are globally unique IDs which can be used to generate clipboard format -ID's as per the requirements of a specific platform. For example, in -Windows they are used as the parameter in a call to RegisterClipboardFormat. + +/* some of these #defines are commented out because */ +/* Visual C++ sets them on the compiler command line instead */ + +/* #define _DEBUG */ +/* #define WIN32 */ +/* #define WIN16 */ +/* #define _WINDOWS */ +/* #define __MWERKS__ */ +/* #define INCLUDEMFC */ + +#define vCardClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCard" +#define vCalendarClipboardFormat "+//ISBN 1-887687-00-9::versit::PDI//vCalendar" + +/* The above strings vCardClipboardFormat and vCalendarClipboardFormat +are globally unique IDs which can be used to generate clipboard format +ID's as per the requirements of a specific platform. For example, in +Windows they are used as the parameter in a call to RegisterClipboardFormat. For example: CLIPFORMAT foo = RegisterClipboardFormat(vCardClipboardFormat); */ -#define vCardMimeType "text/x-vCard" -#define vCalendarMimeType "text/x-vCalendar" +#define vCardMimeType "text/x-vCard" +#define vCalendarMimeType "text/x-vCalendar" + +#define DLLEXPORT(t) t #ifndef FALSE -#define FALSE 0 +#define FALSE 0 #endif #ifndef TRUE -#define TRUE 1 +#define TRUE 1 #endif -#define Parse_Debug(t) - +#define stricmp strcasecmp + #if defined(__CPLUSPLUS__) || defined(__cplusplus) } #endif #endif /* __PORT_H__ */ diff --git a/libkcal/versit/vcc.c b/libkcal/versit/vcc.c index 350cac3..9be752d 100644 --- a/libkcal/versit/vcc.c +++ b/libkcal/versit/vcc.c @@ -1,2162 +1,2319 @@ - -/* A Bison parser, made from ./vcc.y - by GNU Bison version 1.28 */ +/* A Bison parser, made from vcc.y + by GNU bison 1.35. */ #define YYBISON 1 /* Identify Bison output. */ -#ifdef _WIN32_ -#define strcasecmp _stricmp -#endif - -#define EQ 257 -#define COLON 258 -#define DOT 259 -#define SEMICOLON 260 -#define SPACE 261 -#define HTAB 262 -#define LINESEP 263 -#define NEWLINE 264 -#define BEGIN_VCARD 265 -#define END_VCARD 266 -#define BEGIN_VCAL 267 -#define END_VCAL 268 -#define BEGIN_VEVENT 269 -#define END_VEVENT 270 -#define BEGIN_VTODO 271 -#define END_VTODO 272 -#define ID 273 -#define STRING 274 - -#line 1 "./vcc.y" +# define EQ 257 +# define COLON 258 +# define DOT 259 +# define SEMICOLON 260 +# define SPACE 261 +# define HTAB 262 +# define LINESEP 263 +# define NEWLINE 264 +# define BEGIN_VCARD 265 +# define END_VCARD 266 +# define BEGIN_VCAL 267 +# define END_VCAL 268 +# define BEGIN_VEVENT 269 +# define END_VEVENT 270 +# define BEGIN_VTODO 271 +# define END_VTODO 272 +# define ID 273 +# define STRING 274 + +#line 1 "vcc.y" /*************************************************************************** -(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International -Business Machines Corporation and Siemens Rolm Communications Inc. - -For purposes of this license notice, the term Licensors shall mean, -collectively, Apple Computer, Inc., AT&T Corp., International -Business Machines Corporation and Siemens Rolm Communications Inc. -The term Licensor shall mean any of the Licensors. - -Subject to acceptance of the following conditions, permission is hereby -granted by Licensors without the need for written agreement and without -license or royalty fees, to use, copy, modify and distribute this -software for any purpose. - -The above copyright notice and the following four paragraphs must be -reproduced in all copies of this software and any software including -this software. - -THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE -ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR -MODIFICATIONS. - -IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, -INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT -OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. - -EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, -INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. - -The software is provided with RESTRICTED RIGHTS. Use, duplication, or -disclosure by the government are subject to restrictions set forth in -DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. +(C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International +Business Machines Corporation and Siemens Rolm Communications Inc. + +For purposes of this license notice, the term Licensors shall mean, +collectively, Apple Computer, Inc., AT&T Corp., International +Business Machines Corporation and Siemens Rolm Communications Inc. +The term Licensor shall mean any of the Licensors. + +Subject to acceptance of the following conditions, permission is hereby +granted by Licensors without the need for written agreement and without +license or royalty fees, to use, copy, modify and distribute this +software for any purpose. + +The above copyright notice and the following four paragraphs must be +reproduced in all copies of this software and any software including +this software. + +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE +ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR +MODIFICATIONS. + +IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, +INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT +OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +DAMAGE. + +EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. + +The software is provided with RESTRICTED RIGHTS. Use, duplication, or +disclosure by the government are subject to restrictions set forth in +DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ /* * src: vcc.c * doc: Parser for vCard and vCalendar. Note that this code is * generated by a yacc parser generator. Generally it should not * be edited by hand. The real source is vcc.y. The #line directives * can be commented out here to make it easier to trace through - * in a debugger. However, if a bug is found it should + * in a debugger. However, if a bug is found it should * be fixed in vcc.y and this file regenerated. */ /* debugging utilities */ #if __DEBUG #define DBG_(x) printf x #else #define DBG_(x) #endif +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif + /**** External Functions ****/ /* assign local name to parser variables and functions so that we can use more than one yacc based parser. */ #define yyparse mime_parse #define yylex mime_lex #define yyerror mime_error #define yychar mime_char /* #define p_yyval p_mime_val */ #undef yyval #define yyval mime_yyval /* #define p_yylval p_mime_lval */ #undef yylval #define yylval mime_yylval #define yydebug mime_debug #define yynerrs mime_nerrs #define yyerrflag mime_errflag #define yyss mime_ss #define yyssp mime_ssp #define yyvs mime_vs #define yyvsp mime_vsp #define yylhs mime_lhs #define yylen mime_len #define yydefred mime_defred #define yydgoto mime_dgoto #define yysindex mime_sindex #define yyrindex mime_rindex #define yygindex mime_gindex #define yytable mime_table #define yycheck mime_check #define yyname mime_name #define yyrule mime_rule -#undef YYPREFIX #define YYPREFIX "mime_" #ifndef _NO_LINE_FOLDING #define _SUPPORT_LINE_FOLDING 1 #endif -#include <string.h> -#ifndef __FreeBSD__ -#include <malloc.h> +/* undef below if compile with MFC */ +/* #define INCLUDEMFC 1 */ + +#if defined(WIN32) || defined(_WIN32) +#ifdef INCLUDEMFC +#include <afx.h> #endif +#endif + +#include <string.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include "vcc.h" -/* The following is a hack that I hope will get things compiling - * on SunOS 4.1.x systems - */ -#ifndef SEEK_SET -#define SEEK_SET 0 /* Seek from beginning of file. */ -#define SEEK_CUR 1 /* Seek from current position. */ -#define SEEK_END 2 /* Seek from end of file. */ -#endif - /**** Types, Constants ****/ -#define YYDEBUG 0 /* 1 to compile in some debugging code */ +#define YYDEBUG 1 /* 1 to compile in some debugging code */ #define MAXTOKEN 256 /* maximum token (line) length */ -#define YYSTACKSIZE 1000 /* ~unref ? */ +#define YYSTACKSIZE 50 /* ~unref ? */ #define MAXLEVEL 10 /* max # of nested objects parseable */ /* (includes outermost) */ /**** Global Variables ****/ int mime_lineNum, mime_numErrors; /* yyerror() can use these */ static VObject* vObjList; static VObject *curProp; static VObject *curObj; static VObject* ObjStack[MAXLEVEL]; static int ObjStackTop; /* A helpful utility for the rest of the app. */ #if __CPLUSPLUS__ extern "C" { #endif - /* static void Parse_Debug(const char *s);*/ + extern void Parse_Debug(const char *s); static void yyerror(char *s); #if __CPLUSPLUS__ }; #endif int yyparse(); -static int yylex(); + enum LexMode { L_NORMAL, L_VCARD, L_VCAL, L_VEVENT, L_VTODO, L_VALUES, L_BASE64, L_QUOTED_PRINTABLE }; /**** Private Forward Declarations ****/ static int pushVObject(const char *prop); static VObject* popVObject(); -char* lexDataFromBase64(); static void lexPopMode(int top); static int lexWithinMode(enum LexMode mode); static void lexPushMode(enum LexMode mode); static void enterProps(const char *s); static void enterAttr(const char *s1, const char *s2); -/* static void enterValues(const char *value); */ -static void appendValue(const char *value); +static void enterValues(const char *value); static void mime_error_(char *s); -#line 181 "./vcc.y" +#line 180 "vcc.y" +#ifndef YYSTYPE typedef union { char *str; VObject *vobj; - } YYSTYPE; -#include <stdio.h> - -#ifndef __cplusplus -#ifndef __STDC__ -#define const + } yystype; +# define YYSTYPE yystype +# define YYSTYPE_IS_TRIVIAL 1 #endif +#ifndef YYDEBUG +# define YYDEBUG 0 #endif #define YYFINAL 62 #define YYFLAG -32768 #define YYNTBASE 21 +/* YYTRANSLATE(YYLEX) -- Bison token number corresponding to YYLEX. */ #define YYTRANSLATE(x) ((unsigned)(x) <= 274 ? yytranslate[x] : 51) -static const char yytranslate[] = { 0, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 1, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20 +/* YYTRANSLATE[YYLEX] -- Bison token number corresponding to YYLEX. */ +static const char yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20 }; -#if YYDEBUG != 0 -static const short yyprhs[] = { 0, - 0, 2, 3, 7, 9, 11, 13, 14, 19, 20, - 24, 27, 29, 30, 36, 38, 39, 43, 45, 48, - 50, 53, 55, 59, 61, 62, 67, 69, 71, 72, - 73, 78, 79, 83, 86, 88, 90, 92, 94, 95, - 100, 101, 105, 106, 111, 112 +#if YYDEBUG +static const short yyprhs[] = +{ + 0, 0, 2, 3, 7, 9, 11, 13, 14, 19, + 20, 24, 27, 29, 30, 36, 38, 39, 43, 45, + 48, 50, 53, 55, 59, 61, 62, 67, 69, 71, + 72, 73, 78, 79, 83, 86, 88, 90, 92, 94, + 95, 100, 101, 105, 106, 111, 112 }; - -static const short yyrhs[] = { 22, - 0, 0, 24, 23, 22, 0, 24, 0, 25, 0, - 40, 0, 0, 11, 26, 28, 12, 0, 0, 11, - 27, 12, 0, 29, 28, 0, 29, 0, 0, 31, - 4, 30, 37, 9, 0, 1, 0, 0, 36, 32, - 33, 0, 36, 0, 34, 33, 0, 34, 0, 6, - 35, 0, 36, 0, 36, 3, 36, 0, 19, 0, - 0, 39, 6, 38, 37, 0, 39, 0, 20, 0, - 0, 0, 13, 41, 43, 14, 0, 0, 13, 42, - 14, 0, 44, 43, 0, 44, 0, 45, 0, 48, - 0, 28, 0, 0, 15, 46, 28, 16, 0, 0, - 15, 47, 16, 0, 0, 17, 49, 28, 18, 0, - 0, 17, 50, 18, 0 +static const short yyrhs[] = +{ + 22, 0, 0, 24, 23, 22, 0, 24, 0, 25, + 0, 40, 0, 0, 11, 26, 28, 12, 0, 0, + 11, 27, 12, 0, 29, 28, 0, 29, 0, 0, + 31, 4, 30, 37, 9, 0, 1, 0, 0, 36, + 32, 33, 0, 36, 0, 34, 33, 0, 34, 0, + 6, 35, 0, 36, 0, 36, 3, 36, 0, 19, + 0, 0, 39, 6, 38, 37, 0, 39, 0, 20, + 0, 0, 0, 13, 41, 43, 14, 0, 0, 13, + 42, 14, 0, 44, 43, 0, 44, 0, 45, 0, + 48, 0, 28, 0, 0, 15, 46, 28, 16, 0, + 0, 15, 47, 16, 0, 0, 17, 49, 28, 18, + 0, 0, 17, 50, 18, 0 }; #endif -#if YYDEBUG != 0 -static const short yyrline[] = { 0, - 209, 212, 215, 215, 219, 220, 223, 229, 234, 240, - 246, 247, 250, 254, 260, 263, 268, 268, 274, 275, - 278, 281, 285, 292, 295, 296, 296, 300, 301, 305, - 309, 311, 314, 317, 318, 321, 323, 324, 327, 334, - 339, 345, 351, 358, 363, 369 +#if YYDEBUG +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const short yyrline[] = +{ + 0, 208, 211, 211, 214, 218, 219, 222, 222, 233, + 233, 245, 246, 249, 249, 259, 262, 262, 267, 273, + 274, 277, 280, 284, 291, 294, 294, 295, 299, 300, + 303, 303, 309, 309, 315, 316, 319, 321, 322, 325, + 325, 337, 337, 349, 349, 361, 361 }; #endif -#if YYDEBUG != 0 || defined (YYERROR_VERBOSE) +#if (YYDEBUG) || defined YYERROR_VERBOSE -static const char * const yytname[] = { "$","error","$undefined.","EQ","COLON", -"DOT","SEMICOLON","SPACE","HTAB","LINESEP","NEWLINE","BEGIN_VCARD","END_VCARD", -"BEGIN_VCAL","END_VCAL","BEGIN_VEVENT","END_VEVENT","BEGIN_VTODO","END_VTODO", -"ID","STRING","mime","vobjects","@1","vobject","vcard","@2","@3","items","item", -"@4","prop","@5","attr_params","attr_param","attr","name","values","@6","value", -"vcal","@7","@8","calitems","calitem","eventitem","@9","@10","todoitem","@11", -"@12", NULL +/* YYTNAME[TOKEN_NUM] -- String name of the token TOKEN_NUM. */ +static const char *const yytname[] = +{ + "$", "error", "$undefined.", "EQ", "COLON", "DOT", "SEMICOLON", "SPACE", + "HTAB", "LINESEP", "NEWLINE", "BEGIN_VCARD", "END_VCARD", "BEGIN_VCAL", + "END_VCAL", "BEGIN_VEVENT", "END_VEVENT", "BEGIN_VTODO", "END_VTODO", + "ID", "STRING", "mime", "vobjects", "@1", "vobject", "vcard", "@2", + "@3", "items", "item", "@4", "prop", "@5", "attr_params", "attr_param", + "attr", "name", "values", "@6", "value", "vcal", "@7", "@8", "calitems", + "calitem", "eventitem", "@9", "@10", "todoitem", "@11", "@12", 0 }; #endif -static const short yyr1[] = { 0, - 21, 23, 22, 22, 24, 24, 26, 25, 27, 25, - 28, 28, 30, 29, 29, 32, 31, 31, 33, 33, - 34, 35, 35, 36, 38, 37, 37, 39, 39, 41, - 40, 42, 40, 43, 43, 44, 44, 44, 46, 45, - 47, 45, 49, 48, 50, 48 +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const short yyr1[] = +{ + 0, 21, 23, 22, 22, 24, 24, 26, 25, 27, + 25, 28, 28, 30, 29, 29, 32, 31, 31, 33, + 33, 34, 35, 35, 36, 38, 37, 37, 39, 39, + 41, 40, 42, 40, 43, 43, 44, 44, 44, 46, + 45, 47, 45, 49, 48, 50, 48 }; -static const short yyr2[] = { 0, - 1, 0, 3, 1, 1, 1, 0, 4, 0, 3, - 2, 1, 0, 5, 1, 0, 3, 1, 2, 1, - 2, 1, 3, 1, 0, 4, 1, 1, 0, 0, - 4, 0, 3, 2, 1, 1, 1, 1, 0, 4, - 0, 3, 0, 4, 0, 3 +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const short yyr2[] = +{ + 0, 1, 0, 3, 1, 1, 1, 0, 4, 0, + 3, 2, 1, 0, 5, 1, 0, 3, 1, 2, + 1, 2, 1, 3, 1, 0, 4, 1, 1, 0, + 0, 4, 0, 3, 2, 1, 1, 1, 1, 0, + 4, 0, 3, 0, 4, 0, 3 }; -static const short yydefact[] = { 0, - 7, 30, 1, 2, 5, 6, 0, 0, 0, 0, - 0, 15, 24, 0, 0, 0, 16, 10, 39, 43, - 38, 0, 0, 36, 37, 33, 3, 8, 11, 13, - 0, 0, 0, 0, 0, 31, 34, 29, 0, 17, - 20, 0, 42, 0, 46, 28, 0, 27, 21, 22, - 19, 40, 44, 14, 25, 0, 29, 23, 26, 0, - 0, 0 +/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE + doesn't specify something else to do. Zero means the default is an + error. */ +static const short yydefact[] = +{ + 0, 7, 30, 1, 2, 5, 6, 0, 0, 0, + 0, 0, 15, 24, 0, 0, 0, 16, 10, 39, + 43, 38, 0, 0, 36, 37, 33, 3, 8, 11, + 13, 0, 0, 0, 0, 0, 31, 34, 29, 0, + 17, 20, 0, 42, 0, 46, 28, 0, 27, 21, + 22, 19, 40, 44, 14, 25, 0, 29, 23, 26, + 0, 0, 0 }; -static const short yydefgoto[] = { 60, - 3, 11, 4, 5, 7, 8, 21, 15, 38, 16, - 31, 40, 41, 49, 17, 47, 57, 48, 6, 9, - 10, 22, 23, 24, 32, 33, 25, 34, 35 +static const short yydefgoto[] = +{ + 60, 3, 11, 4, 5, 7, 8, 21, 15, 38, + 16, 31, 40, 41, 49, 17, 47, 57, 48, 6, + 9, 10, 22, 23, 24, 32, 33, 25, 34, 35 }; -static const short yypact[] = { -9, - -6, -5,-32768, 7,-32768,-32768, 2, -1, 19, 15, - -9,-32768,-32768, 1, 0, 26, 27,-32768, 16, 17, --32768, 23, 9,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 33, 2, 24, 2, 25,-32768,-32768, 13, 22,-32768, - 33, 28,-32768, 29,-32768,-32768, 36, 40,-32768, 39, --32768,-32768,-32768,-32768,-32768, 22, 13,-32768,-32768, 48, - 49,-32768 +static const short yypact[] = +{ + -9, -6, -5,-32768, 7,-32768,-32768, 2, -1, 19, + 15, -9,-32768,-32768, 1, 0, 26, 27,-32768, 16, + 17,-32768, 23, 9,-32768,-32768,-32768,-32768,-32768,-32768, + -32768, 33, 2, 24, 2, 25,-32768,-32768, 13, 22, + -32768, 33, 28,-32768, 29,-32768,-32768, 36, 40,-32768, + 39,-32768,-32768,-32768,-32768,-32768, 22, 13,-32768,-32768, + 48, 49,-32768 }; -static const short yypgoto[] = {-32768, - 41,-32768,-32768,-32768,-32768,-32768, -7,-32768,-32768,-32768, --32768, 10,-32768,-32768, -34, -4,-32768,-32768,-32768,-32768, --32768, 31,-32768,-32768,-32768,-32768,-32768,-32768,-32768 +static const short yypgoto[] = +{ + -32768, 41,-32768,-32768,-32768,-32768,-32768, -7,-32768,-32768, + -32768,-32768, 10,-32768,-32768, -34, -4,-32768,-32768,-32768, + -32768,-32768, 31,-32768,-32768,-32768,-32768,-32768,-32768,-32768 }; #define YYLAST 54 -static const short yytable[] = { 14, - 12, 1, 12, 2, 50, -9, -4, 29, -32, 12, - 18, -12, 28, -12, -12, -12, -12, -12, 13, 12, - 13, 58, -35, 19, 42, 20, 44, 13, 26, 30, - -18, -41, 46, 19, -45, 20, 36, 13, 39, 43, - 13, 56, 45, 52, 54, 55, 53, 61, 62, 0, - 51, 27, 59, 37 +static const short yytable[] = +{ + 14, 12, 1, 12, 2, 50, -9, -4, 29, -32, + 12, 18, -12, 28, -12, -12, -12, -12, -12, 13, + 12, 13, 58, -35, 19, 42, 20, 44, 13, 26, + 30, -18, -41, 46, 19, -45, 20, 36, 13, 39, + 43, 13, 56, 45, 52, 54, 55, 53, 61, 62, + 0, 51, 27, 59, 37 }; -static const short yycheck[] = { 7, - 1, 11, 1, 13, 39, 12, 0, 15, 14, 1, - 12, 12, 12, 14, 15, 16, 17, 18, 19, 1, - 19, 56, 14, 15, 32, 17, 34, 19, 14, 4, - 4, 16, 20, 15, 18, 17, 14, 19, 6, 16, - 19, 3, 18, 16, 9, 6, 18, 0, 0, -1, - 41, 11, 57, 23 +static const short yycheck[] = +{ + 7, 1, 11, 1, 13, 39, 12, 0, 15, 14, + 1, 12, 12, 12, 14, 15, 16, 17, 18, 19, + 1, 19, 56, 14, 15, 32, 17, 34, 19, 14, + 4, 4, 16, 20, 15, 18, 17, 14, 19, 6, + 16, 19, 3, 18, 16, 9, 6, 18, 0, 0, + -1, 41, 11, 57, 23 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ -#line 3 "/usr/share/bison.simple" -/* This file comes from bison-1.28. */ +#line 3 "/usr/share/bison/bison.simple" /* Skeleton output parser for bison, - Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc. + + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software + Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ -/* This is the parser code that is written into each bison parser - when the %semantic_parser declaration is not specified in the grammar. - It was written by Richard Stallman by simplifying the hairy parser - used when %semantic_parser is specified. */ +/* This is the parser code that is written into each bison parser when + the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +#if ! defined (yyoverflow) || defined (YYERROR_VERBOSE) + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# if YYSTACK_USE_ALLOCA +# define YYSTACK_ALLOC alloca +# else +# ifndef YYSTACK_USE_ALLOCA +# if defined (alloca) || defined (_ALLOCA_H) +# define YYSTACK_ALLOC alloca +# else +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# else +# if defined (__STDC__) || defined (__cplusplus) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +# define YYSTACK_ALLOC malloc +# define YYSTACK_FREE free +# endif +#endif /* ! defined (yyoverflow) || defined (YYERROR_VERBOSE) */ + + +#if (! defined (yyoverflow) \ + && (! defined (__cplusplus) \ + || (YYLTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + short yyss; + YYSTYPE yyvs; +# if YYLSP_NEEDED + YYLTYPE yyls; +# endif +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAX (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# if YYLSP_NEEDED +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \ + + 2 * YYSTACK_GAP_MAX) +# else +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAX) +# endif + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + register YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (0) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack, Stack, yysize); \ + Stack = &yyptr->Stack; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAX; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) -#ifndef YYSTACK_USE_ALLOCA -#ifdef alloca -#define YYSTACK_USE_ALLOCA -#else /* alloca not defined */ -#ifdef __GNUC__ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#else /* not GNU C. */ -#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__) || defined (__sparc) || defined (__sgi) || (defined (__sun) && defined (__i386)) -#define YYSTACK_USE_ALLOCA -#include <alloca.h> -#else /* not sparc */ -/* We think this test detects Watcom and Microsoft C. */ -/* This used to test MSDOS, but that is a bad idea - since that symbol is in the user namespace. */ -#if (defined (_MSDOS) || defined (_MSDOS_)) && !defined (__TURBOC__) -#if 0 /* No need for malloc.h, which pollutes the namespace; - instead, just don't use alloca. */ -#include <malloc.h> #endif -#else /* not MSDOS, or __TURBOC__ */ -#if defined(_AIX) -/* I don't know what this was needed for, but it pollutes the namespace. - So I turned it off. rms, 2 May 1997. */ -/* #include <malloc.h> */ - #pragma alloca -#define YYSTACK_USE_ALLOCA -#else /* not MSDOS, or __TURBOC__, or _AIX */ -#if 0 -#ifdef __hpux /* haible@ilog.fr says this works for HPUX 9.05 and up, - and on HPUX 10. Eventually we can turn this on. */ -#define YYSTACK_USE_ALLOCA -#define alloca __builtin_alloca -#endif /* __hpux */ + + +#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) +# define YYSIZE_T __SIZE_TYPE__ #endif -#endif /* not _AIX */ -#endif /* not MSDOS, or __TURBOC__ */ -#endif /* not sparc */ -#endif /* not GNU C */ -#endif /* alloca not defined */ -#endif /* YYSTACK_USE_ALLOCA not defined */ - -#ifdef YYSTACK_USE_ALLOCA -#define YYSTACK_ALLOC alloca -#else -#define YYSTACK_ALLOC malloc +#if ! defined (YYSIZE_T) && defined (size_t) +# define YYSIZE_T size_t +#endif +#if ! defined (YYSIZE_T) +# if defined (__STDC__) || defined (__cplusplus) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# endif +#endif +#if ! defined (YYSIZE_T) +# define YYSIZE_T unsigned int #endif - -/* Note: there must be only one dollar sign in this file. - It is replaced by the list of actions, each action - as one case of the switch. */ #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY -2 #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 -/* Like YYERROR except do call yyerror. - This remains here temporarily to ease the - transition to the new meaning of YYERROR, for GCC. +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) -#define YYBACKUP(token, value) \ +#define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ - { yychar = (token), yylval = (value); \ + { \ + yychar = (Token); \ + yylval = (Value); \ yychar1 = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ - { yyerror ("syntax error: cannot back up"); YYERROR; } \ + { \ + yyerror ("syntax error: cannot back up"); \ + YYERROR; \ + } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 -#ifndef YYPURE -#define YYLEX yylex() -#endif -#ifdef YYPURE -#ifdef YYLSP_NEEDED -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, &yylloc, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval, &yylloc) -#endif -#else /* not YYLSP_NEEDED */ -#ifdef YYLEX_PARAM -#define YYLEX yylex(&yylval, YYLEX_PARAM) -#else -#define YYLEX yylex(&yylval) -#endif -#endif /* not YYLSP_NEEDED */ -#endif +/* YYLLOC_DEFAULT -- Compute the default location (before the actions + are run). -/* If nonreentrant, generate the variables here */ + When YYLLOC_DEFAULT is run, CURRENT is set the location of the + first token. By default, to implement support for ranges, extend + its range to the last symbol. */ -#ifndef YYPURE - -int yychar; /* the lookahead symbol */ -YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#ifdef YYLSP_NEEDED -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + Current.last_line = Rhs[N].last_line; \ + Current.last_column = Rhs[N].last_column; #endif -int yynerrs; /* number of parse errors so far */ -#endif /* not YYPURE */ - -#if YYDEBUG != 0 -int yydebug; /* nonzero means print parse trace */ -/* Since this is uninitialized, it does not stop multiple parsers - from coexisting. */ -#endif - -/* YYINITDEPTH indicates the initial size of the parser's stacks */ +/* YYLEX -- calling `yylex' with the right arguments. */ + +#if YYPURE +# if YYLSP_NEEDED +# ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM) +# else +# define YYLEX yylex (&yylval, &yylloc) +# endif +# else /* !YYLSP_NEEDED */ +# ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +# else +# define YYLEX yylex (&yylval) +# endif +# endif /* !YYLSP_NEEDED */ +#else /* !YYPURE */ +# define YYLEX yylex () +#endif /* !YYPURE */ + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +#endif /* !YYDEBUG */ + +/* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH -#define YYINITDEPTH 200 +# define YYINITDEPTH 200 #endif -/* YYMAXDEPTH is the maximum size the stacks can grow to - (effective only if the built-in stack extension method is used). */ +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 -#undef YYMAXDEPTH +# undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH -#define YYMAXDEPTH 10000 +# define YYMAXDEPTH 10000 #endif -/* Define __yy_memcpy. Note that the size argument - should be passed with type unsigned int, because that is what the non-GCC - definitions require. With GCC, __builtin_memcpy takes an arg - of type size_t, but it can handle unsigned int. */ - -#if __GNUC__ > 1 /* GNU C and GNU C++ define this. */ -#define __yy_memcpy(TO,FROM,COUNT) __builtin_memcpy(TO,FROM,COUNT) -#else /* not GNU C or C++ */ -#ifndef __cplusplus - -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (to, from, count) - char *to; - char *from; - unsigned int count; -{ - register char *f = from; - register char *t = to; - register int i = count; +#ifdef YYERROR_VERBOSE - while (i-- > 0) - *t++ = *f++; -} +# ifndef yystrlen +# if defined (__GLIBC__) && defined (_STRING_H) +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +# if defined (__STDC__) || defined (__cplusplus) +yystrlen (const char *yystr) +# else +yystrlen (yystr) + const char *yystr; +# endif +{ + register const char *yys = yystr; -#else /* __cplusplus */ + while (*yys++ != '\0') + continue; -/* This is the most reliable way to avoid incompatibilities - in available built-in functions on various systems. */ -static void -__yy_memcpy (char *to, char *from, unsigned int count) + return yys - yystr - 1; +} +# endif +# endif + +# ifndef yystpcpy +# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +# if defined (__STDC__) || defined (__cplusplus) +yystpcpy (char *yydest, const char *yysrc) +# else +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +# endif { - register char *t = to; - register char *f = from; - register int i = count; + register char *yyd = yydest; + register const char *yys = yysrc; - while (i-- > 0) - *t++ = *f++; -} + while ((*yyd++ = *yys++) != '\0') + continue; -#endif + return yyd - 1; +} +# endif +# endif #endif -#line 217 "/usr/share/bison.simple" +#line 315 "/usr/share/bison/bison.simple" + /* The user can define YYPARSE_PARAM as the name of an argument to be passed into yyparse. The argument should have type void *. It should actually point to an object. Grammar actions can access the variable by casting it to the proper pointer type. */ #ifdef YYPARSE_PARAM -#ifdef __cplusplus -#define YYPARSE_PARAM_ARG void *YYPARSE_PARAM -#define YYPARSE_PARAM_DECL -#else /* not __cplusplus */ -#define YYPARSE_PARAM_ARG YYPARSE_PARAM -#define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; -#endif /* not __cplusplus */ -#else /* not YYPARSE_PARAM */ -#define YYPARSE_PARAM_ARG -#define YYPARSE_PARAM_DECL -#endif /* not YYPARSE_PARAM */ +# if defined (__STDC__) || defined (__cplusplus) +# define YYPARSE_PARAM_ARG void *YYPARSE_PARAM +# define YYPARSE_PARAM_DECL +# else +# define YYPARSE_PARAM_ARG YYPARSE_PARAM +# define YYPARSE_PARAM_DECL void *YYPARSE_PARAM; +# endif +#else /* !YYPARSE_PARAM */ +# define YYPARSE_PARAM_ARG +# define YYPARSE_PARAM_DECL +#endif /* !YYPARSE_PARAM */ /* Prevent warning if -Wstrict-prototypes. */ -#if defined (__GNUC__) && ! defined (__cplusplus) -#ifdef YYPARSE_PARAM +#ifdef __GNUC__ +# ifdef YYPARSE_PARAM int yyparse (void *); -#else +# else int yyparse (void); +# endif #endif + +/* YY_DECL_VARIABLES -- depending whether we use a pure parser, + variables are global, or local to YYPARSE. */ + +#define YY_DECL_NON_LSP_VARIABLES \ +/* The lookahead symbol. */ \ +int yychar; \ + \ +/* The semantic value of the lookahead symbol. */ \ +YYSTYPE yylval; \ + \ +/* Number of parse errors so far. */ \ +int yynerrs; + +#if YYLSP_NEEDED +# define YY_DECL_VARIABLES \ +YY_DECL_NON_LSP_VARIABLES \ + \ +/* Location data for the lookahead symbol. */ \ +YYLTYPE yylloc; +#else +# define YY_DECL_VARIABLES \ +YY_DECL_NON_LSP_VARIABLES #endif + +/* If nonreentrant, generate the variables here. */ + +#if !YYPURE +YY_DECL_VARIABLES +#endif /* !YYPURE */ + int -yyparse(YYPARSE_PARAM_ARG) +yyparse (YYPARSE_PARAM_ARG) YYPARSE_PARAM_DECL { + /* If reentrant, generate the variables here. */ +#if YYPURE + YY_DECL_VARIABLES +#endif /* !YYPURE */ + register int yystate; register int yyn; + int yyresult; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + /* Lookahead token as an internal (translated) token number. */ + int yychar1 = 0; + + /* Three stacks and their tools: + `yyss': related to states, + `yyvs': related to semantic values, + `yyls': related to locations. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + short yyssa[YYINITDEPTH]; + short *yyss = yyssa; register short *yyssp; - register YYSTYPE *yyvsp; - int yyerrstatus; /* number of tokens to shift before error messages enabled */ - int yychar1 = 0; /* lookahead token as an internal (translated) token number */ - short yyssa[YYINITDEPTH]; /* the state stack */ - YYSTYPE yyvsa[YYINITDEPTH]; /* the semantic value stack */ - - short *yyss = yyssa; /* refer to the stacks thru separate pointers */ - YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs = yyvsa; + register YYSTYPE *yyvsp; -#ifdef YYLSP_NEEDED - YYLTYPE yylsa[YYINITDEPTH]; /* the location stack */ +#if YYLSP_NEEDED + /* The location stack. */ + YYLTYPE yylsa[YYINITDEPTH]; YYLTYPE *yyls = yylsa; YYLTYPE *yylsp; +#endif -#define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) +#if YYLSP_NEEDED +# define YYPOPSTACK (yyvsp--, yyssp--, yylsp--) #else -#define YYPOPSTACK (yyvsp--, yyssp--) +# define YYPOPSTACK (yyvsp--, yyssp--) #endif - int yystacksize = YYINITDEPTH; - int yyfree_stacks = 0; + YYSIZE_T yystacksize = YYINITDEPTH; -#ifdef YYPURE - int yychar; - YYSTYPE yylval; - int yynerrs; -#ifdef YYLSP_NEEDED - YYLTYPE yylloc; -#endif -#endif - YYSTYPE yyval; /* the variable used to return */ - /* semantic values from the action */ - /* routines */ + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; +#if YYLSP_NEEDED + YYLTYPE yyloc; +#endif + /* When reducing, the number of symbols on the RHS of the reduced + rule. */ int yylen; -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Starting parse\n"); -#endif + YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ - yyssp = yyss - 1; + yyssp = yyss; yyvsp = yyvs; -#ifdef YYLSP_NEEDED +#if YYLSP_NEEDED yylsp = yyls; #endif + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. + */ + yyssp++; -/* Push a new state, which is found in yystate . */ -/* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. */ -yynewstate: - - *++yyssp = yystate; + yysetstate: + *yyssp = yystate; if (yyssp >= yyss + yystacksize - 1) { - /* Give user a chance to reallocate the stack */ - /* Use copies of these so that the &'s don't force the real ones into memory. */ - YYSTYPE *yyvs1 = yyvs; - short *yyss1 = yyss; -#ifdef YYLSP_NEEDED - YYLTYPE *yyls1 = yyls; -#endif - /* Get the current used size of the three stacks, in elements. */ - int size = yyssp - yyss + 1; + YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow - /* Each stack pointer address is followed by the size of - the data in use in that stack, in bytes. */ -#ifdef YYLSP_NEEDED - /* This used to be a conditional around just the two extra args, - but that might be undefined if yyoverflow is a macro. */ - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yyls1, size * sizeof (*yylsp), - &yystacksize); -#else - yyoverflow("parser stack overflow", - &yyss1, size * sizeof (*yyssp), - &yyvs1, size * sizeof (*yyvsp), - &yystacksize); -#endif - - yyss = yyss1; yyvs = yyvs1; -#ifdef YYLSP_NEEDED - yyls = yyls1; -#endif + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + short *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. */ +# if YYLSP_NEEDED + YYLTYPE *yyls1 = yyls; + /* This used to be a conditional around just the two extra args, + but that might be undefined if yyoverflow is a macro. */ + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yyls1, yysize * sizeof (*yylsp), + &yystacksize); + yyls = yyls1; +# else + yyoverflow ("parser stack overflow", + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); +# endif + yyss = yyss1; + yyvs = yyvs1; + } #else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyoverflowlab; +# else /* Extend the stack our own way. */ if (yystacksize >= YYMAXDEPTH) - { - yyerror("parser stack overflow"); - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 2; - } + goto yyoverflowlab; yystacksize *= 2; if (yystacksize > YYMAXDEPTH) yystacksize = YYMAXDEPTH; -#ifndef YYSTACK_USE_ALLOCA - yyfree_stacks = 1; -#endif - yyss = (short *) YYSTACK_ALLOC (yystacksize * sizeof (*yyssp)); - __yy_memcpy ((char *)yyss, (char *)yyss1, - size * (unsigned int) sizeof (*yyssp)); - yyvs = (YYSTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yyvsp)); - __yy_memcpy ((char *)yyvs, (char *)yyvs1, - size * (unsigned int) sizeof (*yyvsp)); -#ifdef YYLSP_NEEDED - yyls = (YYLTYPE *) YYSTACK_ALLOC (yystacksize * sizeof (*yylsp)); - __yy_memcpy ((char *)yyls, (char *)yyls1, - size * (unsigned int) sizeof (*yylsp)); -#endif + + { + short *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyoverflowlab; + YYSTACK_RELOCATE (yyss); + YYSTACK_RELOCATE (yyvs); +# if YYLSP_NEEDED + YYSTACK_RELOCATE (yyls); +# endif +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif #endif /* no yyoverflow */ - yyssp = yyss + size - 1; - yyvsp = yyvs + size - 1; -#ifdef YYLSP_NEEDED - yylsp = yyls + size - 1; + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; +#if YYLSP_NEEDED + yylsp = yyls + yysize - 1; #endif -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Stack size increased to %d\n", yystacksize); -#endif + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); if (yyssp >= yyss + yystacksize - 1) YYABORT; } -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Entering state %d\n", yystate); -#endif + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; - yybackup: + + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYFLAG) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* yychar is either YYEMPTY or YYEOF or a valid token in external form. */ if (yychar == YYEMPTY) { -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Reading a token: "); -#endif + YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } /* Convert token to internal form (in yychar1) for indexing tables with */ if (yychar <= 0) /* This means end of input. */ { yychar1 = 0; yychar = YYEOF; /* Don't call YYLEX any more */ -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Now at end of input.\n"); -#endif + YYDPRINTF ((stderr, "Now at end of input.\n")); } else { - yychar1 = YYTRANSLATE(yychar); + yychar1 = YYTRANSLATE (yychar); -#if YYDEBUG != 0 +#if YYDEBUG + /* We have to keep this `#if YYDEBUG', since we use variables + which are defined only if `YYDEBUG' is set. */ if (yydebug) { - fprintf (stderr, "Next token is %d (%s", yychar, yytname[yychar1]); - /* Give the individual parser a way to print the precise meaning - of a token, for further debugging info. */ -#ifdef YYPRINT + YYFPRINTF (stderr, "Next token is %d (%s", + yychar, yytname[yychar1]); + /* Give the individual parser a way to print the precise + meaning of a token, for further debugging info. */ +# ifdef YYPRINT YYPRINT (stderr, yychar, yylval); -#endif - fprintf (stderr, ")\n"); +# endif + YYFPRINTF (stderr, ")\n"); } #endif } yyn += yychar1; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) goto yydefault; yyn = yytable[yyn]; /* yyn is what to do for this token type in this state. Negative => reduce, -yyn is rule number. Positive => shift, yyn is new state. New state is final state => don't bother to shift, just return success. 0, or most negative number => error. */ if (yyn < 0) { if (yyn == YYFLAG) goto yyerrlab; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrlab; if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); -#endif + YYDPRINTF ((stderr, "Shifting token %d (%s), ", + yychar, yytname[yychar1])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; -#ifdef YYLSP_NEEDED +#if YYLSP_NEEDED *++yylsp = yylloc; #endif - /* count tokens shifted since error; after three, turn off error status. */ - if (yyerrstatus) yyerrstatus--; + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; yystate = yyn; goto yynewstate; -/* Do the default action for the current state. */ -yydefault: +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; + goto yyreduce; -/* Do a reduction. yyn is the number of a rule to reduce with. */ + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ yyreduce: + /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; - if (yylen > 0) - yyval = yyvsp[1-yylen]; /* implement default value of the action */ -#if YYDEBUG != 0 + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to the semantic value of + the lookahead token. This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + +#if YYLSP_NEEDED + /* Similarly for the default location. Let the user run additional + commands if for instance locations are ranges. */ + yyloc = yylsp[1-yylen]; + YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen); +#endif + +#if YYDEBUG + /* We have to keep this `#if YYDEBUG', since we use variables which + are defined only if `YYDEBUG' is set. */ if (yydebug) { - int i; + int yyi; - fprintf (stderr, "Reducing via rule %d (line %d), ", - yyn, yyrline[yyn]); + YYFPRINTF (stderr, "Reducing via rule %d (line %d), ", + yyn, yyrline[yyn]); /* Print the symbols being reduced, and their result. */ - for (i = yyprhs[yyn]; yyrhs[i] > 0; i++) - fprintf (stderr, "%s ", yytname[yyrhs[i]]); - fprintf (stderr, " -> %s\n", yytname[yyr1[yyn]]); + for (yyi = yyprhs[yyn]; yyrhs[yyi] > 0; yyi++) + YYFPRINTF (stderr, "%s ", yytname[yyrhs[yyi]]); + YYFPRINTF (stderr, " -> %s\n", yytname[yyr1[yyn]]); } #endif - switch (yyn) { case 2: -#line 213 "./vcc.y" -{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ; - break;} +#line 212 "vcc.y" +{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } + break; case 4: -#line 216 "./vcc.y" -{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; ; - break;} +#line 215 "vcc.y" +{ addList(&vObjList, yyvsp[0].vobj); curObj = 0; } + break; case 7: -#line 225 "./vcc.y" +#line 224 "vcc.y" { lexPushMode(L_VCARD); if (!pushVObject(VCCardProp)) YYERROR; - ; - break;} + } + break; case 8: -#line 230 "./vcc.y" +#line 229 "vcc.y" { lexPopMode(0); yyval.vobj = popVObject(); - ; - break;} + } + break; case 9: -#line 235 "./vcc.y" +#line 234 "vcc.y" { lexPushMode(L_VCARD); if (!pushVObject(VCCardProp)) YYERROR; - ; - break;} + } + break; case 10: -#line 240 "./vcc.y" +#line 239 "vcc.y" { lexPopMode(0); yyval.vobj = popVObject(); - ; - break;} + } + break; case 13: -#line 251 "./vcc.y" +#line 250 "vcc.y" { lexPushMode(L_VALUES); - ; - break;} + } + break; case 14: -#line 255 "./vcc.y" +#line 254 "vcc.y" { if (lexWithinMode(L_BASE64) || lexWithinMode(L_QUOTED_PRINTABLE)) lexPopMode(0); lexPopMode(0); - ; - break;} + } + break; case 16: -#line 264 "./vcc.y" +#line 263 "vcc.y" { enterProps(yyvsp[0].str); - ; - break;} + } + break; case 18: -#line 269 "./vcc.y" +#line 268 "vcc.y" { enterProps(yyvsp[0].str); - ; - break;} + } + break; case 22: -#line 282 "./vcc.y" +#line 281 "vcc.y" { enterAttr(yyvsp[0].str,0); - ; - break;} + } + break; case 23: -#line 286 "./vcc.y" +#line 285 "vcc.y" { enterAttr(yyvsp[-2].str,yyvsp[0].str); - ; - break;} + } + break; case 25: -#line 295 "./vcc.y" -{ appendValue(yyvsp[-1].str); ; - break;} +#line 294 "vcc.y" +{ enterValues(yyvsp[-1].str); } + break; case 27: -#line 297 "./vcc.y" -{ appendValue(yyvsp[0].str); ; - break;} +#line 296 "vcc.y" +{ enterValues(yyvsp[0].str); } + break; case 29: -#line 302 "./vcc.y" -{ yyval.str = 0; ; - break;} +#line 300 "vcc.y" +{ yyval.str = 0; } + break; case 30: -#line 307 "./vcc.y" -{ if (!pushVObject(VCCalProp)) YYERROR; ; - break;} +#line 305 "vcc.y" +{ if (!pushVObject(VCCalProp)) YYERROR; } + break; case 31: -#line 310 "./vcc.y" -{ yyval.vobj = popVObject(); ; - break;} +#line 308 "vcc.y" +{ yyval.vobj = popVObject(); } + break; case 32: -#line 312 "./vcc.y" -{ if (!pushVObject(VCCalProp)) YYERROR; ; - break;} +#line 310 "vcc.y" +{ if (!pushVObject(VCCalProp)) YYERROR; } + break; case 33: -#line 314 "./vcc.y" -{ yyval.vobj = popVObject(); ; - break;} +#line 312 "vcc.y" +{ yyval.vobj = popVObject(); } + break; case 39: -#line 329 "./vcc.y" +#line 327 "vcc.y" { lexPushMode(L_VEVENT); if (!pushVObject(VCEventProp)) YYERROR; - ; - break;} + } + break; case 40: -#line 335 "./vcc.y" +#line 333 "vcc.y" { lexPopMode(0); popVObject(); - ; - break;} + } + break; case 41: -#line 340 "./vcc.y" +#line 338 "vcc.y" { lexPushMode(L_VEVENT); if (!pushVObject(VCEventProp)) YYERROR; - ; - break;} + } + break; case 42: -#line 345 "./vcc.y" +#line 343 "vcc.y" { lexPopMode(0); popVObject(); - ; - break;} + } + break; case 43: -#line 353 "./vcc.y" +#line 351 "vcc.y" { lexPushMode(L_VTODO); if (!pushVObject(VCTodoProp)) YYERROR; - ; - break;} + } + break; case 44: -#line 359 "./vcc.y" +#line 357 "vcc.y" { lexPopMode(0); popVObject(); - ; - break;} + } + break; case 45: -#line 364 "./vcc.y" +#line 362 "vcc.y" { lexPushMode(L_VTODO); if (!pushVObject(VCTodoProp)) YYERROR; - ; - break;} + } + break; case 46: -#line 369 "./vcc.y" +#line 367 "vcc.y" { lexPopMode(0); popVObject(); - ; - break;} + } + break; } - /* the action file gets copied in in place of this dollarsign */ -#line 543 "/usr/share/bison.simple" +#line 705 "/usr/share/bison/bison.simple" + + yyvsp -= yylen; yyssp -= yylen; -#ifdef YYLSP_NEEDED +#if YYLSP_NEEDED yylsp -= yylen; #endif -#if YYDEBUG != 0 +#if YYDEBUG if (yydebug) { - short *ssp1 = yyss - 1; - fprintf (stderr, "state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); + short *yyssp1 = yyss - 1; + YYFPRINTF (stderr, "state stack now"); + while (yyssp1 != yyssp) + YYFPRINTF (stderr, " %d", *++yyssp1); + YYFPRINTF (stderr, "\n"); } #endif *++yyvsp = yyval; - -#ifdef YYLSP_NEEDED - yylsp++; - if (yylen == 0) - { - yylsp->first_line = yylloc.first_line; - yylsp->first_column = yylloc.first_column; - yylsp->last_line = (yylsp-1)->last_line; - yylsp->last_column = (yylsp-1)->last_column; - yylsp->text = 0; - } - else - { - yylsp->last_line = (yylsp+yylen-1)->last_line; - yylsp->last_column = (yylsp+yylen-1)->last_column; - } +#if YYLSP_NEEDED + *++yylsp = yyloc; #endif - /* Now "shift" the result of the reduction. - Determine what state that goes to, - based on the state we popped back to - and the rule number reduced by. */ + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTBASE] + *yyssp; if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTBASE]; goto yynewstate; -yyerrlab: /* here on detecting error */ - if (! yyerrstatus) - /* If not already recovering from an error, report this error. */ +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) { ++yynerrs; #ifdef YYERROR_VERBOSE yyn = yypact[yystate]; if (yyn > YYFLAG && yyn < YYLAST) { - int size = 0; - char *msg; - int x, count; - - count = 0; - /* Start X at -yyn if nec to avoid negative indexes in yycheck. */ - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) - size += strlen(yytname[x]) + 15, count++; - msg = (char *) malloc(size + 15); - if (msg != 0) + YYSIZE_T yysize = 0; + char *yymsg; + int yyx, yycount; + + yycount = 0; + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) + if (yycheck[yyx + yyn] == yyx) + yysize += yystrlen (yytname[yyx]) + 15, yycount++; + yysize += yystrlen ("parse error, unexpected ") + 1; + yysize += yystrlen (yytname[YYTRANSLATE (yychar)]); + yymsg = (char *) YYSTACK_ALLOC (yysize); + if (yymsg != 0) { - strcpy(msg, "parse error"); + char *yyp = yystpcpy (yymsg, "parse error, unexpected "); + yyp = yystpcpy (yyp, yytname[YYTRANSLATE (yychar)]); - if (count < 5) + if (yycount < 5) { - count = 0; - for (x = (yyn < 0 ? -yyn : 0); - x < (sizeof(yytname) / sizeof(char *)); x++) - if (yycheck[x + yyn] == x) + yycount = 0; + for (yyx = yyn < 0 ? -yyn : 0; + yyx < (int) (sizeof (yytname) / sizeof (char *)); + yyx++) + if (yycheck[yyx + yyn] == yyx) { - strcat(msg, count == 0 ? ", expecting `" : " or `"); - strcat(msg, yytname[x]); - strcat(msg, "'"); - count++; + const char *yyq = ! yycount ? ", expecting " : " or "; + yyp = yystpcpy (yyp, yyq); + yyp = yystpcpy (yyp, yytname[yyx]); + yycount++; } } - yyerror(msg); - free(msg); + yyerror (yymsg); + YYSTACK_FREE (yymsg); } else - yyerror ("parse error; also virtual memory exceeded"); + yyerror ("parse error; also virtual memory exhausted"); } else -#endif /* YYERROR_VERBOSE */ - yyerror("parse error"); +#endif /* defined (YYERROR_VERBOSE) */ + yyerror ("parse error"); } - goto yyerrlab1; -yyerrlab1: /* here on error raised explicitly by an action */ + +/*--------------------------------------------------. +| yyerrlab1 -- error raised explicitly by an action | +`--------------------------------------------------*/ +yyerrlab1: if (yyerrstatus == 3) { - /* if just tried and failed to reuse lookahead token after an error, discard it. */ + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ /* return failure if at end of input */ if (yychar == YYEOF) YYABORT; - -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); -#endif - + YYDPRINTF ((stderr, "Discarding token %d (%s).\n", + yychar, yytname[yychar1])); yychar = YYEMPTY; } - /* Else will try to reuse lookahead token - after shifting the error token. */ + /* Else will try to reuse lookahead token after shifting the error + token. */ yyerrstatus = 3; /* Each real token shifted decrements this */ goto yyerrhandle; -yyerrdefault: /* current state does not do anything special for the error token. */ +/*-------------------------------------------------------------------. +| yyerrdefault -- current state does not do anything special for the | +| error token. | +`-------------------------------------------------------------------*/ +yyerrdefault: #if 0 /* This is wrong; only states that explicitly want error tokens should shift them. */ - yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ - if (yyn) goto yydefault; + + /* If its default is to accept any token, ok. Otherwise pop it. */ + yyn = yydefact[yystate]; + if (yyn) + goto yydefault; #endif -yyerrpop: /* pop the current state because it cannot handle the error token */ - if (yyssp == yyss) YYABORT; +/*---------------------------------------------------------------. +| yyerrpop -- pop the current state because it cannot handle the | +| error token | +`---------------------------------------------------------------*/ +yyerrpop: + if (yyssp == yyss) + YYABORT; yyvsp--; yystate = *--yyssp; -#ifdef YYLSP_NEEDED +#if YYLSP_NEEDED yylsp--; #endif -#if YYDEBUG != 0 +#if YYDEBUG if (yydebug) { - short *ssp1 = yyss - 1; - fprintf (stderr, "Error: state stack now"); - while (ssp1 != yyssp) - fprintf (stderr, " %d", *++ssp1); - fprintf (stderr, "\n"); + short *yyssp1 = yyss - 1; + YYFPRINTF (stderr, "Error: state stack now"); + while (yyssp1 != yyssp) + YYFPRINTF (stderr, " %d", *++yyssp1); + YYFPRINTF (stderr, "\n"); } #endif +/*--------------. +| yyerrhandle. | +`--------------*/ yyerrhandle: - yyn = yypact[yystate]; if (yyn == YYFLAG) goto yyerrdefault; yyn += YYTERROR; if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) goto yyerrdefault; yyn = yytable[yyn]; if (yyn < 0) { if (yyn == YYFLAG) goto yyerrpop; yyn = -yyn; goto yyreduce; } else if (yyn == 0) goto yyerrpop; if (yyn == YYFINAL) YYACCEPT; -#if YYDEBUG != 0 - if (yydebug) - fprintf(stderr, "Shifting error token, "); -#endif + YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; -#ifdef YYLSP_NEEDED +#if YYLSP_NEEDED *++yylsp = yylloc; #endif yystate = yyn; goto yynewstate; - yyacceptlab: - /* YYACCEPT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); -#endif - } - return 0; - yyabortlab: - /* YYABORT comes here. */ - if (yyfree_stacks) - { - free (yyss); - free (yyvs); -#ifdef YYLSP_NEEDED - free (yyls); +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +/*---------------------------------------------. +| yyoverflowab -- parser overflow comes here. | +`---------------------------------------------*/ +yyoverflowlab: + yyerror ("parser stack overflow"); + yyresult = 2; + /* Fall through. */ + +yyreturn: +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); #endif - } - return 1; + return yyresult; } -#line 375 "./vcc.y" +#line 373 "vcc.y" -/****************************************************************************/ static int pushVObject(const char *prop) { VObject *newObj; if (ObjStackTop == MAXLEVEL) return FALSE; ObjStack[++ObjStackTop] = curObj; if (curObj) { newObj = addProp(curObj,prop); curObj = newObj; } else curObj = newVObject(prop); return TRUE; } -/****************************************************************************/ /* This pops the recently built vCard off the stack and returns it. */ static VObject* popVObject() { VObject *oldObj; if (ObjStackTop < 0) { yyerror("pop on empty Object Stack\n"); return 0; } oldObj = curObj; curObj = ObjStack[ObjStackTop--]; return oldObj; } -/* static void enterValues(const char *value) */ -/* { */ -/* if (fieldedProp && *fieldedProp) { */ -/* if (value) { */ -/* addPropValue(curProp,*fieldedProp,value); */ -/* } */ - /* else this field is empty, advance to next field */ -/* fieldedProp++; */ -/* } */ -/* else { */ -/* if (value) { */ -/* setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); */ -/* } */ -/* } */ -/* deleteStr(value); */ -/* } */ - -static void appendValue(const char *value) -{ - char *p1, *p2; - wchar_t *p3; - int i; - - if (fieldedProp && *fieldedProp) { - if (value) { - addPropValue(curProp, *fieldedProp, value); +static void enterValues(const char *value) + { + if (fieldedProp && *fieldedProp) { + if (value) { + addPropValue(curProp,*fieldedProp,value); + } + /* else this field is empty, advance to next field */ + fieldedProp++; + } + else { + if (value) { + char *p1, *p2; + wchar_t *p3; + int i; + + /* If the property already has a string value, we append this one, + using ';' to separate the values. */ + if (vObjectUStringZValue(curProp)) { + p1 = fakeCString(vObjectUStringZValue(curProp)); + p2 = malloc((strlen(p1)+strlen(value)+1)); + strcpy(p2, p1); + deleteStr(p1); + + i = strlen(p2); + p2[i] = ';'; + p2[i+1] = '\0'; + p2 = strcat(p2, value); + p3 = (wchar_t *) vObjectUStringZValue(curProp); + free(p3); + setVObjectUStringZValue_(curProp,fakeUnicode(p2,0)); + deleteStr(p2); + } else { + setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); + } + } } - /* else this field is empty, advance to next field */ - fieldedProp++; - } else { - if (value) { - if (vObjectUStringZValue(curProp)) { - p1 = fakeCString(vObjectUStringZValue(curProp)); - p2 = malloc(sizeof(char *) * (strlen(p1)+strlen(value)+1)); - strcpy(p2, p1); - deleteStr(p1); - - i = strlen(p2); - p2[i] = ','; - p2[i+1] = '\0'; - p2 = strcat(p2, value); - p3 = (wchar_t *) vObjectUStringZValue(curProp); - free(p3); - setVObjectUStringZValue_(curProp,fakeUnicode(p2,0)); - deleteStr(p2); - } else { - setVObjectUStringZValue_(curProp,fakeUnicode(value,0)); - } + deleteStr(value); } - } - deleteStr(value); -} - static void enterProps(const char *s) { curProp = addGroup(curObj,s); deleteStr(s); } static void enterAttr(const char *s1, const char *s2) { - const char *p1=0L, *p2=0L; + const char *p1, *p2; p1 = lookupProp_(s1); if (s2) { VObject *a; p2 = lookupProp_(s2); a = addProp(curProp,p1); setVObjectStringZValue(a,p2); } else addProp(curProp,p1); - if (strcasecmp(p1,VCBase64Prop) == 0 || (s2 && strcasecmp(p2,VCBase64Prop)==0)) + if (stricmp(p1,VCBase64Prop) == 0 || (s2 && stricmp(p2,VCBase64Prop)==0)) lexPushMode(L_BASE64); - else if (strcasecmp(p1,VCQuotedPrintableProp) == 0 - || (s2 && strcasecmp(p2,VCQuotedPrintableProp)==0)) + else if (stricmp(p1,VCQuotedPrintableProp) == 0 + || (s2 && stricmp(p2,VCQuotedPrintableProp)==0)) lexPushMode(L_QUOTED_PRINTABLE); deleteStr(s1); deleteStr(s2); } #define MAX_LEX_LOOKAHEAD_0 32 #define MAX_LEX_LOOKAHEAD 64 #define MAX_LEX_MODE_STACK_SIZE 10 #define LEXMODE() (lexBuf.lexModeStack[lexBuf.lexModeStackTop]) struct LexBuf { /* input */ +#ifdef INCLUDEMFC + CFile *inputFile; +#else FILE *inputFile; +#endif char *inputString; unsigned long curPos; unsigned long inputLen; /* lookahead buffer */ /* -- lookahead buffer is short instead of char so that EOF / can be represented correctly. */ unsigned long len; short buf[MAX_LEX_LOOKAHEAD]; unsigned long getPtr; /* context stack */ unsigned long lexModeStackTop; enum LexMode lexModeStack[MAX_LEX_MODE_STACK_SIZE]; /* token buffer */ unsigned long maxToken; char *strs; unsigned long strsLen; } lexBuf; static void lexPushMode(enum LexMode mode) { if (lexBuf.lexModeStackTop == (MAX_LEX_MODE_STACK_SIZE-1)) yyerror("lexical context stack overflow"); else { lexBuf.lexModeStack[++lexBuf.lexModeStackTop] = mode; } } static void lexPopMode(int top) { /* special case of pop for ease of error recovery -- this version will never underflow */ if (top) lexBuf.lexModeStackTop = 0; else if (lexBuf.lexModeStackTop > 0) lexBuf.lexModeStackTop--; } static int lexWithinMode(enum LexMode mode) { unsigned long i; for (i=0;i<lexBuf.lexModeStackTop;i++) if (mode == lexBuf.lexModeStack[i]) return 1; return 0; } -static int lexGetc_() +static char lexGetc_() { /* get next char from input, no buffering. */ if (lexBuf.curPos == lexBuf.inputLen) return EOF; else if (lexBuf.inputString) return *(lexBuf.inputString + lexBuf.curPos++); else { - if (!feof(lexBuf.inputFile)) - return fgetc(lexBuf.inputFile); - else - return EOF; +#ifdef INCLUDEMFC + char result; + return lexBuf.inputFile->Read(&result, 1) == 1 ? result : EOF; +#else + return fgetc(lexBuf.inputFile); +#endif } } static int lexGeta() { ++lexBuf.len; return (lexBuf.buf[lexBuf.getPtr] = lexGetc_()); } static int lexGeta_(int i) { ++lexBuf.len; return (lexBuf.buf[(lexBuf.getPtr+i)%MAX_LEX_LOOKAHEAD] = lexGetc_()); } static void lexSkipLookahead() { if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { /* don't skip EOF. */ lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; lexBuf.len--; } } static int lexLookahead() { int c = (lexBuf.len)? lexBuf.buf[lexBuf.getPtr]: lexGeta(); /* do the \r\n -> \n or \r -> \n translation here */ if (c == '\r') { int a = (lexBuf.len>1)? lexBuf.buf[(lexBuf.getPtr+1)%MAX_LEX_LOOKAHEAD]: lexGeta_(1); if (a == '\n') { lexSkipLookahead(); } lexBuf.buf[lexBuf.getPtr] = c = '\n'; } else if (c == '\n') { - int a; - if (lexBuf.len > 1) - a = lexBuf.buf[lexBuf.getPtr]; - else - a = lexGeta_(1); + int a = (lexBuf.len>1)? + lexBuf.buf[lexBuf.getPtr+1]: + lexGeta_(1); if (a == '\r') { lexSkipLookahead(); } lexBuf.buf[lexBuf.getPtr] = '\n'; } return c; } static int lexGetc() { int c = lexLookahead(); if (lexBuf.len > 0 && lexBuf.buf[lexBuf.getPtr]!=EOF) { /* EOF will remain in lookahead buffer */ lexBuf.getPtr = (lexBuf.getPtr + 1) % MAX_LEX_LOOKAHEAD; lexBuf.len--; } return c; } static void lexSkipLookaheadWord() { if (lexBuf.strsLen <= lexBuf.len) { lexBuf.len -= lexBuf.strsLen; lexBuf.getPtr = (lexBuf.getPtr + lexBuf.strsLen) % MAX_LEX_LOOKAHEAD; } } static void lexClearToken() { lexBuf.strsLen = 0; } static void lexAppendc(int c) { - /* not sure if I am doing this right to fix purify report -- PGB */ - lexBuf.strs = (char *) realloc(lexBuf.strs, (size_t) lexBuf.strsLen + 1); lexBuf.strs[lexBuf.strsLen] = c; /* append up to zero termination */ if (c == 0) return; lexBuf.strsLen++; if (lexBuf.strsLen > lexBuf.maxToken) { /* double the token string size */ lexBuf.maxToken <<= 1; lexBuf.strs = (char*) realloc(lexBuf.strs,(size_t)lexBuf.maxToken); } } static char* lexStr() { return dupStr(lexBuf.strs,(size_t)lexBuf.strsLen+1); } static void lexSkipWhite() { int c = lexLookahead(); while (c == ' ' || c == '\t') { lexSkipLookahead(); c = lexLookahead(); } } static char* lexGetWord() { int c; lexSkipWhite(); lexClearToken(); c = lexLookahead(); - /* some "words" have a space in them, like "NEEDS ACTION". - this may be an oversight of the spec, but it is true nevertheless. - while (c != EOF && !strchr("\t\n ;:=",c)) { */ - while (c != EOF && !strchr("\n;:=",c)) { + while (c != EOF && !strchr("\t\n ;:=",c)) { lexAppendc(c); lexSkipLookahead(); c = lexLookahead(); } lexAppendc(0); return lexStr(); } -void lexPushLookahead(char *s, int len) { - int putptr; - if (len == 0) len = strlen(s); - putptr = (int)lexBuf.getPtr - len; - /* this function assumes that length of word to push back - / is not greater than MAX_LEX_LOOKAHEAD. - */ - if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; - lexBuf.getPtr = putptr; - while (*s) { - lexBuf.buf[putptr] = *s++; - putptr = (putptr + 1) % MAX_LEX_LOOKAHEAD; - } - lexBuf.len += len; - } - static void lexPushLookaheadc(int c) { int putptr; /* can't putback EOF, because it never leaves lookahead buffer */ if (c == EOF) return; putptr = (int)lexBuf.getPtr - 1; if (putptr < 0) putptr += MAX_LEX_LOOKAHEAD; lexBuf.getPtr = putptr; lexBuf.buf[putptr] = c; lexBuf.len += 1; } static char* lexLookaheadWord() { /* this function can lookahead word with max size of MAX_LEX_LOOKAHEAD_0 / and thing bigger than that will stop the lookahead and return 0; / leading white spaces are not recoverable. */ int c; int len = 0; int curgetptr = 0; lexSkipWhite(); lexClearToken(); curgetptr = (int)lexBuf.getPtr; /* remember! */ while (len < (MAX_LEX_LOOKAHEAD_0)) { c = lexGetc(); len++; if (c == EOF || strchr("\t\n ;:=", c)) { lexAppendc(0); /* restore lookahead buf. */ lexBuf.len += len; lexBuf.getPtr = curgetptr; return lexStr(); } else lexAppendc(c); } lexBuf.len += len; /* char that has been moved to lookahead buffer */ lexBuf.getPtr = curgetptr; return 0; } #ifdef _SUPPORT_LINE_FOLDING static void handleMoreRFC822LineBreak(int c) { /* suport RFC 822 line break in cases like * ADR: foo; * morefoo; * more foo; */ if (c == ';') { int a; lexSkipLookahead(); /* skip white spaces */ a = lexLookahead(); while (a == ' ' || a == '\t') { lexSkipLookahead(); a = lexLookahead(); } if (a == '\n') { lexSkipLookahead(); a = lexLookahead(); if (a == ' ' || a == '\t') { /* continuation, throw away all the \n and spaces read so * far */ lexSkipWhite(); lexPushLookaheadc(';'); } else { lexPushLookaheadc('\n'); lexPushLookaheadc(';'); } } else { lexPushLookaheadc(';'); } } } static char* lexGet1Value() { int c; lexSkipWhite(); c = lexLookahead(); lexClearToken(); while (c != EOF && c != ';') { if (c == '\n') { int a; lexSkipLookahead(); a = lexLookahead(); if (a == ' ' || a == '\t') { lexAppendc(' '); lexSkipLookahead(); } else { lexPushLookaheadc('\n'); break; } } else { lexAppendc(c); lexSkipLookahead(); } c = lexLookahead(); } lexAppendc(0); handleMoreRFC822LineBreak(c); return c==EOF?0:lexStr(); } #endif -char* lexGetStrUntil(char *termset) { - int c = lexLookahead(); - lexClearToken(); - while (c != EOF && !strchr(termset,c)) { - lexAppendc(c); - lexSkipLookahead(); - c = lexLookahead(); - } - lexAppendc(0); - return c==EOF?0:lexStr(); - } static int match_begin_name(int end) { char *n = lexLookaheadWord(); int token = ID; if (n) { - if (!strcasecmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; - else if (!strcasecmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; - else if (!strcasecmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; - else if (!strcasecmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; + if (!stricmp(n,"vcard")) token = end?END_VCARD:BEGIN_VCARD; + else if (!stricmp(n,"vcalendar")) token = end?END_VCAL:BEGIN_VCAL; + else if (!stricmp(n,"vevent")) token = end?END_VEVENT:BEGIN_VEVENT; + else if (!stricmp(n,"vtodo")) token = end?END_VTODO:BEGIN_VTODO; deleteStr(n); return token; } return 0; } +#ifdef INCLUDEMFC +void initLex(const char *inputstring, unsigned long inputlen, CFile *inputfile) +#else void initLex(const char *inputstring, unsigned long inputlen, FILE *inputfile) +#endif { /* initialize lex mode stack */ lexBuf.lexModeStack[lexBuf.lexModeStackTop=0] = L_NORMAL; /* iniatialize lex buffer. */ lexBuf.inputString = (char*) inputstring; lexBuf.inputLen = inputlen; lexBuf.curPos = 0; lexBuf.inputFile = inputfile; lexBuf.len = 0; lexBuf.getPtr = 0; lexBuf.maxToken = MAXTOKEN; lexBuf.strs = (char*)malloc(MAXTOKEN); lexBuf.strsLen = 0; } static void finiLex() { free(lexBuf.strs); } -/****************************************************************************/ /* This parses and converts the base64 format for binary encoding into * a decoded buffer (allocated with new). See RFC 1521. */ static char * lexGetDataFromBase64() { unsigned long bytesLen = 0, bytesMax = 0; int quadIx = 0, pad = 0; unsigned long trip = 0; unsigned char b; int c; unsigned char *bytes = NULL; unsigned char *oldBytes = NULL; DBG_(("db: lexGetDataFromBase64\n")); while (1) { c = lexGetc(); if (c == '\n') { ++mime_lineNum; if (lexLookahead() == '\n') { /* a '\n' character by itself means end of data */ break; } else continue; /* ignore '\n' */ } else { if ((c >= 'A') && (c <= 'Z')) b = (unsigned char)(c - 'A'); else if ((c >= 'a') && (c <= 'z')) b = (unsigned char)(c - 'a') + 26; else if ((c >= '0') && (c <= '9')) b = (unsigned char)(c - '0') + 52; else if (c == '+') b = 62; else if (c == '/') b = 63; else if (c == '=') { b = 0; pad++; } else if ((c == ' ') || (c == '\t')) { continue; } else { /* error condition */ if (bytes) free(bytes); else if (oldBytes) free(oldBytes); /* error recovery: skip until 2 adjacent newlines. */ DBG_(("db: invalid character 0x%x '%c'\n", c,c)); if (c != EOF) { c = lexGetc(); while (c != EOF) { if (c == '\n' && lexLookahead() == '\n') { ++mime_lineNum; break; } c = lexGetc(); } } return NULL; } trip = (trip << 6) | b; if (++quadIx == 4) { unsigned char outBytes[3]; int numOut; int i; for (i = 0; i < 3; i++) { outBytes[2-i] = (unsigned char)(trip & 0xFF); trip >>= 8; } numOut = 3 - pad; if (bytesLen + numOut > bytesMax) { if (!bytes) { bytesMax = 1024; bytes = (unsigned char*)malloc((size_t)bytesMax); } else { bytesMax <<= 2; oldBytes = bytes; bytes = (unsigned char*)realloc(bytes,(size_t)bytesMax); } if (bytes == 0) { mime_error("out of memory while processing BASE64 data\n"); } } if (bytes) { memcpy(bytes + bytesLen, outBytes, numOut); bytesLen += numOut; } trip = 0; quadIx = 0; } } } /* while */ DBG_(("db: bytesLen = %d\n", bytesLen)); /* kludge: all this won't be necessary if we have tree form representation */ if (bytes) { setValueWithSize(curProp,bytes,(unsigned int)bytesLen); free(bytes); } else if (oldBytes) { setValueWithSize(curProp,oldBytes,(unsigned int)bytesLen); free(oldBytes); } return 0; } static int match_begin_end_name(int end) { int token; lexSkipWhite(); if (lexLookahead() != ':') return ID; lexSkipLookahead(); lexSkipWhite(); token = match_begin_name(end); if (token == ID) { lexPushLookaheadc(':'); DBG_(("db: ID '%s'\n", yylval.str)); return ID; } else if (token != 0) { lexSkipLookaheadWord(); deleteStr(yylval.str); DBG_(("db: begin/end %d\n", token)); return token; } return 0; } static char* lexGetQuotedPrintable() { char cur; lexClearToken(); do { cur = lexGetc(); switch (cur) { case '=': { int c = 0; int next[2]; int i; for (i = 0; i < 2; i++) { next[i] = lexGetc(); if (next[i] >= '0' && next[i] <= '9') c = c * 16 + next[i] - '0'; else if (next[i] >= 'A' && next[i] <= 'F') c = c * 16 + next[i] - 'A' + 10; else break; } if (i == 0) { /* single '=' follow by LINESEP is continuation sign? */ if (next[0] == '\n') { ++mime_lineNum; } else { lexPushLookaheadc('='); goto EndString; } } else if (i == 1) { lexPushLookaheadc(next[1]); lexPushLookaheadc(next[0]); lexAppendc('='); } else { lexAppendc(c); } break; } /* '=' */ case '\n': { lexPushLookaheadc('\n'); goto EndString; } case (char)EOF: break; default: lexAppendc(cur); break; } /* switch */ } while (cur != (char)EOF); EndString: lexAppendc(0); return lexStr(); } /* LexQuotedPrintable */ -static int yylex() { +int yylex() { int lexmode = LEXMODE(); if (lexmode == L_VALUES) { int c = lexGetc(); if (c == ';') { DBG_(("db: SEMICOLON\n")); lexPushLookaheadc(c); +#ifdef _SUPPORT_LINE_FOLDING handleMoreRFC822LineBreak(c); +#endif lexSkipLookahead(); return SEMICOLON; } else if (strchr("\n",c)) { ++mime_lineNum; /* consume all line separator(s) adjacent to each other */ c = lexLookahead(); while (strchr("\n",c)) { lexSkipLookahead(); c = lexLookahead(); ++mime_lineNum; } DBG_(("db: LINESEP\n")); return LINESEP; } else { char *p = 0; lexPushLookaheadc(c); if (lexWithinMode(L_BASE64)) { /* get each char and convert to bin on the fly... */ p = lexGetDataFromBase64(); yylval.str = p; return STRING; } else if (lexWithinMode(L_QUOTED_PRINTABLE)) { p = lexGetQuotedPrintable(); } else { #ifdef _SUPPORT_LINE_FOLDING p = lexGet1Value(); #else p = lexGetStrUntil(";\n"); #endif } if (p) { DBG_(("db: STRING: '%s'\n", p)); yylval.str = p; return STRING; } else return 0; } } - else { /* normal mode */ while (1) { int c = lexGetc(); switch(c) { case ':': { /* consume all line separator(s) adjacent to each other */ /* ignoring linesep immediately after colon. */ - c = lexLookahead(); +/* c = lexLookahead(); while (strchr("\n",c)) { lexSkipLookahead(); c = lexLookahead(); ++mime_lineNum; - } + }*/ DBG_(("db: COLON\n")); return COLON; } case ';': DBG_(("db: SEMICOLON\n")); return SEMICOLON; case '=': DBG_(("db: EQ\n")); return EQ; - /* ignore tabs/newlines in this mode. We can't ignore - * spaces, because values like NEEDS ACTION have a space. */ - case '\t': continue; + /* ignore whitespace in this mode */ + case '\t': + case ' ': continue; case '\n': { ++mime_lineNum; continue; } case EOF: return 0; break; - default: { - lexPushLookaheadc(c); - /* pending lutz : why linker error with isalpha(c)? */ - /*if ( isalpha(c) || c == ' ') { */ - if ( ( c >= 'A' && c <= 'Z') || ( c >= 'a' && c <= 'z') || c == ' ') { - + default: { + lexPushLookaheadc(c); + if (isalpha(c)) { char *t = lexGetWord(); yylval.str = t; - if (!strcasecmp(t, "begin")) { + if (!stricmp(t, "begin")) { return match_begin_end_name(0); } - else if (!strcasecmp(t,"end")) { + else if (!stricmp(t,"end")) { return match_begin_end_name(1); } else { DBG_(("db: ID '%s'\n", t)); return ID; } } else { - /* unknown token */ + /* unknow token */ return 0; - } + } break; } } } } - return 0; } /***************************************************************************/ -/*** Public Functions ****/ +/*** Public Functions ****/ /***************************************************************************/ static VObject* Parse_MIMEHelper() { ObjStackTop = -1; mime_numErrors = 0; mime_lineNum = 1; vObjList = 0; curObj = 0; if (yyparse() != 0) return 0; finiLex(); return vObjList; } -/****************************************************************************/ -VObject* Parse_MIME(const char *input, unsigned long len) +DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len) { initLex(input, len, 0); return Parse_MIMEHelper(); } +#if INCLUDEMFC + +DLLEXPORT(VObject*) Parse_MIME_FromFile(CFile *file) + { + unsigned long startPos; + VObject *result; + + initLex(0,-1,file); + startPos = file->GetPosition(); + if (!(result = Parse_MIMEHelper())) + file->Seek(startPos, CFile::begin); + return result; + } + +#else + VObject* Parse_MIME_FromFile(FILE *file) { - VObject *result; + VObject *result; long startPos; initLex(0,(unsigned long)-1,file); startPos = ftell(file); if (!(result = Parse_MIMEHelper())) { fseek(file,startPos,SEEK_SET); } return result; } -VObject* Parse_MIME_FromFileName(const char *fname) +DLLEXPORT(VObject*) Parse_MIME_FromFileName(char *fname) { FILE *fp = fopen(fname,"r"); if (fp) { VObject* o = Parse_MIME_FromFile(fp); fclose(fp); return o; } else { - char msg[255]; - sprintf(msg, "can't open file '%s' for reading\n", fname); + char msg[256]; + snprintf(msg, sizeof(msg), "can't open file '%s' for reading\n", fname); mime_error_(msg); return 0; } } -/****************************************************************************/ -void YYDebug(const char *s) -{ - Parse_Debug(s); -} +#endif static MimeErrorHandler mimeErrorHandler; -void registerMimeErrorHandler(MimeErrorHandler me) +DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler me) { mimeErrorHandler = me; } static void mime_error(char *s) { char msg[256]; if (mimeErrorHandler) { sprintf(msg,"%s at line %d", s, mime_lineNum); mimeErrorHandler(msg); } } static void mime_error_(char *s) { if (mimeErrorHandler) { mimeErrorHandler(s); } } diff --git a/libkcal/versit/vcc.h b/libkcal/versit/vcc.h index 03886d1..0e52034 100644 --- a/libkcal/versit/vcc.h +++ b/libkcal/versit/vcc.h @@ -1,76 +1,80 @@ /*************************************************************************** (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. For purposes of this license notice, the term Licensors shall mean, collectively, Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. The term Licensor shall mean any of the Licensors. Subject to acceptance of the following conditions, permission is hereby granted by Licensors without the need for written agreement and without license or royalty fees, to use, copy, modify and distribute this software for any purpose. The above copyright notice and the following four paragraphs must be reproduced in all copies of this software and any software including this software. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS. IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The software is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ #ifndef __VCC_H__ #define __VCC_H__ 1 #include "vobject.h" #if defined(__CPLUSPLUS__) || defined(__cplusplus) extern "C" { #endif typedef void (*MimeErrorHandler)(char *); -extern void registerMimeErrorHandler(MimeErrorHandler); +extern DLLEXPORT(void) registerMimeErrorHandler(MimeErrorHandler); -extern VObject* Parse_MIME(const char *input, unsigned long len); -extern VObject* Parse_MIME_FromFileName(const char* fname); +extern DLLEXPORT(VObject*) Parse_MIME(const char *input, unsigned long len); +extern DLLEXPORT(VObject*) Parse_MIME_FromFileName(char* fname); /* NOTE regarding Parse_MIME_FromFile -The function below, Parse_MIME_FromFile, come in two flavors, +The function above, Parse_MIME_FromFile, comes in two flavors, neither of which is exported from the DLL. Each version takes a CFile or FILE* as a parameter, neither of which can be passed across a DLL interface (at least that is my experience). If you are linking this code into your build directly then you may find them a more convenient API that the other flavors that take a file name. If you use them with the DLL LIB you will get a link error. */ +#if INCLUDEMFC +extern VObject* Parse_MIME_FromFile(CFile *file); +#else extern VObject* Parse_MIME_FromFile(FILE *file); +#endif #if defined(__CPLUSPLUS__) || defined(__cplusplus) } #endif #endif /* __VCC_H__ */ diff --git a/libkcal/versit/vobject.c b/libkcal/versit/vobject.c index 637efb2..3fac63e 100644 --- a/libkcal/versit/vobject.c +++ b/libkcal/versit/vobject.c @@ -1,1433 +1,1454 @@ /*************************************************************************** (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. For purposes of this license notice, the term Licensors shall mean, collectively, Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. The term Licensor shall mean any of the Licensors. Subject to acceptance of the following conditions, permission is hereby granted by Licensors without the need for written agreement and without license or royalty fees, to use, copy, modify and distribute this software for any purpose. The above copyright notice and the following four paragraphs must be reproduced in all copies of this software and any software including this software. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS. IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The software is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ /* * src: vobject.c * doc: vobject and APIs to construct vobject, APIs pretty print * vobject, and convert a vobject into its textual representation. */ -#include <stdlib.h> +#ifdef WIN32 +#define snprintf _snprintf +#define strcasecmp stricmp +#endif #include "vobject.h" +#include <stdlib.h> #include <string.h> #include <stdio.h> -#ifdef _WIN32_ +#include <fcntl.h> - #define strcasecmp _stricmp -#endif - -#define NAME_OF(o) o->id +#define NAME_OF(o) o->id #define VALUE_TYPE(o) o->valType #define STRINGZ_VALUE_OF(o) o->val.strs #define USTRINGZ_VALUE_OF(o) o->val.ustrs #define INTEGER_VALUE_OF(o) o->val.i #define LONG_VALUE_OF(o) o->val.l #define ANY_VALUE_OF(o) o->val.any #define VOBJECT_VALUE_OF(o) o->val.vobj +typedef union ValueItem { + const char *strs; + const wchar_t *ustrs; + unsigned int i; + unsigned long l; + void *any; + VObject *vobj; + } ValueItem; + +struct VObject { + VObject *next; + const char *id; + VObject *prop; + unsigned short valType; + ValueItem val; + }; + +typedef struct StrItem StrItem; + +struct StrItem { + StrItem *next; + const char *s; + unsigned int refCnt; + }; + const char** fieldedProp; /*---------------------------------------------------------------------- The following functions involve with memory allocation: newVObject deleteVObject dupStr deleteStr newStrItem deleteStrItem ----------------------------------------------------------------------*/ -VObject* newVObject_(const char *id) +DLLEXPORT(VObject*) newVObject_(const char *id) { VObject *p = (VObject*)malloc(sizeof(VObject)); p->next = 0; p->id = id; p->prop = 0; VALUE_TYPE(p) = 0; ANY_VALUE_OF(p) = 0; return p; } -VObject* newVObject(const char *id) +DLLEXPORT(VObject*) newVObject(const char *id) { return newVObject_(lookupStr(id)); } -void deleteVObject(VObject *p) +DLLEXPORT(void) deleteVObject(VObject *p) { - if (p->id) unUseStr(p->id); - if (p) free(p); - p = NULL; } -char* dupStr(const char *s, unsigned int size) +DLLEXPORT(char*) dupStr(const char *s, unsigned int size) { char *t; if (size == 0) { size = strlen(s); } t = (char*)malloc(size+1); if (t) { memcpy(t,s,size); t[size] = 0; return t; } else { return (char*)0; } } -void deleteStr(const char *p) +DLLEXPORT(void) deleteStr(const char *p) { - if (p) - free((void*)p); - p = NULL; + if (p) free((void*)p); } static StrItem* newStrItem(const char *s, StrItem *next) { StrItem *p = (StrItem*)malloc(sizeof(StrItem)); p->next = next; p->s = s; p->refCnt = 1; return p; } static void deleteStrItem(StrItem *p) { - if (p) - free((void*)p); - p = NULL; + free((void*)p); } /*---------------------------------------------------------------------- The following function provide accesses to VObject's value. ----------------------------------------------------------------------*/ -const char* vObjectName(VObject *o) +DLLEXPORT(const char*) vObjectName(VObject *o) { return NAME_OF(o); } -void setVObjectName(VObject *o, const char* id) +DLLEXPORT(void) setVObjectName(VObject *o, const char* id) { NAME_OF(o) = id; } -const char* vObjectStringZValue(VObject *o) +DLLEXPORT(const char*) vObjectStringZValue(VObject *o) { return STRINGZ_VALUE_OF(o); } -void setVObjectStringZValue(VObject *o, const char *s) +DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s) { STRINGZ_VALUE_OF(o) = dupStr(s,0); VALUE_TYPE(o) = VCVT_STRINGZ; } -void setVObjectStringZValue_(VObject *o, const char *s) +DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s) { STRINGZ_VALUE_OF(o) = s; VALUE_TYPE(o) = VCVT_STRINGZ; } -const wchar_t* vObjectUStringZValue(VObject *o) +DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o) { return USTRINGZ_VALUE_OF(o); } -void setVObjectUStringZValue(VObject *o, const wchar_t *s) +DLLEXPORT(void) setVObjectUStringZValue(VObject *o, const wchar_t *s) { USTRINGZ_VALUE_OF(o) = (wchar_t*) dupStr((char*)s,(uStrLen(s)+1)*2); VALUE_TYPE(o) = VCVT_USTRINGZ; } -void setVObjectUStringZValue_(VObject *o, const wchar_t *s) +DLLEXPORT(void) setVObjectUStringZValue_(VObject *o, const wchar_t *s) { USTRINGZ_VALUE_OF(o) = s; VALUE_TYPE(o) = VCVT_USTRINGZ; } -unsigned int vObjectIntegerValue(VObject *o) +DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o) { return INTEGER_VALUE_OF(o); } -void setVObjectIntegerValue(VObject *o, unsigned int i) +DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i) { INTEGER_VALUE_OF(o) = i; VALUE_TYPE(o) = VCVT_UINT; } -unsigned long vObjectLongValue(VObject *o) +DLLEXPORT(unsigned long) vObjectLongValue(VObject *o) { return LONG_VALUE_OF(o); } -void setVObjectLongValue(VObject *o, unsigned long l) +DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l) { LONG_VALUE_OF(o) = l; VALUE_TYPE(o) = VCVT_ULONG; } -void* vObjectAnyValue(VObject *o) +DLLEXPORT(void*) vObjectAnyValue(VObject *o) { return ANY_VALUE_OF(o); } -void setVObjectAnyValue(VObject *o, void *t) +DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t) { ANY_VALUE_OF(o) = t; VALUE_TYPE(o) = VCVT_RAW; } -VObject* vObjectVObjectValue(VObject *o) +DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o) { return VOBJECT_VALUE_OF(o); } -void setVObjectVObjectValue(VObject *o, VObject *p) +DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p) { VOBJECT_VALUE_OF(o) = p; VALUE_TYPE(o) = VCVT_VOBJECT; } -int vObjectValueType(VObject *o) +DLLEXPORT(int) vObjectValueType(VObject *o) { return VALUE_TYPE(o); } /*---------------------------------------------------------------------- The following functions can be used to build VObject. ----------------------------------------------------------------------*/ -VObject* addVObjectProp(VObject *o, VObject *p) +DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p) { /* circular link list pointed to tail */ /* o {next,id,prop,val} V pn {next,id,prop,val} V ... p1 {next,id,prop,val} V pn --> o {next,id,prop,val} V pn {next,id,prop,val} V p {next,id,prop,val} ... p1 {next,id,prop,val} V pn */ VObject *tail = o->prop; if (tail) { p->next = tail->next; o->prop = tail->next = p; } else { o->prop = p->next = p; } return p; } -VObject* addProp(VObject *o, const char *id) +DLLEXPORT(VObject*) addProp(VObject *o, const char *id) { return addVObjectProp(o,newVObject(id)); } -VObject* addProp_(VObject *o, const char *id) +DLLEXPORT(VObject*) addProp_(VObject *o, const char *id) { return addVObjectProp(o,newVObject_(id)); } -void addList(VObject **o, VObject *p) +DLLEXPORT(void) addList(VObject **o, VObject *p) { p->next = 0; if (*o == 0) { *o = p; } else { VObject *t = *o; while (t->next) { t = t->next; } t->next = p; } } -VObject* nextVObjectInList(VObject *o) +DLLEXPORT(VObject*) nextVObjectInList(VObject *o) { return o->next; } -VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size) +DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size) { VObject *sizeProp; setVObjectAnyValue(prop, val); sizeProp = addProp(prop,VCDataSizeProp); setVObjectLongValue(sizeProp, size); return prop; } -VObject* setValueWithSize(VObject *prop, void *val, unsigned int size) +DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size) { - void *p = dupStr(val,size); + void *p = dupStr((const char *)val,size); return setValueWithSize_(prop,p,p?size:0); } -void initPropIterator(VObjectIterator *i, VObject *o) +DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o) { i->start = o->prop; i->next = 0; } -void initVObjectIterator(VObjectIterator *i, VObject *o) +DLLEXPORT(void) initVObjectIterator(VObjectIterator *i, VObject *o) { i->start = o->next; i->next = 0; } -int moreIteration(VObjectIterator *i) +DLLEXPORT(int) moreIteration(VObjectIterator *i) { return (i->start && (i->next==0 || i->next!=i->start)); } -VObject* nextVObject(VObjectIterator *i) +DLLEXPORT(VObject*) nextVObject(VObjectIterator *i) { if (i->start && i->next != i->start) { if (i->next == 0) { i->next = i->start->next; return i->next; } else { i->next = i->next->next; return i->next; } } else return (VObject*)0; } -VObject* isAPropertyOf(VObject *o, const char *id) +DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id) { VObjectIterator i; initPropIterator(&i,o); while (moreIteration(&i)) { VObject *each = nextVObject(&i); - if (!strcasecmp(id,each->id)) + if (!stricmp(id,each->id)) return each; } return (VObject*)0; } -VObject* addGroup(VObject *o, const char *g) +DLLEXPORT(VObject*) addGroup(VObject *o, const char *g) { /* a.b.c --> prop(c) prop(VCGrouping=b) prop(VCGrouping=a) */ char *dot = strrchr(g,'.'); if (dot) { VObject *p, *t; char *gs, *n = dot+1; gs = dupStr(g,0); /* so we can write to it. */ /* used to be * t = p = addProp_(o,lookupProp_(n)); */ t = p = addProp_(o,lookupProp(n)); dot = strrchr(gs,'.'); *dot = 0; do { dot = strrchr(gs,'.'); if (dot) { n = dot+1; *dot=0; } else n = gs; /* property(VCGroupingProp=n); * and the value may have VCGrouping property */ t = addProp(t,VCGroupingProp); setVObjectStringZValue(t,lookupProp_(n)); } while (n != gs); deleteStr(gs); return p; } else return addProp_(o,lookupProp(g)); } -VObject* addPropValue(VObject *o, const char *p, const char *v) +DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v) { VObject *prop; prop = addProp(o,p); setVObjectUStringZValue_(prop, fakeUnicode(v,0)); return prop; } -VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, +DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size) { VObject *prop; prop = addProp(o,p); setValueWithSize_(prop, (void*)v, size); return prop; } -VObject* addPropSizedValue(VObject *o, const char *p, const char *v, +DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size) { return addPropSizedValue_(o,p,dupStr(v,size),size); } /*---------------------------------------------------------------------- The following pretty print a VObject ----------------------------------------------------------------------*/ static void printVObject_(FILE *fp, VObject *o, int level); static void indent(FILE *fp, int level) { int i; for (i=0;i<level*4;i++) { fputc(' ', fp); } } static void printValue(FILE *fp, VObject *o, int level) { switch (VALUE_TYPE(o)) { case VCVT_USTRINGZ: { char c; char *t,*s; s = t = fakeCString(USTRINGZ_VALUE_OF(o)); fputc('"',fp); while (c=*t,c) { fputc(c,fp); if (c == '\n') indent(fp,level+2); t++; } fputc('"',fp); deleteStr(s); break; } case VCVT_STRINGZ: { char c; const char *s = STRINGZ_VALUE_OF(o); fputc('"',fp); while (c=*s,c) { fputc(c,fp); if (c == '\n') indent(fp,level+2); s++; } fputc('"',fp); break; } case VCVT_UINT: fprintf(fp,"%d", INTEGER_VALUE_OF(o)); break; case VCVT_ULONG: fprintf(fp,"%ld", LONG_VALUE_OF(o)); break; case VCVT_RAW: fprintf(fp,"[raw data]"); break; case VCVT_VOBJECT: fprintf(fp,"[vobject]\n"); printVObject_(fp,VOBJECT_VALUE_OF(o),level+1); break; case 0: fprintf(fp,"[none]"); break; default: fprintf(fp,"[unknown]"); break; } } static void printNameValue(FILE *fp,VObject *o, int level) { indent(fp,level); if (NAME_OF(o)) { fprintf(fp,"%s", NAME_OF(o)); } if (VALUE_TYPE(o)) { fputc('=',fp); printValue(fp,o, level); } fprintf(fp,"\n"); } static void printVObject_(FILE *fp, VObject *o, int level) { VObjectIterator t; if (o == 0) { fprintf(fp,"[NULL]\n"); return; } printNameValue(fp,o,level); initPropIterator(&t,o); while (moreIteration(&t)) { VObject *eachProp = nextVObject(&t); printVObject_(fp,eachProp,level+1); } } void printVObject(FILE *fp,VObject *o) { printVObject_(fp,o,0); } -void printVObjectToFile(char *fname,VObject *o) +DLLEXPORT(void) printVObjectToFile(char *fname,VObject *o) { FILE *fp = fopen(fname,"w"); if (fp) { printVObject(fp,o); fclose(fp); } } -void printVObjectsToFile(char *fname,VObject *list) +DLLEXPORT(void) printVObjectsToFile(char *fname,VObject *list) { FILE *fp = fopen(fname,"w"); if (fp) { while (list) { printVObject(fp,list); list = nextVObjectInList(list); } fclose(fp); } } -void cleanVObject(VObject *o) +DLLEXPORT(void) cleanVObject(VObject *o) { if (o == 0) return; if (o->prop) { /* destroy time: cannot use the iterator here. Have to break the cycle in the circular link list and turns it into regular NULL-terminated list -- since at some point of destruction, the reference entry for the iterator to work will not longer be valid. */ VObject *p; p = o->prop->next; o->prop->next = 0; do { VObject *t = p->next; cleanVObject(p); p = t; } while (p); } switch (VALUE_TYPE(o)) { case VCVT_USTRINGZ: case VCVT_STRINGZ: case VCVT_RAW: - /* assume they are all allocated by malloc. */ + /* assume they are all allocated by malloc. */ free((char*)STRINGZ_VALUE_OF(o)); break; case VCVT_VOBJECT: cleanVObject(VOBJECT_VALUE_OF(o)); break; } deleteVObject(o); } -void cleanVObjects(VObject *list) +DLLEXPORT(void) cleanVObjects(VObject *list) { while (list) { VObject *t = list; list = nextVObjectInList(list); cleanVObject(t); } } /*---------------------------------------------------------------------- The following is a String Table Facilities. ----------------------------------------------------------------------*/ #define STRTBLSIZE 255 static StrItem *strTbl[STRTBLSIZE]; static unsigned int hashStr(const char *s) { unsigned int h = 0; int i; for (i=0;s[i];i++) { h += s[i]*i; } return h % STRTBLSIZE; } -const char* lookupStr(const char *s) +DLLEXPORT(const char*) lookupStr(const char *s) { - char *newS; - - StrItem *t; - unsigned int h = hashStr(s); - if ((t = strTbl[h]) != 0) { - do { - if (strcasecmp(t->s,s) == 0) { - t->refCnt++; - return t->s; - } - t = t->next; - } while (t); - } - newS = dupStr(s,0); - strTbl[h] = newStrItem(newS,strTbl[h]); - return newS; + StrItem *t; + unsigned int h = hashStr(s); + if ((t = strTbl[h]) != 0) { + do { + if (stricmp(t->s,s) == 0) { + t->refCnt++; + return t->s; + } + t = t->next; + } while (t); + } + s = dupStr(s,0); + strTbl[h] = newStrItem(s,strTbl[h]); + return s; } -void unUseStr(const char *s) +DLLEXPORT(void) unUseStr(const char *s) { - StrItem *cur, *prev; - + StrItem *t, *p; unsigned int h = hashStr(s); - cur = strTbl[h]; - prev = cur; - while (cur != 0) { - if (strcasecmp(cur->s,s) == 0) { - cur->refCnt--; - /* if that was the last reference to this string, kill it. */ - if (cur->refCnt == 0) { - if (cur == strTbl[h]) { - strTbl[h] = cur->next; - deleteStr(prev->s); - deleteStrItem(prev); - } else { - prev->next = cur->next; - deleteStr(cur->s); - deleteStrItem(cur); - } - return; + if ((t = strTbl[h]) != 0) { + p = t; + do { + if (stricmp(t->s,s) == 0) { + t->refCnt--; + if (t->refCnt == 0) { + if (p == strTbl[h]) { + strTbl[h] = t->next; + } + else { + p->next = t->next; + } + deleteStr(t->s); + deleteStrItem(t); + return; + } + } + p = t; + t = t->next; + } while (t); } - } - prev = cur; - cur = cur->next; - } } -void cleanStrTbl() +DLLEXPORT(void) cleanStrTbl() { - int i; - for (i=0; i<STRTBLSIZE;i++) { - StrItem *t = strTbl[i]; - while (t) { - StrItem *p; - deleteStr(t->s); - p = t; - t = t->next; - deleteStrItem(p); - } - strTbl[i] = 0; - } + int i; + for (i=0; i<STRTBLSIZE;i++) { + StrItem *t = strTbl[i]; + while (t) { + StrItem *p; + deleteStr(t->s); + p = t; + t = t->next; + deleteStrItem(p); + } while (t); + strTbl[i] = 0; + } } struct PreDefProp { const char *name; const char *alias; const char** fields; unsigned int flags; }; /* flags in PreDefProp */ #define PD_BEGIN 0x1 #define PD_INTERNAL 0x2 static const char *adrFields[] = { VCPostalBoxProp, VCExtAddressProp, VCStreetAddressProp, VCCityProp, VCRegionProp, VCPostalCodeProp, VCCountryNameProp, 0 }; static const char *nameFields[] = { VCFamilyNameProp, VCGivenNameProp, VCAdditionalNamesProp, VCNamePrefixesProp, VCNameSuffixesProp, NULL }; static const char *orgFields[] = { VCOrgNameProp, VCOrgUnitProp, VCOrgUnit2Prop, VCOrgUnit3Prop, VCOrgUnit4Prop, NULL }; static const char *AAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCAudioContentProp, 0 }; /* ExDate -- has unamed fields */ /* RDate -- has unamed fields */ static const char *DAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCDisplayStringProp, 0 }; static const char *MAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCEmailAddressProp, VCNoteProp, 0 }; static const char *PAlarmFields[] = { VCRunTimeProp, VCSnoozeTimeProp, VCRepeatCountProp, VCProcedureNameProp, 0 }; static struct PreDefProp propNames[] = { { VC7bitProp, 0, 0, 0 }, { VC8bitProp, 0, 0, 0 }, { VCAAlarmProp, 0, AAlarmFields, 0 }, { VCAdditionalNamesProp, 0, 0, 0 }, { VCAdrProp, 0, adrFields, 0 }, { VCAgentProp, 0, 0, 0 }, { VCAIFFProp, 0, 0, 0 }, { VCAOLProp, 0, 0, 0 }, { VCAppleLinkProp, 0, 0, 0 }, { VCAttachProp, 0, 0, 0 }, { VCAttendeeProp, 0, 0, 0 }, { VCATTMailProp, 0, 0, 0 }, { VCAudioContentProp, 0, 0, 0 }, { VCAVIProp, 0, 0, 0 }, { VCBase64Prop, 0, 0, 0 }, { VCBBSProp, 0, 0, 0 }, { VCBirthDateProp, 0, 0, 0 }, { VCBMPProp, 0, 0, 0 }, { VCBodyProp, 0, 0, 0 }, { VCBusinessRoleProp, 0, 0, 0 }, { VCCalProp, 0, 0, PD_BEGIN }, { VCCaptionProp, 0, 0, 0 }, { VCCardProp, 0, 0, PD_BEGIN }, { VCCarProp, 0, 0, 0 }, { VCCategoriesProp, 0, 0, 0 }, { VCCellularProp, 0, 0, 0 }, { VCCGMProp, 0, 0, 0 }, { VCCharSetProp, 0, 0, 0 }, { VCCIDProp, VCContentIDProp, 0, 0 }, { VCCISProp, 0, 0, 0 }, { VCCityProp, 0, 0, 0 }, { VCClassProp, 0, 0, 0 }, { VCCommentProp, 0, 0, 0 }, { VCCompletedProp, 0, 0, 0 }, { VCContentIDProp, 0, 0, 0 }, { VCCountryNameProp, 0, 0, 0 }, { VCDAlarmProp, 0, DAlarmFields, 0 }, { VCDataSizeProp, 0, 0, PD_INTERNAL }, { VCDayLightProp, 0, 0, 0 }, { VCDCreatedProp, 0, 0, 0 }, { VCDeliveryLabelProp, 0, 0, 0 }, { VCDescriptionProp, 0, 0, 0 }, { VCDIBProp, 0, 0, 0 }, { VCDisplayStringProp, 0, 0, 0 }, { VCDomesticProp, 0, 0, 0 }, { VCDTendProp, 0, 0, 0 }, { VCDTstartProp, 0, 0, 0 }, { VCDueProp, 0, 0, 0 }, { VCEmailAddressProp, 0, 0, 0 }, { VCEncodingProp, 0, 0, 0 }, { VCEndProp, 0, 0, 0 }, { VCEventProp, 0, 0, PD_BEGIN }, { VCEWorldProp, 0, 0, 0 }, { VCExNumProp, 0, 0, 0 }, - { VCExDateProp, 0, 0, 0 }, + { VCExpDateProp, 0, 0, 0 }, { VCExpectProp, 0, 0, 0 }, { VCExtAddressProp, 0, 0, 0 }, { VCFamilyNameProp, 0, 0, 0 }, { VCFaxProp, 0, 0, 0 }, { VCFullNameProp, 0, 0, 0 }, { VCGeoLocationProp, 0, 0, 0 }, { VCGeoProp, 0, 0, 0 }, { VCGIFProp, 0, 0, 0 }, { VCGivenNameProp, 0, 0, 0 }, { VCGroupingProp, 0, 0, 0 }, { VCHomeProp, 0, 0, 0 }, { VCIBMMailProp, 0, 0, 0 }, { VCInlineProp, 0, 0, 0 }, { VCInternationalProp, 0, 0, 0 }, { VCInternetProp, 0, 0, 0 }, { VCISDNProp, 0, 0, 0 }, { VCJPEGProp, 0, 0, 0 }, { VCLanguageProp, 0, 0, 0 }, { VCLastModifiedProp, 0, 0, 0 }, { VCLastRevisedProp, 0, 0, 0 }, { VCLocationProp, 0, 0, 0 }, { VCLogoProp, 0, 0, 0 }, { VCMailerProp, 0, 0, 0 }, { VCMAlarmProp, 0, MAlarmFields, 0 }, { VCMCIMailProp, 0, 0, 0 }, { VCMessageProp, 0, 0, 0 }, { VCMETProp, 0, 0, 0 }, { VCModemProp, 0, 0, 0 }, { VCMPEG2Prop, 0, 0, 0 }, { VCMPEGProp, 0, 0, 0 }, { VCMSNProp, 0, 0, 0 }, { VCNamePrefixesProp, 0, 0, 0 }, { VCNameProp, 0, nameFields, 0 }, { VCNameSuffixesProp, 0, 0, 0 }, { VCNoteProp, 0, 0, 0 }, { VCOrgNameProp, 0, 0, 0 }, { VCOrgProp, 0, orgFields, 0 }, { VCOrgUnit2Prop, 0, 0, 0 }, { VCOrgUnit3Prop, 0, 0, 0 }, { VCOrgUnit4Prop, 0, 0, 0 }, { VCOrgUnitProp, 0, 0, 0 }, { VCPagerProp, 0, 0, 0 }, { VCPAlarmProp, 0, PAlarmFields, 0 }, { VCParcelProp, 0, 0, 0 }, { VCPartProp, 0, 0, 0 }, { VCPCMProp, 0, 0, 0 }, { VCPDFProp, 0, 0, 0 }, { VCPGPProp, 0, 0, 0 }, { VCPhotoProp, 0, 0, 0 }, { VCPICTProp, 0, 0, 0 }, { VCPMBProp, 0, 0, 0 }, { VCPostalBoxProp, 0, 0, 0 }, { VCPostalCodeProp, 0, 0, 0 }, { VCPostalProp, 0, 0, 0 }, { VCPowerShareProp, 0, 0, 0 }, { VCPreferredProp, 0, 0, 0 }, { VCPriorityProp, 0, 0, 0 }, { VCProcedureNameProp, 0, 0, 0 }, { VCProdIdProp, 0, 0, 0 }, { VCProdigyProp, 0, 0, 0 }, { VCPronunciationProp, 0, 0, 0 }, { VCPSProp, 0, 0, 0 }, { VCPublicKeyProp, 0, 0, 0 }, { VCQPProp, VCQuotedPrintableProp, 0, 0 }, { VCQuickTimeProp, 0, 0, 0 }, { VCQuotedPrintableProp, 0, 0, 0 }, { VCRDateProp, 0, 0, 0 }, { VCRegionProp, 0, 0, 0 }, { VCRelatedToProp, 0, 0, 0 }, { VCRepeatCountProp, 0, 0, 0 }, { VCResourcesProp, 0, 0, 0 }, { VCRNumProp, 0, 0, 0 }, { VCRoleProp, 0, 0, 0 }, { VCRRuleProp, 0, 0, 0 }, { VCRSVPProp, 0, 0, 0 }, { VCRunTimeProp, 0, 0, 0 }, { VCSequenceProp, 0, 0, 0 }, { VCSnoozeTimeProp, 0, 0, 0 }, { VCStartProp, 0, 0, 0 }, { VCStatusProp, 0, 0, 0 }, { VCStreetAddressProp, 0, 0, 0 }, { VCSubTypeProp, 0, 0, 0 }, { VCSummaryProp, 0, 0, 0 }, { VCTelephoneProp, 0, 0, 0 }, { VCTIFFProp, 0, 0, 0 }, { VCTimeZoneProp, 0, 0, 0 }, { VCTitleProp, 0, 0, 0 }, { VCTLXProp, 0, 0, 0 }, { VCTodoProp, 0, 0, PD_BEGIN }, { VCTranspProp, 0, 0, 0 }, { VCUniqueStringProp, 0, 0, 0 }, { VCURLProp, 0, 0, 0 }, { VCURLValueProp, 0, 0, 0 }, { VCValueProp, 0, 0, 0 }, { VCVersionProp, 0, 0, 0 }, { VCVideoProp, 0, 0, 0 }, { VCVoiceProp, 0, 0, 0 }, { VCWAVEProp, 0, 0, 0 }, { VCWMFProp, 0, 0, 0 }, { VCWorkProp, 0, 0, 0 }, { VCX400Prop, 0, 0, 0 }, { VCX509Prop, 0, 0, 0 }, { VCXRuleProp, 0, 0, 0 }, { 0,0,0,0 } }; static struct PreDefProp* lookupPropInfo(const char* str) { /* brute force for now, could use a hash table here. */ int i; for (i = 0; propNames[i].name; i++) - if (strcasecmp(str, propNames[i].name) == 0) { + if (stricmp(str, propNames[i].name) == 0) { return &propNames[i]; } return 0; } -const char* lookupProp_(const char* str) +DLLEXPORT(const char*) lookupProp_(const char* str) { int i; for (i = 0; propNames[i].name; i++) - if (strcasecmp(str, propNames[i].name) == 0) { + if (stricmp(str, propNames[i].name) == 0) { const char* s; s = propNames[i].alias?propNames[i].alias:propNames[i].name; return lookupStr(s); } return lookupStr(str); } -const char* lookupProp(const char* str) +DLLEXPORT(const char*) lookupProp(const char* str) { int i; for (i = 0; propNames[i].name; i++) - if (strcasecmp(str, propNames[i].name) == 0) { + if (stricmp(str, propNames[i].name) == 0) { const char *s; fieldedProp = propNames[i].fields; s = propNames[i].alias?propNames[i].alias:propNames[i].name; return lookupStr(s); } fieldedProp = 0; return lookupStr(str); } /*---------------------------------------------------------------------- APIs to Output text form. ----------------------------------------------------------------------*/ #define OFILE_REALLOC_SIZE 256 typedef struct OFile { FILE *fp; char *s; int len; int limit; int alloc:1; int fail:1; } OFile; - -/* vCalendar files need crlf linebreaks. The disabled functions didn't provide - that. */ #if 0 - static void appendsOFile(OFile *fp, const char *s) { int slen; if (fp->fail) return; slen = strlen(s); if (fp->fp) { fwrite(s,1,slen,fp->fp); } else { stuff: if (fp->len + slen < fp->limit) { memcpy(fp->s+fp->len,s,slen); fp->len += slen; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; if (OFILE_REALLOC_SIZE <= slen) fp->limit += slen; - if (fp->s) - fp->s = realloc(fp->s,fp->limit); - else - fp->s = malloc(fp->limit); + fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } static void appendcOFile(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; - fp->s = realloc(fp->s,fp->limit); + fp->s = (char *) realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } - #else - static void appendcOFile_(OFile *fp, char c) { if (fp->fail) return; if (fp->fp) { fputc(c,fp->fp); } else { stuff: if (fp->len+1 < fp->limit) { fp->s[fp->len] = c; fp->len++; return; } else if (fp->alloc) { fp->limit = fp->limit + OFILE_REALLOC_SIZE; fp->s = realloc(fp->s,fp->limit); if (fp->s) goto stuff; } if (fp->alloc) free(fp->s); fp->s = 0; fp->fail = 1; } } static void appendcOFile(OFile *fp, char c) { if (c == '\n') { /* write out as <CR><LF> */ appendcOFile_(fp,0xd); appendcOFile_(fp,0xa); } else appendcOFile_(fp,c); } static void appendsOFile(OFile *fp, const char *s) { int i, slen; slen = strlen(s); for (i=0; i<slen; i++) { appendcOFile(fp,s[i]); } } #endif static void initOFile(OFile *fp, FILE *ofp) { fp->fp = ofp; fp->s = 0; fp->len = 0; fp->limit = 0; fp->alloc = 0; fp->fail = 0; } static void initMemOFile(OFile *fp, char *s, int len) { fp->fp = 0; fp->s = s; fp->len = 0; fp->limit = s?len:0; fp->alloc = s?0:1; fp->fail = 0; } static int writeBase64(OFile *fp, unsigned char *s, long len) { long cur = 0; int i, numQuads = 0; unsigned long trip; unsigned char b; char quad[5]; #define MAXQUADS 16 quad[4] = 0; while (cur < len) { - /* collect the triplet of bytes into 'trip' */ + /* collect the triplet of bytes into 'trip' */ trip = 0; for (i = 0; i < 3; i++) { b = (cur < len) ? *(s + cur) : 0; cur++; trip = trip << 8 | b; } /* fill in 'quad' with the appropriate four characters */ for (i = 3; i >= 0; i--) { b = (unsigned char)(trip & 0x3F); trip = trip >> 6; if ((3 - i) < (cur - len)) - quad[i] = '='; /* pad char */ + quad[i] = '='; /* pad char */ else if (b < 26) quad[i] = (char)b + 'A'; else if (b < 52) quad[i] = (char)(b - 26) + 'a'; else if (b < 62) quad[i] = (char)(b - 52) + '0'; else if (b == 62) quad[i] = '+'; else quad[i] = '/'; } /* now output 'quad' with appropriate whitespace and line ending */ appendsOFile(fp, (numQuads == 0 ? " " : "")); appendsOFile(fp, quad); appendsOFile(fp, ((cur >= len)?"\n" :(numQuads==MAXQUADS-1?"\n" : ""))); numQuads = (numQuads + 1) % MAXQUADS; } appendcOFile(fp,'\n'); return 1; } -/* this function really sucks. Too basic. */ -static void writeQPString(OFile *fp, const char *s, int qp) +static void writeString(OFile *fp, const char *s) +{ + appendsOFile(fp,s); +} + +static void writeQPString(OFile *fp, const char *s) { + char buf[4]; + int count=0; const char *p = s; + while (*p) { - if (*p == '\n') { - if (p[1]) appendsOFile(fp,"=0A="); - } - if (*p == '=' && qp) - appendsOFile(fp,"=3D"); - else - appendcOFile(fp,*p); - p++; + /* break up lines biggger than 75 chars */ + if(count >=74){ + count=0; + appendsOFile(fp,"=\n"); + } + + /* escape any non ASCII characters and '=' as per rfc1521 */ + if (*p<= 0x1f || *p >=0x7f || *p == '=' ) { + sprintf(buf,"=%02X",(unsigned char)*p); + appendsOFile(fp,buf); + count+=3; + } else { + appendcOFile(fp,*p); + count++; + } + p++; } } + + static void writeVObject_(OFile *fp, VObject *o); -static void writeValue(OFile *fp, VObject *o, unsigned long size) +static void writeValue(OFile *fp, VObject *o, unsigned long size,int quote) { if (o == 0) return; switch (VALUE_TYPE(o)) { case VCVT_USTRINGZ: { char *s = fakeCString(USTRINGZ_VALUE_OF(o)); - if (isAPropertyOf(o, VCQuotedPrintableProp)) - writeQPString(fp, s, 1); - else - writeQPString(fp, s, 0); + if(quote) writeQPString(fp, s); + else writeString(fp,s); deleteStr(s); break; } case VCVT_STRINGZ: { - if (isAPropertyOf(o, VCQuotedPrintableProp)) - writeQPString(fp, STRINGZ_VALUE_OF(o), 1); - else - writeQPString(fp, STRINGZ_VALUE_OF(o), 0); + if(quote) writeQPString(fp, STRINGZ_VALUE_OF(o)); + else writeString(fp,STRINGZ_VALUE_OF(o)); break; } case VCVT_UINT: { char buf[16]; sprintf(buf,"%u", INTEGER_VALUE_OF(o)); appendsOFile(fp,buf); break; } case VCVT_ULONG: { char buf[16]; sprintf(buf,"%lu", LONG_VALUE_OF(o)); appendsOFile(fp,buf); break; } case VCVT_RAW: { appendcOFile(fp,'\n'); writeBase64(fp,(unsigned char*)(ANY_VALUE_OF(o)),size); break; } case VCVT_VOBJECT: appendcOFile(fp,'\n'); writeVObject_(fp,VOBJECT_VALUE_OF(o)); break; } } static void writeAttrValue(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_INTERNAL) != 0)) return; appendcOFile(fp,';'); appendsOFile(fp,NAME_OF(o)); } else appendcOFile(fp,';'); if (VALUE_TYPE(o)) { appendcOFile(fp,'='); - writeValue(fp,o,0); + writeValue(fp,o,0,0); } } static void writeGroup(OFile *fp, VObject *o) { char buf1[256]; char buf2[256]; strcpy(buf1,NAME_OF(o)); while ((o=isAPropertyOf(o,VCGroupingProp)) != 0) { - strncpy(buf2,STRINGZ_VALUE_OF(o),sizeof(buf2)); - buf2[sizeof(buf2)] = '\0'; - strncat(buf2,".",sizeof(buf2)-strlen(buf2)-1); - strncat(buf2,buf1,sizeof(buf2)-strlen(buf2)-1); + strcpy(buf2,STRINGZ_VALUE_OF(o)); + strcat(buf2,"."); + strcat(buf2,buf1); strcpy(buf1,buf2); } appendsOFile(fp,buf1); } static int inList(const char **list, const char *s) { if (list == 0) return 0; while (*list) { - if (strcasecmp(*list,s) == 0) return 1; + if (stricmp(*list,s) == 0) return 1; list++; } return 0; } static void writeProp(OFile *fp, VObject *o) { + int isQuoted=0; if (NAME_OF(o)) { struct PreDefProp *pi; VObjectIterator t; const char **fields_ = 0; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_BEGIN) != 0)) { writeVObject_(fp,o); return; } if (isAPropertyOf(o,VCGroupingProp)) writeGroup(fp,o); else appendsOFile(fp,NAME_OF(o)); if (pi) fields_ = pi->fields; initPropIterator(&t,o); while (moreIteration(&t)) { const char *s; VObject *eachProp = nextVObject(&t); s = NAME_OF(eachProp); - if (strcasecmp(VCGroupingProp,s) && !inList(fields_,s)) + if (stricmp(VCGroupingProp,s) && !inList(fields_,s)) writeAttrValue(fp,eachProp); + if (stricmp(VCQPProp,s)==0 || stricmp(VCQuotedPrintableProp,s)==0) + isQuoted=1; } if (fields_) { int i = 0, n = 0; const char** fields = fields_; /* output prop as fields */ appendcOFile(fp,':'); while (*fields) { - VObject *tl = isAPropertyOf(o,*fields); + VObject *t = isAPropertyOf(o,*fields); i++; - if (tl) n = i; + if (t) n = i; fields++; } fields = fields_; for (i=0;i<n;i++) { - writeValue(fp,isAPropertyOf(o,*fields),0); + writeValue(fp,isAPropertyOf(o,*fields),0,isQuoted); fields++; if (i<(n-1)) appendcOFile(fp,';'); } } } if (VALUE_TYPE(o)) { unsigned long size = 0; VObject *p = isAPropertyOf(o,VCDataSizeProp); if (p) size = LONG_VALUE_OF(p); appendcOFile(fp,':'); - writeValue(fp,o,size); + writeValue(fp,o,size,isQuoted); } appendcOFile(fp,'\n'); } static void writeVObject_(OFile *fp, VObject *o) { if (NAME_OF(o)) { struct PreDefProp *pi; pi = lookupPropInfo(NAME_OF(o)); if (pi && ((pi->flags & PD_BEGIN) != 0)) { VObjectIterator t; const char *begin = NAME_OF(o); appendsOFile(fp,"BEGIN:"); appendsOFile(fp,begin); appendcOFile(fp,'\n'); initPropIterator(&t,o); while (moreIteration(&t)) { VObject *eachProp = nextVObject(&t); writeProp(fp, eachProp); } appendsOFile(fp,"END:"); appendsOFile(fp,begin); appendsOFile(fp,"\n\n"); } } } void writeVObject(FILE *fp, VObject *o) { OFile ofp; initOFile(&ofp,fp); writeVObject_(&ofp,o); } -void writeVObjectToFile(char *fname, VObject *o) +DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o) { FILE *fp = fopen(fname,"w"); if (fp) { writeVObject(fp,o); fclose(fp); } } -void writeVObjectsToFile(char *fname, VObject *list) +DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list) { FILE *fp = fopen(fname,"w"); if (fp) { while (list) { writeVObject(fp,list); list = nextVObjectInList(list); } fclose(fp); } } -char* writeMemVObject(char *s, int *len, VObject *o) +DLLEXPORT(char*) writeMemVObject(char *s, int *len, VObject *o) { OFile ofp; initMemOFile(&ofp,s,len?*len:0); writeVObject_(&ofp,o); if (len) *len = ofp.len; appendcOFile(&ofp,0); return ofp.s; } -char* writeMemVObjects(char *s, int *len, VObject *list) +DLLEXPORT(char*) writeMemVObjects(char *s, int *len, VObject *list) { OFile ofp; initMemOFile(&ofp,s,len?*len:0); while (list) { writeVObject_(&ofp,list); list = nextVObjectInList(list); } if (len) *len = ofp.len; appendcOFile(&ofp,0); return ofp.s; } /*---------------------------------------------------------------------- APIs to do fake Unicode stuff. ----------------------------------------------------------------------*/ -wchar_t* fakeUnicode(const char *ps, int *bytes) +DLLEXPORT(wchar_t*) fakeUnicode(const char *ps, int *bytes) { wchar_t *r, *pw; int len = strlen(ps)+1; pw = r = (wchar_t*)malloc(sizeof(wchar_t)*len); if (bytes) *bytes = len * sizeof(wchar_t); while (*ps) { if (*ps == '\n') *pw = (wchar_t)0x2028; else if (*ps == '\r') *pw = (wchar_t)0x2029; else *pw = (wchar_t)(unsigned char)*ps; ps++; pw++; } *pw = (wchar_t)0; return r; } -int uStrLen(const wchar_t *u) +DLLEXPORT(int) uStrLen(const wchar_t *u) { int i = 0; while (*u != (wchar_t)0) { u++; i++; } return i; } -char* fakeCString(const wchar_t *u) +DLLEXPORT(char*) fakeCString(const wchar_t *u) { char *s, *t; int len = uStrLen(u) + 1; - t = s = (char*)malloc(len+1); + t = s = (char*)malloc(len); while (*u) { if (*u == (wchar_t)0x2028) *t = '\n'; else if (*u == (wchar_t)0x2029) *t = '\r'; else *t = (char)*u; u++; t++; } *t = 0; return s; } /* end of source file vobject.c */ diff --git a/libkcal/versit/vobject.h b/libkcal/versit/vobject.h index 0ec8b31..85c299e 100644 --- a/libkcal/versit/vobject.h +++ b/libkcal/versit/vobject.h @@ -1,384 +1,369 @@ /*************************************************************************** (C) Copyright 1996 Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. For purposes of this license notice, the term Licensors shall mean, collectively, Apple Computer, Inc., AT&T Corp., International Business Machines Corporation and Siemens Rolm Communications Inc. The term Licensor shall mean any of the Licensors. Subject to acceptance of the following conditions, permission is hereby granted by Licensors without the need for written agreement and without license or royalty fees, to use, copy, modify and distribute this software for any purpose. The above copyright notice and the following four paragraphs must be reproduced in all copies of this software and any software including this software. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS AND NO LICENSOR SHALL HAVE ANY OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS OR MODIFICATIONS. IN NO EVENT SHALL ANY LICENSOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOST PROFITS ARISING OUT OF THE USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. EACH LICENSOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY OF NONINFRINGEMENT OR THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. The software is provided with RESTRICTED RIGHTS. Use, duplication, or disclosure by the government are subject to restrictions set forth in DFARS 252.227-7013 or 48 CFR 52.227-19, as applicable. ***************************************************************************/ /* The vCard/vCalendar C interface is implemented in the set of files as follows: vcc.y, yacc source, and vcc.c, the yacc output you will use implements the core parser vobject.c implements an API that insulates the caller from the parser and changes in the vCard/vCalendar BNF port.h defines compilation environment dependent stuff vcc.h and vobject.h are header files for their .c counterparts vcaltmp.h and vcaltmp.c implement vCalendar "macro" functions which you may find useful. test.c is a standalone test driver that exercises some of the features of the APIs provided. Invoke test.exe on a VCARD/VCALENDAR input text file and you will see the pretty print output of the internal representation (this pretty print output should give you a good idea of how the internal representation looks like -- there is one such output in the following too). Also, a file with the .out suffix is generated to show that the internal representation can be written back in the original text format. For more information on this API see the readme.txt file which accompanied this distribution. Also visit: http://www.versit.com http://www.ralden.com */ #ifndef __VOBJECT_H__ #define __VOBJECT_H__ 1 #include "port.h" #include <stdlib.h> #include <stdio.h> #if defined(__CPLUSPLUS__) || defined(__cplusplus) extern "C" { #endif #define VC7bitProp "7BIT" #define VC8bitProp "8BIT" #define VCAAlarmProp "AALARM" #define VCAdditionalNamesProp "ADDN" #define VCAdrProp "ADR" #define VCAgentProp "AGENT" #define VCAIFFProp "AIFF" #define VCAOLProp "AOL" #define VCAppleLinkProp "APPLELINK" #define VCAttachProp "ATTACH" #define VCAttendeeProp "ATTENDEE" #define VCATTMailProp "ATTMAIL" #define VCAudioContentProp "AUDIOCONTENT" #define VCAVIProp "AVI" #define VCBase64Prop "BASE64" #define VCBBSProp "BBS" #define VCBirthDateProp "BDAY" #define VCBMPProp "BMP" #define VCBodyProp "BODY" #define VCBusinessRoleProp "ROLE" #define VCCalProp "VCALENDAR" #define VCCaptionProp "CAP" #define VCCardProp "VCARD" #define VCCarProp "CAR" #define VCCategoriesProp "CATEGORIES" #define VCCellularProp "CELL" #define VCCGMProp "CGM" #define VCCharSetProp "CS" #define VCCIDProp "CID" #define VCCISProp "CIS" #define VCCityProp "L" #define VCClassProp "CLASS" #define VCCommentProp "NOTE" #define VCCompletedProp "COMPLETED" #define VCContentIDProp "CONTENT-ID" #define VCCountryNameProp "C" #define VCDAlarmProp "DALARM" #define VCDataSizeProp "DATASIZE" #define VCDayLightProp "DAYLIGHT" #define VCDCreatedProp "DCREATED" #define VCDeliveryLabelProp "LABEL" #define VCDescriptionProp "DESCRIPTION" #define VCDIBProp "DIB" #define VCDisplayStringProp "DISPLAYSTRING" #define VCDomesticProp "DOM" #define VCDTendProp "DTEND" #define VCDTstartProp "DTSTART" #define VCDueProp "DUE" #define VCEmailAddressProp "EMAIL" #define VCEncodingProp "ENCODING" #define VCEndProp "END" #define VCEventProp "VEVENT" #define VCEWorldProp "EWORLD" #define VCExNumProp "EXNUM" -#define VCExDateProp "EXDATE" +#define VCExpDateProp "EXDATE" #define VCExpectProp "EXPECT" #define VCExtAddressProp "EXT ADD" #define VCFamilyNameProp "F" #define VCFaxProp "FAX" #define VCFullNameProp "FN" #define VCGeoProp "GEO" #define VCGeoLocationProp "GEO" #define VCGIFProp "GIF" #define VCGivenNameProp "G" #define VCGroupingProp "Grouping" #define VCHomeProp "HOME" #define VCIBMMailProp "IBMMail" #define VCInlineProp "INLINE" #define VCInternationalProp "INTL" #define VCInternetProp "INTERNET" #define VCISDNProp "ISDN" #define VCJPEGProp "JPEG" #define VCLanguageProp "LANG" #define VCLastModifiedProp "LAST-MODIFIED" #define VCLastRevisedProp "REV" #define VCLocationProp "LOCATION" #define VCLogoProp "LOGO" #define VCMailerProp "MAILER" #define VCMAlarmProp "MALARM" #define VCMCIMailProp "MCIMAIL" #define VCMessageProp "MSG" #define VCMETProp "MET" #define VCModemProp "MODEM" #define VCMPEG2Prop "MPEG2" #define VCMPEGProp "MPEG" #define VCMSNProp "MSN" #define VCNamePrefixesProp "NPRE" #define VCNameProp "N" #define VCNameSuffixesProp "NSUF" #define VCNoteProp "NOTE" #define VCOrgNameProp "ORGNAME" #define VCOrgProp "ORG" #define VCOrgUnit2Prop "OUN2" #define VCOrgUnit3Prop "OUN3" #define VCOrgUnit4Prop "OUN4" #define VCOrgUnitProp "OUN" #define VCPagerProp "PAGER" #define VCPAlarmProp "PALARM" #define VCParcelProp "PARCEL" #define VCPartProp "PART" #define VCPCMProp "PCM" #define VCPDFProp "PDF" #define VCPGPProp "PGP" #define VCPhotoProp "PHOTO" #define VCPICTProp "PICT" #define VCPMBProp "PMB" #define VCPostalBoxProp "BOX" #define VCPostalCodeProp "PC" #define VCPostalProp "POSTAL" #define VCPowerShareProp "POWERSHARE" #define VCPreferredProp "PREF" #define VCPriorityProp "PRIORITY" #define VCProcedureNameProp "PROCEDURENAME" #define VCProdIdProp "PRODID" #define VCProdigyProp "PRODIGY" #define VCPronunciationProp "SOUND" #define VCPSProp "PS" #define VCPublicKeyProp "KEY" #define VCQPProp "QP" #define VCQuickTimeProp "QTIME" #define VCQuotedPrintableProp "QUOTED-PRINTABLE" #define VCRDateProp "RDATE" #define VCRegionProp "R" #define VCRelatedToProp "RELATED-TO" #define VCRepeatCountProp "REPEATCOUNT" #define VCResourcesProp "RESOURCES" #define VCRNumProp "RNUM" #define VCRoleProp "ROLE" #define VCRRuleProp "RRULE" #define VCRSVPProp "RSVP" #define VCRunTimeProp "RUNTIME" #define VCSequenceProp "SEQUENCE" #define VCSnoozeTimeProp "SNOOZETIME" #define VCStartProp "START" #define VCStatusProp "STATUS" #define VCStreetAddressProp "STREET" #define VCSubTypeProp "SUBTYPE" #define VCSummaryProp "SUMMARY" #define VCTelephoneProp "TEL" #define VCTIFFProp "TIFF" #define VCTimeZoneProp "TZ" #define VCTitleProp "TITLE" #define VCTLXProp "TLX" #define VCTodoProp "VTODO" #define VCTranspProp "TRANSP" #define VCUniqueStringProp "UID" #define VCURLProp "URL" #define VCURLValueProp "URLVAL" #define VCValueProp "VALUE" #define VCVersionProp "VERSION" #define VCVideoProp "VIDEO" #define VCVoiceProp "VOICE" #define VCWAVEProp "WAVE" #define VCWMFProp "WMF" #define VCWorkProp "WORK" #define VCX400Prop "X400" #define VCX509Prop "X509" #define VCXRuleProp "XRULE" -/* extensions for KOrganizer / KPilot */ -#define KPilotIdProp "X-PILOTID" -#define KPilotStatusProp "X-PILOTSTAT" +/* Extensions */ +#define XPilotIdProp "X-PILOTID" +#define XPilotStatusProp "X-PILOTSTAT" /* extensions for iMIP / iTIP */ #define ICOrganizerProp "X-ORGANIZER" #define ICMethodProp "X-METHOD" #define ICRequestStatusProp "X-REQUEST-STATUS" - typedef struct VObject VObject; -typedef union ValueItem { - const char *strs; - const wchar_t *ustrs; - unsigned int i; - unsigned long l; - void *any; - VObject *vobj; - } ValueItem; - -struct VObject { - VObject *next; - const char *id; - VObject *prop; - unsigned short valType; - ValueItem val; - }; - -typedef struct StrItem StrItem; - -struct StrItem { - StrItem *next; - const char *s; - unsigned int refCnt; - }; - typedef struct VObjectIterator { VObject* start; VObject* next; } VObjectIterator; -extern VObject* newVObject(const char *id); -extern void deleteVObject(VObject *p); -extern char* dupStr(const char *s, unsigned int size); -extern void deleteStr(const char *p); -extern void unUseStr(const char *s); - -extern void setVObjectName(VObject *o, const char* id); -extern void setVObjectStringZValue(VObject *o, const char *s); -extern void setVObjectStringZValue_(VObject *o, const char *s); -extern void setVObjectUStringZValue(VObject *o, const wchar_t *s); -extern void setVObjectUStringZValue_(VObject *o, const wchar_t *s); -extern void setVObjectIntegerValue(VObject *o, unsigned int i); -extern void setVObjectLongValue(VObject *o, unsigned long l); -extern void setVObjectAnyValue(VObject *o, void *t); -extern VObject* setValueWithSize(VObject *prop, void *val, unsigned int size); -extern VObject* setValueWithSize_(VObject *prop, void *val, unsigned int size); - -extern const char* vObjectName(VObject *o); -extern const char* vObjectStringZValue(VObject *o); -extern const wchar_t* vObjectUStringZValue(VObject *o); -extern unsigned int vObjectIntegerValue(VObject *o); -extern unsigned long vObjectLongValue(VObject *o); -extern void* vObjectAnyValue(VObject *o); -extern VObject* vObjectVObjectValue(VObject *o); -extern void setVObjectVObjectValue(VObject *o, VObject *p); - -extern VObject* addVObjectProp(VObject *o, VObject *p); -extern VObject* addProp(VObject *o, const char *id); -extern VObject* addProp_(VObject *o, const char *id); -extern VObject* addPropValue(VObject *o, const char *p, const char *v); -extern VObject* addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); -extern VObject* addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); -extern VObject* addGroup(VObject *o, const char *g); -extern void addList(VObject **o, VObject *p); - -extern VObject* isAPropertyOf(VObject *o, const char *id); - -extern VObject* nextVObjectInList(VObject *o); -extern void initPropIterator(VObjectIterator *i, VObject *o); -extern int moreIteration(VObjectIterator *i); -extern VObject* nextVObject(VObjectIterator *i); - -extern char* writeMemVObject(char *s, int *len, VObject *o); -extern char* writeMemVObjects(char *s, int *len, VObject *list); - -extern const char* lookupStr(const char *s); -extern void cleanStrTbl(); - -extern void cleanVObject(VObject *o); -extern void cleanVObjects(VObject *list); - -extern const char* lookupProp(const char* str); -extern const char* lookupProp_(const char* str); - -extern wchar_t* fakeUnicode(const char *ps, int *bytes); -extern int uStrLen(const wchar_t *u); -extern char* fakeCString(const wchar_t *u); - -extern void printVObjectToFile(char *fname,VObject *o); -extern void printVObjectsToFile(char *fname,VObject *list); -extern void writeVObjectToFile(char *fname, VObject *o); -extern void writeVObjectsToFile(char *fname, VObject *list); - -extern int vObjectValueType(VObject *o); +extern DLLEXPORT(VObject*) newVObject(const char *id); +extern DLLEXPORT(void) deleteVObject(VObject *p); +extern DLLEXPORT(char*) dupStr(const char *s, unsigned int size); +extern DLLEXPORT(void) deleteStr(const char *p); +extern DLLEXPORT(void) unUseStr(const char *s); + +extern DLLEXPORT(void) setVObjectName(VObject *o, const char* id); +extern DLLEXPORT(void) setVObjectStringZValue(VObject *o, const char *s); +extern DLLEXPORT(void) setVObjectStringZValue_(VObject *o, const char *s); +extern DLLEXPORT(void) setVObjectUStringZValue(VObject *o, const wchar_t *s); +extern DLLEXPORT(void) setVObjectUStringZValue_(VObject *o, const wchar_t *s); +extern DLLEXPORT(void) setVObjectIntegerValue(VObject *o, unsigned int i); +extern DLLEXPORT(void) setVObjectLongValue(VObject *o, unsigned long l); +extern DLLEXPORT(void) setVObjectAnyValue(VObject *o, void *t); +extern DLLEXPORT(VObject*) setValueWithSize(VObject *prop, void *val, unsigned int size); +extern DLLEXPORT(VObject*) setValueWithSize_(VObject *prop, void *val, unsigned int size); + +extern DLLEXPORT(const char*) vObjectName(VObject *o); +extern DLLEXPORT(const char*) vObjectStringZValue(VObject *o); +extern DLLEXPORT(const wchar_t*) vObjectUStringZValue(VObject *o); +extern DLLEXPORT(unsigned int) vObjectIntegerValue(VObject *o); +extern DLLEXPORT(unsigned long) vObjectLongValue(VObject *o); +extern DLLEXPORT(void*) vObjectAnyValue(VObject *o); +extern DLLEXPORT(VObject*) vObjectVObjectValue(VObject *o); +extern DLLEXPORT(void) setVObjectVObjectValue(VObject *o, VObject *p); + +extern DLLEXPORT(VObject*) addVObjectProp(VObject *o, VObject *p); +extern DLLEXPORT(VObject*) addProp(VObject *o, const char *id); +extern DLLEXPORT(VObject*) addProp_(VObject *o, const char *id); +extern DLLEXPORT(VObject*) addPropValue(VObject *o, const char *p, const char *v); +extern DLLEXPORT(VObject*) addPropSizedValue_(VObject *o, const char *p, const char *v, unsigned int size); +extern DLLEXPORT(VObject*) addPropSizedValue(VObject *o, const char *p, const char *v, unsigned int size); +extern DLLEXPORT(VObject*) addGroup(VObject *o, const char *g); +extern DLLEXPORT(void) addList(VObject **o, VObject *p); + +extern DLLEXPORT(VObject*) isAPropertyOf(VObject *o, const char *id); + +extern DLLEXPORT(VObject*) nextVObjectInList(VObject *o); +extern DLLEXPORT(void) initPropIterator(VObjectIterator *i, VObject *o); +extern DLLEXPORT(int) moreIteration(VObjectIterator *i); +extern DLLEXPORT(VObject*) nextVObject(VObjectIterator *i); + +extern DLLEXPORT(char*) writeMemVObject(char *s, int *len, VObject *o); +extern DLLEXPORT(char*) writeMemVObjects(char *s, int *len, VObject *list); + +extern DLLEXPORT(const char*) lookupStr(const char *s); +extern DLLEXPORT(void) cleanStrTbl(); + +extern DLLEXPORT(void) cleanVObject(VObject *o); +extern DLLEXPORT(void) cleanVObjects(VObject *list); + +extern DLLEXPORT(const char*) lookupProp(const char* str); +extern DLLEXPORT(const char*) lookupProp_(const char* str); + +extern DLLEXPORT(wchar_t*) fakeUnicode(const char *ps, int *bytes); +extern DLLEXPORT(int) uStrLen(const wchar_t *u); +extern DLLEXPORT(char*) fakeCString(const wchar_t *u); + +extern DLLEXPORT(void) printVObjectToFile(char *fname,VObject *o); +extern DLLEXPORT(void) printVObjectsToFile(char *fname,VObject *list); +extern DLLEXPORT(void) writeVObjectToFile(char *fname, VObject *o); +extern DLLEXPORT(void) writeVObjectsToFile(char *fname, VObject *list); + +extern DLLEXPORT(int) vObjectValueType(VObject *o); /* return type of vObjectValueType: */ #define VCVT_NOVALUE 0 /* if the VObject has no value associated with it. */ #define VCVT_STRINGZ 1 /* if the VObject has value set by setVObjectStringZValue. */ #define VCVT_USTRINGZ 2 /* if the VObject has value set by setVObjectUStringZValue. */ #define VCVT_UINT 3 /* if the VObject has value set by setVObjectIntegerValue. */ #define VCVT_ULONG 4 /* if the VObject has value set by setVObjectLongValue. */ #define VCVT_RAW 5 /* if the VObject has value set by setVObjectAnyValue. */ #define VCVT_VOBJECT 6 /* if the VObject has value set by setVObjectVObjectValue. */ extern const char** fieldedProp; +/* NOTE regarding printVObject and writeVObject + +The functions below are not exported from the DLL because they +take a FILE* as a parameter, which cannot be passed across a DLL +interface (at least that is my experience). Instead you can use +their companion functions which take file names or pointers +to memory. However, if you are linking this code into +your build directly then you may find them a more convenient API +and you can go ahead and use them. If you try to use them with +the DLL LIB you will get a link error. +*/ extern void printVObject(FILE *fp,VObject *o); extern void writeVObject(FILE *fp, VObject *o); #if defined(__CPLUSPLUS__) || defined(__cplusplus) } #endif #endif /* __VOBJECT_H__ */ diff --git a/variables.pri b/variables.pri index 01fcea3..2b83fb5 100644 --- a/variables.pri +++ b/variables.pri @@ -1,5 +1,11 @@ # variables settings for compilation for Linux desktop and Qt 3.x.x +unix { CONFIG += debug #release +} +win32 { +CONFIG += release + +}
\ No newline at end of file @@ -1 +1 @@ -version = "1.9.1"; +version = "1.9.2"; |