Remove ancient trunk folder from svn repository
[synfig.git] / synfig-studio / src / synfigapp / cvs.cpp
diff --git a/synfig-studio/src/synfigapp/cvs.cpp b/synfig-studio/src/synfigapp/cvs.cpp
new file mode 100644 (file)
index 0000000..7173785
--- /dev/null
@@ -0,0 +1,381 @@
+/* === S Y N F I G ========================================================= */
+/*!    \file cvs.cpp
+**     \brief Template File
+**
+**     $Id$
+**
+**     \legal
+**     Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
+**
+**     This package 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 package 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.
+**     \endlegal
+*/
+/* ========================================================================= */
+
+/* === H E A D E R S ======================================================= */
+
+#ifdef USING_PCH
+#      include "pch.h"
+#else
+#ifdef HAVE_CONFIG_H
+#      include <config.h>
+#endif
+
+#include "cvs.h"
+#include <ETL/stringf>
+#include <fstream>
+#include <iostream>
+#include <synfig/general.h>
+#include <stdlib.h>
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+//#include <unistd.h>
+
+#include <cassert>
+
+#include "general.h"
+
+#endif
+
+/* === U S I N G =========================================================== */
+
+using namespace std;
+using namespace etl;
+using namespace synfig;
+using namespace synfigapp;
+
+/* === M A C R O S ========================================================= */
+
+#define cvs_command            synfig::String("cvs -z4")
+
+#ifndef WIN32
+#define HAVE_STRPTIME
+#endif
+
+#ifdef __APPLE__
+time_t _daylight_() { time_t t(time(0)); return localtime(&t)->tm_gmtoff; }
+#define daylight _daylight_()
+#endif
+
+/* === G L O B A L S ======================================================= */
+
+/* === P R O C E D U R E S ================================================= */
+
+/* === M E T H O D S ======================================================= */
+
+CVSInfo::CVSInfo(const synfig::String& file_name)
+{
+       update_available_=false;
+       set_file_name(file_name);
+}
+
+CVSInfo::CVSInfo()
+{
+       update_available_=false;
+}
+
+CVSInfo::~CVSInfo()
+{
+}
+
+void
+CVSInfo::set_file_name(const synfig::String& file_name)
+{
+       file_name_=file_name;
+
+       std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str());
+
+       if(file)
+       {
+               in_sandbox_=true;
+               calc_repository_info();
+       }
+       else
+               in_sandbox_=false;
+}
+
+void
+CVSInfo::calc_repository_info()
+{
+#ifdef _DEBUG
+       synfig::info("in_sandbox() = %d",in_sandbox());
+#endif
+
+       if(!in_sandbox_)
+               return;
+
+       std::ifstream file((dirname(file_name_)+"/CVS/Entries").c_str());
+
+       while(file)
+       {
+               String line;
+               getline(file,line);
+               if(line.find(basename(file_name_))!=String::npos)
+               {
+                       in_repository_=true;
+                       String::size_type s,f;
+
+                       // Grab the version
+                       s=line.find('/',1);
+                       assert(s!=String::npos);
+                       s++;
+                       f=line.find('/',s+1);
+                       assert(f!=String::npos);
+                       cvs_version_=String(line,s,f-s);
+
+                       // Grab the time
+#ifdef HAVE_STRPTIME
+                       s=f+1;
+                       f=line.find('/',s+1);
+                       assert(f!=String::npos);
+                       tm time_struct;
+                       strptime(String(line,s,f-s).c_str(),"%c",&time_struct);
+                       original_timestamp_=mktime(&time_struct);
+#endif
+
+                       if(
+                               system(strprintf(
+                                       "cd '%s' && cvs status '%s' | grep -q -e 'Needs Patch'",
+                                       dirname(file_name_).c_str(),
+                                       basename(file_name_).c_str()
+                               ).c_str())==0
+                       )
+                       {
+                               synfig::info("UPDATE_AVAILABLE=TRUE");
+                               update_available_=true;
+                       }
+                       else
+                       {
+                               system(strprintf(
+                                       "cd '%s' && cvs status '%s'",
+                                       dirname(file_name_).c_str(),
+                                       basename(file_name_).c_str()
+                               ).c_str());
+                               synfig::info("UPDATE_AVAILABLE=FALSE");
+                               update_available_=false;
+                       }
+
+
+#ifdef _DEBUG
+                       synfig::info("in_repository() = %d",in_repository());
+                       synfig::info("get_cvs_version() = %s",get_cvs_version().c_str());
+                       synfig::info("get_original_timestamp() = %s",ctime(&get_original_timestamp()));
+                       time_t t(get_current_timestamp());
+                       synfig::info("get_current_timestamp() = %s",ctime(&t));
+                       synfig::info("get_cvs_root() = %s",get_cvs_root().c_str());
+                       synfig::info("get_cvs_module() = %s",get_cvs_module().c_str());
+#endif
+                       return;
+               }
+       }
+
+       in_repository_=false;
+       cvs_version_.clear();
+       original_timestamp_=0;
+
+#ifdef _DEBUG
+       synfig::info("in_repository() = %d",in_repository());
+#endif
+}
+
+bool
+CVSInfo::in_sandbox()const
+{
+       return in_sandbox_;
+}
+
+bool
+CVSInfo::in_repository()const
+{
+       if(!in_sandbox_)
+               return false;
+       return in_repository_;
+}
+
+bool
+CVSInfo::is_modified()const
+{
+       if(!in_sandbox() || !in_repository())
+               return false;
+#ifdef _DEBUG
+       synfig::info("%d-%d=%d",get_current_timestamp(),get_original_timestamp(),get_current_timestamp()-get_original_timestamp());
+#endif
+       return get_current_timestamp()!=get_original_timestamp() && abs(get_current_timestamp()-get_original_timestamp())!=3600;
+}
+
+bool
+CVSInfo::is_updated()const
+{
+       return update_available_;
+}
+
+const synfig::String&
+CVSInfo::get_cvs_version()const
+{
+       return cvs_version_;
+}
+
+const time_t&
+CVSInfo::get_original_timestamp()const
+{
+       return original_timestamp_;
+}
+
+time_t
+CVSInfo::get_current_timestamp()const
+{
+       struct stat st;
+       if(stat(file_name_.c_str(),&st)<0)
+       {
+               synfig::error("Unable to get file stats");
+               return false;
+       }
+       time_t ret((daylight-1)*3600);
+       //ret+=timezone;
+       ret+=st.st_mtime;
+       return ret;
+}
+
+synfig::String
+CVSInfo::get_cvs_root()const
+{
+       if(!in_sandbox_)
+               return synfig::String();
+
+       std::ifstream file((dirname(file_name_)+"/CVS/Root").c_str());
+
+       if(file)
+       {
+               String ret;
+               getline(file,ret);
+               return ret;
+       }
+
+       return synfig::String();
+}
+
+synfig::String
+CVSInfo::get_cvs_module()const
+{
+       if(!in_sandbox_)
+               return synfig::String();
+
+       std::ifstream file((dirname(file_name_)+"/CVS/Repository").c_str());
+
+       if(file)
+       {
+               String ret;
+               getline(file,ret);
+               return ret;
+       }
+
+       return synfig::String();
+}
+
+// This function pre-processes the message so that we
+// don't get any CVS syntax errors.
+inline synfig::String fix_msg(const synfig::String& message)
+{
+       synfig::String ret;
+       int i;
+       for(i=0;i<(int)message.size();i++)
+       {
+               if(message[i]=='\'')
+                       ret+="'\"'\"'";
+               else
+                       ret+=message[i];
+       }
+       return ret;
+}
+
+void
+CVSInfo::cvs_add(const synfig::String& message)
+{
+       if(!in_sandbox_)
+       {
+               synfig::error("cvs_add(): Not in a sand box");
+               throw int();
+               return;
+       }
+
+       synfig::String command(strprintf("cd '%s' && %s add -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str()));
+
+       int ret(system(command.c_str()));
+
+       calc_repository_info();
+
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               throw(ret);
+               break;
+       }
+}
+
+void
+CVSInfo::cvs_update()
+{
+       if(!in_sandbox_)
+       {
+               synfig::error("cvs_update(): Not in a sand box");
+               throw int();
+               return;
+       }
+
+       synfig::String command(strprintf("cd '%s' && %s update '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),basename(file_name_).c_str()));
+
+       int ret(system(command.c_str()));
+
+       calc_repository_info();
+
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               throw(ret);
+               break;
+       }
+}
+
+void
+CVSInfo::cvs_commit(const synfig::String& message)
+{
+       if(!in_sandbox_)
+       {
+               synfig::error("cvs_commit(): Not in a sand box");
+               throw int();
+               return;
+       }
+
+       synfig::String command(strprintf("cd '%s' && %s commit -m '%s' '%s'",dirname(file_name_).c_str(),cvs_command.c_str(),fix_msg(message).c_str(),basename(file_name_).c_str()));
+
+       int ret(system(command.c_str()));
+
+       calc_repository_info();
+
+       switch(ret)
+       {
+       case 0:
+               break;
+       default:
+               synfig::error("Unknown errorcode %d (\"%s\")",ret,command.c_str());
+               if(is_modified())
+                       throw(ret);
+               break;
+       }
+}