Commits (4)
......@@ -1399,7 +1399,7 @@ void sbbs_t::progress(const char* text, int count, int total, int interval)
if(cfg.node_num == 0)
return; // Don't output this for events
double now = xp_timer();
if(count < total && (now - last_progress) * 1000 < interval)
if(count > 0 && count < total && (now - last_progress) * 1000 < interval)
return;
if(text == NULL) text = "";
float pct = total ? ((float)count/total)*100.0F : 100.0F;
......
......@@ -308,24 +308,32 @@ int sbbs_t::exec_file(csi_t *csi)
&& strcmp(csi->str, ALLFILES) != 0) {
bputs(text[SearchingAllDirs]);
for(i=0;i<usrdirs[curlib];i++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
progress(text[Scanning], i, usrdirs[curlib]);
if(i!=curdir[curlib] &&
(s=listfileinfo(usrdir[curlib][i],csi->str,FI_DOWNLOAD))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
bputs(text[Scanned]);
bputs(text[SearchingAllLibs]);
for(i=0;i<usrlibs;i++) {
progress(text[Scanning], i, usrlibs);
if(i==curlib) continue;
for(j=0;j<usrdirs[i];j++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
if((s=listfileinfo(usrdir[i][j],csi->str,FI_DOWNLOAD))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
}
}
bputs(text[Scanned]);
}
return(0);
case CS_FILE_DOWNLOAD_USER: /* Download from user dir */
......@@ -385,24 +393,32 @@ int sbbs_t::exec_file(csi_t *csi)
return(0);
bputs(text[SearchingAllDirs]);
for(i=0;i<usrdirs[curlib];i++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
progress(text[Scanning], i, usrdirs[curlib]);
if(i==curdir[curlib]) continue;
if(listfiles(usrdir[curlib][i],csi->str,0,FL_VIEW))
break;
}
bputs(text[Scanned]);
if(i<usrdirs[curlib])
return(0);
bputs(text[SearchingAllLibs]);
for(i=0;i<usrlibs;i++) {
progress(text[Scanning], i, usrlibs);
if(i==curlib) continue;
for(j=0;j<usrdirs[i];j++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
if(listfiles(usrdir[i][j],csi->str,0,FL_VIEW))
return(0);
}
}
bputs(text[Scanned]);
csi->logic=LOGIC_FALSE;
bputs(text[FileNotFound]);
return(0);
......@@ -425,24 +441,32 @@ int sbbs_t::exec_file(csi_t *csi)
&& strcmp(csi->str, ALLFILES) != 0) {
bputs(text[SearchingAllDirs]);
for(i=0;i<usrdirs[curlib];i++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
progress(text[Scanning], i, usrdirs[curlib]);
if(i!=curdir[curlib] && (s=listfileinfo(usrdir[curlib][i]
,csi->str,FI_INFO))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
bputs(text[Scanned]);
bputs(text[SearchingAllLibs]);
for(i=0;i<usrlibs;i++) {
progress(text[Scanning], i, usrlibs);
if(i==curlib) continue;
for(j=0;j<usrdirs[i];j++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
if((s=listfileinfo(usrdir[i][j],csi->str,FI_INFO))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
}
}
bputs(text[Scanned]);
}
return(0);
case CS_FILE_FIND_TEXT: /* Find text in descriptions */
......@@ -487,24 +511,32 @@ int sbbs_t::exec_file(csi_t *csi)
return(0);
bputs(text[SearchingAllDirs]);
for(i=0;i<usrdirs[curlib];i++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
progress(text[Scanning], i, usrdirs[curlib]);
if(i!=curdir[curlib] && i!=cfg.user_dir
&& (s=listfileinfo(usrdir[curlib][i],csi->str,FI_REMOVE))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
bputs(text[Scanned]);
bputs(text[SearchingAllLibs]);
for(i=0;i<usrlibs;i++) {
progress(text[Scanning], i, usrlibs);
if(i==curlib || i==cfg.user_dir) continue;
for(j=0;j<usrdirs[i]; j++) {
if(msgabort())
if(msgabort()) {
bputs(text[Aborted]);
return 0;
}
if((s=listfileinfo(usrdir[i][j],csi->str,FI_REMOVE))!=0)
if(s==-1 || (!strchr(csi->str,'?') && !strchr(csi->str,'*')))
return(0);
}
}
}
bputs(text[Scanned]);
}
return(0);
}
......
......@@ -2258,6 +2258,54 @@ js_clearOn(JSContext *cx, uintN argc, jsval *arglist)
return js_clear_console_event(cx, argc, arglist, TRUE);
}
static JSBool
js_progress(JSContext *cx, uintN argc, jsval *arglist)
{
jsval *argv=JS_ARGV(cx, arglist);
sbbs_t* sbbs;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((sbbs=(sbbs_t*)js_GetClassPrivate(cx, JS_THIS_OBJECT(cx, arglist), &js_console_class))==NULL)
return JS_FALSE;
if(argc < 3) {
JS_ReportError(cx, "Invalid number of arguments to function");
return JS_FALSE;
}
JSString* js_str = JS_ValueToString(cx, argv[0]);
if(js_str == NULL)
return JS_FALSE;
bool hungry = true;
int32 count = 0;
int32 total = 1;
int32 interval = 500;
uintN argn = 1;
if(argc > argn) {
if(!JS_ValueToInt32(cx,argv[argn], &count))
return JS_FALSE;
argn++;
}
if(argc > argn) {
if(!JS_ValueToInt32(cx,argv[argn], &total))
return JS_FALSE;
argn++;
}
if(argc > argn) {
if(!JS_ValueToInt32(cx,argv[argn], &interval))
return JS_FALSE;
argn++;
}
char* p = NULL;
JSSTRING_TO_MSTRING(cx, js_str, p, NULL);
if(p == NULL)
return JS_FALSE;
sbbs->progress(p, count, total, interval);
free(p);
return JS_TRUE;
}
static jsSyncMethodSpec js_console_functions[] = {
{"inkey", js_inkey, 0, JSTYPE_STRING, JSDOCSTR("[mode=<tt>K_NONE</tt>] [,timeout=<tt>0</tt>]")
,JSDOCSTR("get a single key with optional <i>timeout</i> in milliseconds (defaults to 0, for no wait).<br>"
......@@ -2366,6 +2414,10 @@ static jsSyncMethodSpec js_console_functions[] = {
,JSDOCSTR("display a string double-wide on the screen (sending \"fullwidth\" Unicode characters when possible)")
,31702
},
{"progress", js_progress, 1, JSTYPE_VOID, JSDOCSTR("text, count, total [,interval = 500]")
,JSDOCSTR("display a progress indication bar, updated every <i>interval</i> milliseconds")
,31902
},
{"strlen", js_strlen, 1, JSTYPE_NUMBER, JSDOCSTR("text [,mode=<tt>P_NONE</tt>]")
,JSDOCSTR("returns the printed-length (number of columns) of the specified <i>text</i>, accounting for Ctrl-A codes")
,310
......
......@@ -1307,6 +1307,26 @@ js_get_time_left(JSContext *cx, uintN argc, jsval *arglist)
return JS_TRUE;
}
static JSBool
js_user_close(JSContext *cx, uintN argc, jsval *arglist)
{
JSObject *obj=JS_THIS_OBJECT(cx, arglist);
private_t* p;
jsrefcount rc;
JS_SET_RVAL(cx, arglist, JSVAL_VOID);
if((p=(private_t*)js_GetClassPrivate(cx, obj, &js_user_class))==NULL)
return JS_FALSE;
rc=JS_SUSPENDREQUEST(cx);
if(p->file > 0)
closeuserdat(p->file);
p->file = -1;
JS_RESUMEREQUEST(cx, rc);
return JS_TRUE;
}
static jsSyncMethodSpec js_user_functions[] = {
{"compare_ars", js_chk_ar, 1, JSTYPE_BOOLEAN, JSDOCSTR("string ars")
......@@ -1346,6 +1366,10 @@ static jsSyncMethodSpec js_user_functions[] = {
"Note: for the pre-defined user object on the BBS, you almost certainly want bbs.get_time_left() instead.")
,31401
},
{"close", js_user_close, 0, JSTYPE_VOID, JSDOCSTR("")
,JSDOCSTR("Close the <tt>user.dat</tt> file, if open. The file will be auto-reopened if necessary.")
,31902
},
{0}
};
......