*/ static REBSER *String_List_To_Block(REBCHR *str) /* ** Convert a series of null terminated strings to ** a block of strings separated with '='. ** ***********************************************************************/ { REBCNT n; REBCNT len = 0; REBCHR *start = str; REBCHR *eq; REBSER *blk; while (n = LEN_STR(str)) { len++; str += n + 1; // next } blk = Make_Block(len*2); SAVE_SERIES(blk); str = start; while (NZ(eq = FIND_CHR(str+1, '=')) && NZ(n = LEN_STR(str))) { Set_Series(REB_STRING, Append_Value(blk), Copy_OS_Str(str, eq-str)); Set_Series(REB_STRING, Append_Value(blk), Copy_OS_Str(eq+1, n-(eq-str)-1)); str += n + 1; // next } Block_As_Map(blk); UNSAVE_SERIES(blk); return blk; }
*/ REBINT PD_File(REBPVS *pvs) /* ***********************************************************************/ { REBSER *ser; REB_MOLD mo = {0}; REBCNT n; REBUNI c; REBSER *arg; if (pvs->setval) return PE_BAD_SET; ser = Copy_Series_Value(pvs->value); n = SERIES_TAIL(ser); if (n > 0) c = GET_ANY_CHAR(ser, n-1); if (n == 0 || c != '/') Append_Byte(ser, '/'); if (ANY_STR(pvs->select)) arg = VAL_SERIES(pvs->select); else { Reset_Mold(&mo); Mold_Value(&mo, pvs->select, 0); arg = mo.series; } c = GET_ANY_CHAR(arg, 0); n = (c == '/' || c == '\\') ? 1 : 0; Append_String(ser, arg, n, arg->tail-n); Set_Series(VAL_TYPE(pvs->value), pvs->store, ser); return PE_USE; }
*/ static void Read_File_Port(REBVAL *out, REBSER *port, REBREQ *file, REBVAL *path, REBCNT args, REBCNT len) /* ** Read from a file port. ** ***********************************************************************/ { REBSER *ser; // Allocate read result buffer: ser = Make_Binary(len); Set_Series(REB_BINARY, out, ser); //??? what if already set? // Do the read, check for errors: file->common.data = BIN_HEAD(ser); file->length = len; if (OS_DO_DEVICE(file, RDC_READ) < 0) Trap_Port(RE_READ_ERROR, port, file->error); SERIES_TAIL(ser) = file->actual; STR_TERM(ser); // Convert to string or block of strings. // NOTE: This code is incorrect for files read in chunks!!! if (args & (AM_READ_STRING | AM_READ_LINES)) { REBSER *nser = Decode_UTF_String(BIN_HEAD(ser), file->actual, -1); if (nser == NULL) { Trap(RE_BAD_DECODE); } Set_String(out, nser); if (args & AM_READ_LINES) Set_Block(out, Split_Lines(out)); } }
*/ void Ret_Query_File(REBSER *port, REBREQ *file, REBVAL *ret) /* ** Query file and set RET value to resulting STD_FILE_INFO object. ** ***********************************************************************/ { REBVAL *info = In_Object(port, STD_PORT_SCHEME, STD_SCHEME_INFO, 0); REBSER *obj; REBSER *ser; if (!info || !IS_OBJECT(info)) Trap_Port(RE_INVALID_SPEC, port, -10); obj = CLONE_OBJECT(VAL_OBJ_FRAME(info)); SET_OBJECT(ret, obj); Init_Word_Unbound( OFV(obj, STD_FILE_INFO_TYPE), REB_WORD, GET_FLAG(file->modes, RFM_DIR) ? SYM_DIR : SYM_FILE ); SET_INTEGER(OFV(obj, STD_FILE_INFO_SIZE), file->special.file.size); Set_File_Date(file, OFV(obj, STD_FILE_INFO_DATE)); ser = To_REBOL_Path(file->special.file.path, 0, OS_WIDE, 0); Set_Series(REB_FILE, OFV(obj, STD_FILE_INFO_NAME), ser); }
void Print_Parse_Index(REBCNT type, REBVAL *rules, REBSER *series, REBCNT index) { REBVAL val; Set_Series(type, &val, series); VAL_INDEX(&val) = index; Debug_Fmt("%r: %r", rules, &val); }
*/ static REBVAL *Do_Parse_Path(REBVAL *item, REBPARSE *parse, REBCNT *index) /* ** Handle a PATH, including get and set, that's found in a rule. ** ***********************************************************************/ { REBVAL *path = item; REBVAL tmp; if (IS_PATH(item)) { if (Do_Path(&path, 0)) return item; // found a function item = DS_TOP; } else if (IS_SET_PATH(item)) { Set_Series(parse->type, &tmp, parse->series); VAL_INDEX(&tmp) = *index; if (Do_Path(&path, &tmp)) return item; // found a function return 0; } else if (IS_GET_PATH(item)) { if (Do_Path(&path, 0)) return item; // found a function item = DS_TOP; // CureCode #1263 change // if (parse->type != VAL_TYPE(item) || VAL_SERIES(item) != parse->series) if (!ANY_SERIES(item)) Trap1(RE_PARSE_SERIES, path); *index = Set_Parse_Series(parse, item); return 0; } return item; }
*/ static REBSER *File_List_To_Block(REBCHR *str) /* ** Convert file directory and file name list to block. ** ***********************************************************************/ { REBCNT n; REBCNT len = 0; REBCHR *start = str; REBSER *blk; REBSER *dir; while (n = LEN_STR(str)) { len++; str += n + 1; // next } blk = Make_Block(len); SAVE_SERIES(blk); // First is a dir path or full file path: str = start; n = LEN_STR(str); if (len == 1) { // First is full file path dir = To_REBOL_Path(str, n, -1, 0); Set_Series(REB_FILE, Append_Value(blk), dir); } else { // First is dir path for the rest of the files dir = To_REBOL_Path(str, n, -1, TRUE); str += n + 1; // next len = dir->tail; while (n = LEN_STR(str)) { dir->tail = len; Append_Uni_Uni(dir, str, n); Set_Series(REB_FILE, Append_Value(blk), Copy_String(dir, 0, -1)); str += n + 1; // next } } UNSAVE_SERIES(blk); return blk; }
*/ static void Return_Gob_Pair(REBVAL *ds, REBGOB *gob, REBD32 x, REBD32 y) /* ***********************************************************************/ { REBSER *blk; REBVAL *val; blk = Make_Block(2); Set_Series(REB_BLOCK, ds, blk); val = Append_Value(blk); SET_GOB(val, gob); val = Append_Value(blk); VAL_SET(val, REB_PAIR); VAL_PAIR_X(val) = x; VAL_PAIR_Y(val) = y; }
*/ void Throw_Return_Series(REBCNT type, REBSER *series) /* ** Throws a series value using error temp values. ** ***********************************************************************/ { REBVAL *val; REBVAL *err; REBSER *blk = VAL_SERIES(TASK_ERR_TEMPS); RESET_SERIES(blk); val = Append_Value(blk); Set_Series(type, val, series); err = Append_Value(blk); SET_THROW(err, RE_RETURN, val); VAL_ERR_SYM(err) = SYM_RETURN; // indicates it is "virtual" (parse return) Throw_Break(err); }
*/ static int Read_Dir(REBREQ *dir, REBSER *files) /* ** Provide option to get file info too. ** Provide option to prepend dir path. ** Provide option to use wildcards. ** ***********************************************************************/ { REBINT result; REBCNT len; REBSER *fname; REBSER *name; REBREQ file; RESET_TAIL(files); CLEARS(&file); // Temporary filename storage: fname = BUF_OS_STR; file.file.path = (REBCHR*)Reset_Buffer(fname, MAX_FILE_NAME); SET_FLAG(dir->modes, RFM_DIR); dir->data = (REBYTE*)(&file); while ((result = OS_DO_DEVICE(dir, RDC_READ)) == 0 && !GET_FLAG(dir->flags, RRF_DONE)) { len = LEN_STR(file.file.path); if (GET_FLAG(file.modes, RFM_DIR)) len++; name = Copy_OS_Str(file.file.path, len); if (GET_FLAG(file.modes, RFM_DIR)) SET_ANY_CHAR(name, name->tail-1, '/'); Set_Series(REB_FILE, Append_Value(files), name); } if (result < 0 && dir->error != -RFE_OPEN_FAIL && (FIND_CHR(dir->file.path, '*') || FIND_CHR(dir->file.path, '?'))) result = 0; // no matches found, but not an error return result; }
*/ REBFLG MT_Map(REBVAL *out, REBVAL *data, REBCNT type) /* ***********************************************************************/ { REBCNT n; REBSER *series; if (!IS_BLOCK(data) && !IS_MAP(data)) return FALSE; n = VAL_BLK_LEN(data); if (n & 1) return FALSE; series = Make_Map(n/2); //COPY_BLK_PART(series, VAL_BLK_DATA(data), n); Append_Map(series, data, UNKNOWN); Rehash_Hash(series); Set_Series(REB_MAP, out, series); return TRUE; }
*/ void Make_Block_Type(REBFLG make, REBVAL *value, REBVAL *arg) /* ** Value can be: ** 1. a datatype (e.g. BLOCK!) ** 2. a value (e.g. [...]) ** ** Arg can be: ** 1. integer (length of block) ** 2. block (copy it) ** 3. value (convert to a block) ** ***********************************************************************/ { REBCNT type; REBCNT len; REBSER *ser; // make block! ... if (IS_DATATYPE(value)) type = VAL_DATATYPE(value); else // make [...] .... type = VAL_TYPE(value); // make block! [1 2 3] if (ANY_BLOCK(arg)) { len = VAL_BLK_LEN(arg); if (len > 0 && type >= REB_PATH && type <= REB_LIT_PATH) No_Nones(arg); ser = Copy_Values(VAL_BLK_DATA(arg), len); goto done; } if (IS_STRING(arg)) { REBCNT index, len = 0; VAL_SERIES(arg) = Prep_Bin_Str(arg, &index, &len); // (keeps safe) ser = Scan_Source(VAL_BIN(arg), VAL_LEN(arg)); goto done; } if (IS_BINARY(arg)) { ser = Scan_Source(VAL_BIN_DATA(arg), VAL_LEN(arg)); goto done; } if (IS_MAP(arg)) { ser = Map_To_Block(VAL_SERIES(arg), 0); goto done; } if (ANY_OBJECT(arg)) { ser = Make_Object_Block(VAL_OBJ_FRAME(arg), 3); goto done; } if (IS_VECTOR(arg)) { ser = Make_Vector_Block(arg); goto done; } // if (make && IS_NONE(arg)) { // ser = Make_Block(0); // goto done; // } // to block! typset if (!make && IS_TYPESET(arg) && type == REB_BLOCK) { Set_Block(value, Typeset_To_Block(arg)); return; } if (make) { // make block! 10 if (IS_INTEGER(arg) || IS_DECIMAL(arg)) { len = Int32s(arg, 0); Set_Series(type, value, Make_Block(len)); return; } Trap_Arg(arg); } ser = Copy_Values(arg, 1); done: Set_Series(type, value, ser); return; }