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