On Tue, Oct 09, 2001 at 10:50:56AM +0400, Alexander V. Lukyanov wrote:
> Time difference is not quite the same as time. Another class? Is it worth
> the trouble? Time difference in milliseconds is enough for lftp, I think.

Er?  Time stores either a time or an amount of time, just like time_t
and timeval do.  A difference of two times is an amount of time; the sum
of a time and an amount of time is a time, etc.  (They're the same
thing, in Unix terms.)

I don't see where the problem is, this is a pretty standard operation (and a
fairly textbook class.) It's the same as BSD timeradd/timersub, just with C++
syntax.

-- 
Glenn Maynard
Index: Makefile.am
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/Makefile.am,v
retrieving revision 1.42
diff -u -r1.42 Makefile.am
--- Makefile.am 2001/10/05 06:26:52     1.42
+++ Makefile.am 2001/10/09 07:39:04
@@ -53,7 +53,7 @@
  NetAccess.cc NetAccess.h FtpSplitList.h FtpSplitList.cc Speedometer.cc\
  Speedometer.h lftp_ssl.cc lftp_ssl.h netrc.cc netrc.h buffer_ssl.cc\
  buffer_ssl.h Fish.cc Fish.h ColumnOutput.cc ColumnOutput.h FileSetOutput.cc \
- FileSetOutput.h
+ FileSetOutput.h Time.cc Time.h
 
 libjobs_a_SOURCES = Job.cc Job.h CmdExec.cc CmdExec.h\
  commands.cc mgetJob.h mgetJob.cc SysCmdJob.cc SysCmdJob.h rmJob.cc rmJob.h\
Index: StatusLine.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/StatusLine.cc,v
retrieving revision 1.11
diff -u -r1.11 StatusLine.cc
--- StatusLine.cc       2001/10/03 08:13:38     1.11
+++ StatusLine.cc       2001/10/09 07:39:05
@@ -40,6 +40,8 @@
 #include "misc.h"
 #include "StatusLine.h"
 
+ResDecl status_interval ("cmd:status-interval",        "1000",   
+ResMgr::UNumberValidate,0);
+       
 int  StatusLine::GetWidth()
 {
 #ifdef TIOCGWINSZ
@@ -60,7 +62,6 @@
 {
    fd=new_fd;
    update_delayed=false;
-   update_time=0;
    strcpy(shown,"");
    strcpy(def_title,"");
    not_term=!isatty(fd);
@@ -78,7 +79,7 @@
    newstr[0]=0;
    update(newstr);
    update_delayed=false;
-   update_time=0;
+   timer.force();
 
    WriteTitle(def_title, fd);
 }
@@ -104,17 +105,19 @@
    vsnprintf(newstr,sizeof(newstr),f,v);
    va_end(v);
 
-   if(now>update_time)
+   if(!strcmp(to_be_shown,newstr)) return;
+
+   int res = timer.go(status_interval.Query(0));
+   if(!res)
    {
       update(newstr);
       update_delayed=false;
-      update_time=now;
    }
-   else if(strcmp(to_be_shown,newstr))
+   else
    {
       strcpy(to_be_shown,newstr);
       update_delayed=true;
-      TimeoutS(1);
+      Timeout(res);
    }
 }
 
@@ -182,7 +185,6 @@
    write(fd,newstr,strlen(newstr));
 }
 
-
 void StatusLine::WriteLine(const char *f,...)
 {
    char *newstr=(char*)alloca(sizeof(shown)+strlen(f)+64);
@@ -230,13 +232,13 @@
 {
    if(!update_delayed)
       return STALL;
-   if(now>update_time)
+   int res = timer.go(status_interval.Query(0));
+   if(!res)
    {
       update(to_be_shown);
       update_delayed=false;
-      update_time=now;
       return STALL;
    }
-   TimeoutS(1);
+   Timeout(res);
    return STALL;
 }
Index: StatusLine.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/StatusLine.h,v
retrieving revision 1.6
diff -u -r1.6 StatusLine.h
--- StatusLine.h        2001/03/13 08:41:42     1.6
+++ StatusLine.h        2001/10/09 07:39:05
@@ -29,14 +29,16 @@
 # define PRINTF_LIKE(n,m)
 #endif
 
+#include <time.h>
 #include "SMTask.h"
+#include "Time.h"
 
 class StatusLine : public SMTask
 {
    int fd;
    char shown[0x800];
    bool        not_term;
-   time_t update_time;
+   Timer timer;
    char to_be_shown[0x800];
    char def_title[0x800];
    bool update_delayed;
Index: commands.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/commands.cc,v
retrieving revision 1.141
diff -u -r1.141 commands.cc
--- commands.cc 2001/10/08 07:14:50     1.141
+++ commands.cc 2001/10/09 07:39:06
@@ -147,9 +147,8 @@
    {"close",   cmd_close,   "close [-a]",
         N_("Close idle connections. By default only with current server.\n"
         " -a  close idle connections with all servers\n")},
-   {"cls",     cmd_cls,     0,
-        N_("cls [opts] [path/][wildcards]..."
-           "List remote files. You can redirect output of this command to file\n"
+   {"cls",     cmd_cls,     N_("[re]cls [opts] [path/][pattern]"),
+        N_("List remote files. You can redirect output of this command to file\n"
            "or via pipe to external command.\n"
            "\n"
            /* note: I've tried to keep options which are likely to be always
@@ -319,7 +318,7 @@
         N_("Removes specified files with wildcard expansion\n")},
    {"mv",      cmd_mv,     N_("mv <file1> <file2>"),
         N_("Rename <file1> to <file2>\n")},
-   {"nlist",   cmd_ls,     N_("nlist [<args>]"),
+   {"nlist",   cmd_ls,     N_("[re]nlist [<args>]"),
         N_("List remote file names\n")},
    {"open",    cmd_open,   N_("open [OPTS] <site>"),
         N_("Select a server, URL or bookmark\n"
@@ -344,10 +343,9 @@
    {"pwd",     cmd_pwd,    "pwd [-p]",
         N_("Print current remote URL.\n"
         " -p  show password\n")},
-   {"queue",   cmd_queue,  0,
-        N_(
-        "Usage:\n"
-        "       queue [-n num] <command>\n\n"
+   {"queue",   cmd_queue,  N_("queue <cmd>"),
+        N_("\n"
+        "       queue [-n num] <command>\n"
         "Add the command to queue for current site. Each site has its own command\n"
         "queue. `-n' adds the command before the given item in the queue. It is\n"
         "possible to queue up a running job by using command `queue wait <jobno>'.\n"
@@ -366,20 +364,24 @@
         "unknown remote state and thus will cause reconnect. You cannot\n"
         "be sure that any change of remote state because of quoted command\n"
         "is solid - it can be reset by reconnect at any time.\n")},
-   {"recls",    cmd_cls,   N_("recls [<args>]"),
-        N_("Same as `cls', but don't look in cache\n")},
-   {"reget",   cmd_get,    N_("reget [OPTS] <rfile> [-o <lfile>]"),
-        N_("Same as `get -c'\n")},
-   {"rels",    cmd_ls,     N_("rels [<args>]"),
-        N_("Same as `ls', but don't look in cache\n")},
-   {"renlist", cmd_ls,     N_("renlist [<args>]"),
-        N_("Same as `nlist', but don't look in cache\n")},
-   {"repeat",  cmd_repeat, 0,
-        N_("Usage: repeat [delay] [command]\n"
-        "Repeat specified command with a delay between iterations.\n"
+   {"recls",    cmd_cls,   0,
+        N_("recls [<args>]"
+        "Same as `cls', but don't look in cache\n")},
+   {"reget",   cmd_get,    0,
+        N_("Usage: reget [OPTS] <rfile> [-o <lfile>]"
+        "Same as `get -c'\n")},
+   {"rels",    cmd_ls,     0,
+        N_("Usage: rels [<args>]"
+           "Same as `ls', but don't look in cache\n")},
+   {"renlist", cmd_ls,     0,
+        N_("Usage: renlist [<args>]"
+        "Same as `nlist', but don't look in cache\n")},
+   {"repeat",  cmd_repeat, N_("repeat [delay] [command]"),
+        N_("Repeat specified command with a delay between iterations.\n"
         "Default delay is one second, default command is empty.\n")},
-   {"reput",   cmd_get,    N_("reput <lfile> [-o <rfile>]"),
-        N_("Same as `put -c'\n")},
+   {"reput",   cmd_get,    0,
+        N_("Usage: reput <lfile> [-o <rfile>]"
+        "Same as `put -c'\n")},
    {"rm",      cmd_rm,     N_("rm [-r] [-f] <files>"),
         N_("Remove remote files\n"
            " -r  recursive directory removal, be careful\n"
Index: complete.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/complete.cc,v
retrieving revision 1.43
diff -u -r1.43 complete.cc
--- complete.cc 2001/10/08 05:50:55     1.43
+++ complete.cc 2001/10/09 07:39:07
@@ -638,8 +638,6 @@
 
       rl_save_prompt();
       
-      int now_s = SMTask::now, now_ms = SMTask::now_ms;
-
       ArgV arg("", ResMgr::Query("cmd:cls-completion-default", 0));
       fso.parse_argv(&arg);
 
@@ -654,6 +652,9 @@
            rl_variable_bind("completion-ignore-case", "0");
         if(type==REMOTE_DIR)
            rg->glob->DirectoriesOnly();
+        Timer timer;
+        int interval = ResMgr::Query("cmd:status-interval", 0);
+
         for(;;)
         {
            SMTask::Schedule();
@@ -666,19 +667,13 @@
               delete rg;
               return 0;
            }
-
-           /* this time should match StatusLine's */
-           if((SMTask::now - now_s)*1000 + (SMTask::now_ms - now_ms) > 1000) {
-              now_s = SMTask::now;
-              now_ms = SMTask::now_ms;
 
-              if(!fso.quiet) {
-                 /* don't set blank status; if we're operating from cache,
-                  * that's all we'll get and it'll look ugly: */
-                 const char *ret = rg->Status();
-                 if(*ret)
-                    rl_message ("%s ", ret);
-              }
+           if(!fso.quiet && !timer.go(interval)) {
+              /* don't set blank status; if we're operating from cache,
+               * that's all we'll get and it'll look ugly: */
+              const char *ret = rg->Status();
+              if(*ret)
+                 rl_message ("%s ", ret);
            }
 
            SMTask::Block();
Index: misc.cc
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/misc.cc,v
retrieving revision 1.28
diff -u -r1.28 misc.cc
--- misc.cc     2001/10/05 06:26:53     1.28
+++ misc.cc     2001/10/09 07:39:07
@@ -37,9 +37,11 @@
 #include <termios.h>
 #endif
 
-#ifdef TM_IN_SYS_TIME
-# include <sys/time.h>
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
 #endif
+
 #include <regex.h>
 #include "misc.h"
 #include "ProcWait.h"
@@ -598,5 +600,18 @@
    if(!argv) return;
    xfree(argv[0]);
    xfree(argv);
+}
+
+void xgettimeofday(time_t *sec, int *usec)
+{
+#ifdef HAVE_GETTIMEOFDAY
+   struct timeval tv;
+   gettimeofday(&tv,0);
+   if(sec) *sec = tv.tv_sec;
+   if(usec) *usec = tv.tv_usec;
+#else
+   if(sec) time(sec);
+   if(usec) *usec = 0;
+#endif
 }
 
Index: misc.h
===================================================================
RCS file: /home/lav/cvsroot/lftp/src/misc.h,v
retrieving revision 1.20
diff -u -r1.20 misc.h
--- misc.h      2001/10/05 06:43:31     1.20
+++ misc.h      2001/10/09 07:39:07
@@ -25,7 +25,10 @@
 
 #include <stdio.h>
 #include <sys/types.h>
-#include <time.h>
+#include <sys/time.h>
+#ifdef TIME_WITH_SYS_TIME
+# include <time.h>
+#endif
 
 // expands tilde; returns pointer to static data
 const char *expand_home_relative(const char *);
@@ -93,5 +96,8 @@
 
 char **tokenize(const char *str, int *argc = NULL);
 void tokenize_free(char **argv);
+
+/* uses gettimeofday if available */
+void xgettimeofday(time_t *sec, int *usec);
 
 #endif // MISC_H
#include "misc.h"
#include "Time.h"

void Time::set_now()
{
   xgettimeofday(&tsec, &tms);
   tms /= 1000; /* us -> ms */
}

Time Time::operator - (Time rhs) const
{
   Time ret(*this);
   ret -= rhs;
   return ret;
}

Time &Time::operator -= (Time rhs)
{
   tsec -= rhs.tsec;
   tms -= rhs.tms;
   if (tms < 0) {
	 --tsec;
	 tms += 1000;
   }

   return *this;
}

Time Time::operator + (int ms) const
{
   Time ret(*this);
   ret += ms;
   return ret;
}

Time &Time::operator += (int ms)
{
   tms += ms;
   tsec += tms / 1000;
   tms %= 1000;

   return *this;
}

bool Time::operator < (Time cmp) const
{
   if(tsec == cmp.tsec) return tms < cmp.tms;
   else return tsec < cmp.tsec;
}

/* don't want to add a dependancy to SMTask */
void Timer::reset()
{
   last.set_now();
}

void Timer::force()
{
   last.clear();
}
   
Timer::Timer()
{
   force();
}

int Timer::go(int ms)
{
   Time now;
   now.set_now();

   Time next = last + ms;

   if(now < next) {
      Time left = next - now;
      return left.ms();
   }

   reset();
   
   return 0;
}

#ifndef TIME_CLASSES_H
#define TIME_CLASSES_H

class Time {
	time_t tsec;
	int tms;

public:
	Time() { clear(); }

	/* set the time to now */
	void set_now();

	/* clear to the beginning of time */
	void clear() { tsec = tms = 0; }

	int sec() const { return tsec; }
	/* int usec() const { return ms; } */
	int ms() const { return (tsec * 1000) + tms; }

	/* all integer operations are in milliseconds */
	/* these are mostly operators which are in use; add others as needed */
	Time operator + (int ms) const;
	Time &operator += (int ms);

	Time operator - (Time rhs) const;
	Time &operator -= (Time rhs);
		
	bool operator < (Time cmp) const;
	bool operator >= (Time cmp) const { return !(*this < cmp); }
};

class Timer {
	Time last;

public:
	Timer();

	/* return 0 if ms have elapsed since last 0 return or instantiation;
	 * otherwise return the number of ms left */
	int go(int ms);

	/* reset timer */
	void reset();

	/* force timer to go on next call */
	void force();
};

#endif

Reply via email to