Skip to content

Commit c02753a

Browse files
committed
FEAT: implemented QUERY/MODE for FILE, DIR, INPUT (console) and HTTP ports
1 parent 25255d1 commit c02753a

File tree

11 files changed

+200
-49
lines changed

11 files changed

+200
-49
lines changed

src/boot/sysobj.r

+4-2
Original file line numberDiff line numberDiff line change
@@ -255,8 +255,10 @@ standard: context [
255255
]
256256

257257
console-info: context [
258-
buffer-size: none
259-
window-size: none
258+
buffer-cols: none
259+
buffer-rows: none
260+
window-cols: none
261+
window-rows: none
260262
]
261263

262264
extension: context [

src/boot/words.r

+4
Original file line numberDiff line numberDiff line change
@@ -216,3 +216,7 @@ unixtime-now
216216
unixtime-now-le
217217
random-bytes
218218
length?
219+
buffer-cols
220+
buffer-rows
221+
window-cols
222+
window-rows

src/core/c-frame.c

+18
Original file line numberDiff line numberDiff line change
@@ -1162,6 +1162,24 @@
11621162
return NOT_FOUND;
11631163
}
11641164

1165+
/***********************************************************************
1166+
**
1167+
*/ REBSER* Get_Object_Words(REBVAL *object)
1168+
/*
1169+
** Returns block of object's words converted to simple word (not set-word)
1170+
** Note: used in query/mode function to return default modes
1171+
**
1172+
***********************************************************************/
1173+
{
1174+
REBSER *prior = VAL_OBJ_WORDS(object);
1175+
REBSER *words = Copy_Block_Len(prior, 1, SERIES_TAIL(prior) - 1);
1176+
// convert set-words to just words:
1177+
REBVAL *word = BLK_HEAD(words);
1178+
for (; NOT_END(word); word++)
1179+
if (IS_SET_WORD(word)) SET_TYPE(word, REB_WORD);
1180+
return words;
1181+
}
1182+
11651183

11661184
/***********************************************************************
11671185
**

src/core/p-console.c

+60-6
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@
4949
REBINT result;
5050
REBVAL *arg = D_ARG(2);
5151
REBSER *ser;
52+
REBCNT args = 0;
53+
REBVAL *spec;
5254

5355
Validate_Port(port, action);
5456

@@ -129,13 +131,16 @@
129131
return R_FALSE;
130132

131133
case A_QUERY:
132-
if (OS_DO_DEVICE(req, RDC_QUERY) < 0) return R_NONE;
133-
REBVAL *spec = Get_System(SYS_STANDARD, STD_CONSOLE_INFO);
134+
spec = Get_System(SYS_STANDARD, STD_CONSOLE_INFO);
134135
if (!IS_OBJECT(spec)) Trap_Arg(spec);
135-
REBSER *obj = CLONE_OBJECT(VAL_OBJ_FRAME(spec));
136-
SET_OBJECT(D_RET, obj);
137-
SET_PAIR(OFV(obj, STD_CONSOLE_INFO_BUFFER_SIZE), req->console.buffer_cols, req->console.buffer_rows);
138-
SET_PAIR(OFV(obj, STD_CONSOLE_INFO_WINDOW_SIZE), req->console.window_cols, req->console.window_rows);
136+
args = Find_Refines(ds, ALL_QUERY_REFS);
137+
if ((args & AM_QUERY_MODE) && IS_NONE(D_ARG(ARG_QUERY_FIELD))) {
138+
Set_Block(D_RET, Get_Object_Words(spec));
139+
return R_RET;
140+
}
141+
if (OS_DO_DEVICE(req, RDC_QUERY) < 0) return R_NONE;
142+
143+
Ret_Query_Console(req, D_RET, D_ARG(ARG_QUERY_FIELD), spec);
139144
break;
140145

141146
default:
@@ -145,6 +150,55 @@
145150
return R_RET;
146151
}
147152

153+
/***********************************************************************
154+
**
155+
*/ static REBOOL Set_Console_Mode_Value(REBREQ *req, REBCNT mode, REBVAL *ret)
156+
/*
157+
** Set a value with file data according specified mode
158+
**
159+
***********************************************************************/
160+
{
161+
switch (mode) {
162+
case SYM_BUFFER_COLS:
163+
SET_INTEGER(ret, req->console.buffer_cols);
164+
break;
165+
case SYM_BUFFER_ROWS:
166+
SET_INTEGER(ret, req->console.buffer_rows);
167+
break;
168+
case SYM_WINDOW_COLS:
169+
SET_INTEGER(ret, req->console.window_cols);
170+
break;
171+
case SYM_WINDOW_ROWS:
172+
SET_INTEGER(ret, req->console.window_rows);
173+
break;
174+
default:
175+
return FALSE;
176+
}
177+
return TRUE;
178+
}
179+
180+
/***********************************************************************
181+
**
182+
*/ void Ret_Query_Console(REBREQ *req, REBVAL *ret, REBVAL *info, REBVAL *spec)
183+
/*
184+
** Query file and set RET value to resulting STD_FILE_INFO object.
185+
**
186+
***********************************************************************/
187+
{
188+
if (IS_WORD(info)) {
189+
if (!Set_Console_Mode_Value(req, VAL_WORD_CANON(info), ret))
190+
Trap1(RE_INVALID_ARG, info);
191+
}
192+
else {
193+
REBSER *obj = CLONE_OBJECT(VAL_OBJ_FRAME(spec));
194+
SET_INTEGER(OFV(obj, STD_CONSOLE_INFO_BUFFER_COLS), req->console.buffer_cols);
195+
SET_INTEGER(OFV(obj, STD_CONSOLE_INFO_BUFFER_ROWS), req->console.buffer_rows);
196+
SET_INTEGER(OFV(obj, STD_CONSOLE_INFO_WINDOW_COLS), req->console.window_cols);
197+
SET_INTEGER(OFV(obj, STD_CONSOLE_INFO_WINDOW_ROWS), req->console.window_rows);
198+
SET_OBJECT(ret, obj);
199+
}
200+
}
201+
148202

149203
/***********************************************************************
150204
**

src/core/p-dir.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,15 @@
331331

332332
case A_QUERY:
333333
//Trap_Security(flags[POL_READ], POL_READ, path);
334+
args = Find_Refines(ds, ALL_QUERY_REFS);
335+
if ((args & AM_QUERY_MODE) && IS_NONE(D_ARG(ARG_QUERY_FIELD))) {
336+
Ret_File_Modes(port, D_RET);
337+
return R_RET;
338+
}
334339
SET_NONE(state);
335340
Init_Dir_Path(&dir, path, -1, REMOVE_TAIL_SLASH | POL_READ);
336341
if (OS_DO_DEVICE(&dir, RDC_QUERY) < 0) return R_NONE;
337-
Ret_Query_File(port, &dir, D_RET);
342+
Ret_Query_File(port, &dir, D_RET, D_ARG(ARG_QUERY_FIELD));
338343
///OS_FREE(dir.file.path);
339344
break;
340345

src/core/p-file.c

+56-18
Original file line numberDiff line numberDiff line change
@@ -96,33 +96,68 @@
9696
Set_Date(val, &dat);
9797
}
9898

99+
/***********************************************************************
100+
**
101+
*/ static REBOOL Set_File_Mode_Value(REBREQ *file, REBCNT mode, REBVAL *ret)
102+
/*
103+
** Set a value with file data according specified mode
104+
**
105+
***********************************************************************/
106+
{
107+
switch (mode) {
108+
case SYM_SIZE:
109+
SET_INTEGER(ret, file->file.size);
110+
break;
111+
case SYM_TYPE:
112+
Init_Word(ret, GET_FLAG(file->modes, RFM_DIR) ? SYM_DIR : SYM_FILE);
113+
break;
114+
case SYM_DATE:
115+
Set_File_Date(file, ret);
116+
break;
117+
case SYM_NAME:
118+
Set_Series(REB_FILE, ret, To_REBOL_Path(file->file.path, 0, OS_WIDE, 0));
119+
break;
120+
default:
121+
return FALSE;
122+
}
123+
return TRUE;
124+
}
99125

100126
/***********************************************************************
101127
**
102-
*/ void Ret_Query_File(REBSER *port, REBREQ *file, REBVAL *ret)
128+
*/ void Ret_Query_File(REBSER *port, REBREQ *file, REBVAL *ret, REBVAL *info)
103129
/*
104130
** Query file and set RET value to resulting STD_FILE_INFO object.
105131
**
106132
***********************************************************************/
107133
{
108-
REBVAL *info = In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0);
109134
REBSER *obj;
110-
REBSER *ser;
111135

112-
if (!info || !IS_OBJECT(info)) Trap_Port(RE_INVALID_SPEC, port, -10);
113-
114-
obj = CLONE_OBJECT(VAL_OBJ_FRAME(info));
115-
116-
SET_OBJECT(ret, obj);
117-
Init_Word(OFV(obj, STD_FILE_INFO_TYPE), GET_FLAG(file->modes, RFM_DIR) ? SYM_DIR : SYM_FILE);
118-
SET_INTEGER(OFV(obj, STD_FILE_INFO_SIZE), file->file.size);
119-
Set_File_Date(file, OFV(obj, STD_FILE_INFO_DATE));
120-
121-
ser = To_REBOL_Path(file->file.path, 0, OS_WIDE, 0);
122-
123-
Set_Series(REB_FILE, OFV(obj, STD_FILE_INFO_NAME), ser);
136+
if ( IS_WORD(info) ) {
137+
if(!Set_File_Mode_Value(file, VAL_WORD_CANON(info), ret))
138+
Trap1(RE_INVALID_ARG, info);
139+
} else {
140+
info = In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0);
141+
if (!info || !IS_OBJECT(info)) Trap_Port(RE_INVALID_SPEC, port, -10);
142+
obj = CLONE_OBJECT(VAL_OBJ_FRAME(info));
143+
Set_File_Mode_Value(file, SYM_TYPE, OFV(obj, STD_FILE_INFO_TYPE));
144+
Set_File_Mode_Value(file, SYM_SIZE, OFV(obj, STD_FILE_INFO_SIZE));
145+
Set_File_Mode_Value(file, SYM_DATE, OFV(obj, STD_FILE_INFO_DATE));
146+
Set_File_Mode_Value(file, SYM_NAME, OFV(obj, STD_FILE_INFO_NAME));
147+
SET_OBJECT(ret, obj);
148+
}
124149
}
125150

151+
/***********************************************************************
152+
**
153+
*/ void Ret_File_Modes(REBSER *port, REBVAL *ret)
154+
/*
155+
** Sets value with block of possible file mode names
156+
**
157+
***********************************************************************/
158+
{
159+
Set_Block(ret, Get_Object_Words(In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0)));
160+
}
126161

127162
/***********************************************************************
128163
**
@@ -461,11 +496,16 @@ REBINT Mode_Syms[] = {
461496
break;
462497

463498
case A_QUERY:
499+
args = Find_Refines(ds, ALL_QUERY_REFS);
500+
if ((args & AM_QUERY_MODE) && IS_NONE(D_ARG(ARG_QUERY_FIELD))) {
501+
Ret_File_Modes(port, D_RET);
502+
return R_RET;
503+
}
464504
if (!IS_OPEN(file)) {
465505
Setup_File(file, 0, path);
466506
if (OS_DO_DEVICE(file, RDC_QUERY) < 0) return R_NONE;
467507
}
468-
Ret_Query_File(port, file, D_RET);
508+
Ret_Query_File(port, file, D_RET, D_ARG(ARG_QUERY_FIELD));
469509
// !!! free file path?
470510
break;
471511

@@ -476,7 +516,6 @@ REBINT Mode_Syms[] = {
476516
if (OS_DO_DEVICE(file, RDC_MODIFY) < 0) return R_NONE;
477517
}
478518
return R_TRUE;
479-
break;
480519

481520
case A_INDEXQ:
482521
SET_INTEGER(D_RET, file->file.index + 1);
@@ -535,7 +574,6 @@ REBINT Mode_Syms[] = {
535574
A_REMOVE, // 52
536575
A_CHANGE, // 53
537576
A_POKE, // 54
538-
A_QUERY, // 64
539577
A_FLUSH, // 65
540578
*/
541579

src/mezz/base-files.r

+3-9
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,21 @@ exists?: func [
2020
{Determines if a file or URL exists.}
2121
target [file! url!]
2222
][
23-
to logic! query target
23+
not none? query/mode target 'type
2424
]
2525

2626
size?: func [
2727
{Returns the size of a file.}
2828
target [file! url!]
2929
][
30-
all [
31-
target: attempt [query target]
32-
target/size
33-
]
30+
query/mode target 'size
3431
]
3532

3633
modified?: func [
3734
{Returns the last modified date of a file.}
3835
target [file! url!]
3936
][
40-
all [
41-
target: attempt [query target]
42-
target/date
43-
]
37+
query/mode target 'date
4438
]
4539

4640
suffix?: func [

src/mezz/mezz-help.r

+4-5
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,10 @@ import module [
178178
'word [any-type!]
179179
/into "Help text will be inserted into provided string instead of printed"
180180
string [string!] "Returned series will be past the insertion"
181-
/local value spec args refs rets type ret desc arg def des tmp
181+
/local value spec args refs rets type ret desc arg def des ref
182182
][
183183
try [
184-
tmp: query system/ports/input
185-
max-desc-width: tmp/window-size/x - 36
184+
max-desc-width: (query/mode system/ports/input 'buffer-cols) - 36
186185
]
187186
buffer: any [string make string! 1024]
188187
catch [
@@ -278,8 +277,8 @@ import module [
278277
output "^/^/^[[4;1;36mREFINEMENTS^[[m:"
279278
parse back refs [
280279
any [
281-
set tmp refinement! (output ajoin ["^/ ^[[1;32m" pad mold tmp 14 "^[[m"])
282-
opt [set tmp string! (output tmp)]
280+
set ref refinement! (output ajoin ["^/ ^[[1;32m" pad mold ref 14 "^[[m"])
281+
opt [set des string! (output des)]
283282
any [
284283
set arg [word! | lit-word! | get-word!]
285284
set def opt block!

src/mezz/prot-http.r

+8-5
Original file line numberDiff line numberDiff line change
@@ -646,11 +646,12 @@ sys/make-scheme [
646646
]
647647
query: func [
648648
port [port!]
649+
/mode
650+
field [word! none!]
649651
/local error state
650652
] [
651-
either port/state [
652-
state: port/state
653-
][
653+
if all [mode none? field] [ return words-of system/standard/file-info]
654+
if none? state: port/state [
654655
open port ;there is port opening in sync-op, but it would also close the port later and so clear the state
655656
attempt [sync-op port [parse-write-dialect port [HEAD]]]
656657
state: port/state
@@ -659,9 +660,11 @@ sys/make-scheme [
659660
;?? state
660661
either all [
661662
state
662-
find [ok redirect] state/info/response-parsed
663+
state/info/response-parsed
663664
][
664-
state/info
665+
either field [
666+
select state/info field
667+
][ state/info ]
665668
][ none ]
666669
]
667670
length?: func [

0 commit comments

Comments
 (0)