*/ 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; }
*/ REBCHR *OS_Form_Error(int errnum, REBCHR *str, int len) /* ** Translate OS error into a string. The str is the string ** buffer and the len is the length of the buffer. ** ***********************************************************************/ { LPVOID lpMsgBuf; int ok; if (!errnum) errnum = GetLastError(); ok = FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errnum, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL); len--; // termination if (!ok) COPY_STR(str, TEXT("unknown error"), len); else { COPY_STR(str, lpMsgBuf, len); len = (int)LEN_STR(str); if (str[len-2] == '\r' && str[len-1] == '\n') str[len-2] = 0; // trim CRLF LocalFree(lpMsgBuf); } return str; }
*/ DEVICE_CMD Read_Clipboard(REBREQ *req) /* ***********************************************************************/ { REBYTE *data; //put the OS specific code here //============================= // //============================= req->actual = 0; if ((data) == NULL) { req->error = 30; return DR_ERROR; } //make sure "bytes mode" is set CLR_FLAG(req->flags, RRF_WIDE); req->data = data; req->actual = LEN_STR(data); return DR_DONE; }
*/ REBVAL *Make_OS_Error() /* ***********************************************************************/ { REBCHR str[100]; OS_FORM_ERROR(0, str, 100); Set_String(DS_RETURN, Copy_OS_Str(str, LEN_STR(str))); return DS_RETURN; }
*/ 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; }
*/ DEVICE_CMD Read_Clipboard(REBREQ *req) /* ***********************************************************************/ { HANDLE data; REBUNI *cp; REBUNI *bin; REBINT len; req->actual = 0; // If there is no clipboard data: if (!IsClipboardFormatAvailable(CF_UNICODETEXT)) { req->error = 10; return DR_ERROR; } if (!OpenClipboard(NULL)) { req->error = 20; return DR_ERROR; } // Read the UTF-8 data: if ((data = GetClipboardData(CF_UNICODETEXT)) == NULL) { CloseClipboard(); req->error = 30; return DR_ERROR; } cp = GlobalLock(data); if (!cp) { GlobalUnlock(data); CloseClipboard(); req->error = 40; return DR_ERROR; } len = LEN_STR(cp); // wide chars bin = OS_Make((len+1) * sizeof(REBCHR)); COPY_STR(bin, cp, len); GlobalUnlock(data); CloseClipboard(); SET_FLAG(req->flags, RRF_WIDE); req->data = (REBYTE *)bin; req->actual = len * sizeof(REBCHR); return DR_DONE; }
*/ static void Insert_Command_Arg(REBCHR *cmd, REBCHR *arg, REBINT limit) /* ** Insert an argument into a command line at the %1 position, ** or at the end if there is no %1. (An INSERT action.) ** Do not exceed the specified limit length. ** ** Too bad std Clib does not provide INSERT or REPLACE functions. ** ***********************************************************************/ { #define HOLD_SIZE 2000 REBCHR *spot; REBCHR hold[HOLD_SIZE+4]; if ((REBINT)LEN_STR(cmd) >= limit) return; // invalid case, ignore it. // Find %1: spot = FIND_STR(cmd, TEXT("%1")); if (spot) { // Save rest of cmd line (such as end quote, -flags, etc.) COPY_STR(hold, spot+2, HOLD_SIZE); // Terminate at the arg location: spot[0] = 0; // Insert the arg: JOIN_STR(spot, arg, limit - LEN_STR(cmd) - 1); // Add back the rest of cmd: JOIN_STR(spot, hold, limit - LEN_STR(cmd) - 1); } else { JOIN_STR(cmd, TEXT(" "), 1); JOIN_STR(cmd, arg, limit - LEN_STR(cmd) - 1); } }
*/ 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; }
*/ REBCHR *OS_List_Env(void) /* ***********************************************************************/ { REBCHR *env = GetEnvironmentStrings(); REBCNT n, len = 0; REBCHR *str; str = env; while (n = (REBCNT)LEN_STR(str)) { len += n + 1; str = env + len; // next } len++; str = OS_Make(len * sizeof(REBCHR)); MOVE_MEM(str, env, len * sizeof(REBCHR)); FreeEnvironmentStrings(env); return str; }
*/ void Parse_Args(int argc, REBCHR **argv, REBARGS *rargs) /* ** Parse REBOL's command line arguments, setting options ** and values in the provided args structure. ** ***********************************************************************/ { REBCHR *arg; REBCHR *args = 0; // holds trailing args int flag; int i; CLEARS(rargs); // First arg is path to execuable (on most systems): if (argc > 0) rargs->exe_path = *argv; OS_Get_Current_Dir(&rargs->home_dir); // Parse each argument: for (i = 1; i < argc ; i++) { arg = argv[i]; if (arg == 0) continue; // shell bug if (*arg == '-') { if (arg[1] == '-') { // --option words flag = find_option_word(arg+2); if (flag & RO_EXT) { flag = Get_Ext_Arg(flag, rargs, (i+1 >= argc) ? 0 : argv[i+1]); if ((flag & RO_EXT) == 0) i++; // used it else flag &= ~RO_EXT; } if (!flag) flag = RO_HELP; rargs->options |= flag; } else { // -x option chars while (*++arg) { flag = find_option_char(*arg, arg_chars); if (flag & RO_EXT) { flag = Get_Ext_Arg(flag, rargs, (i+1 >= argc) ? 0 : argv[i+1]); if ((flag & RO_EXT) == 0) i++; // used it else flag &= ~RO_EXT; } if (!flag) flag = RO_HELP; rargs->options |= flag; } } } else if (*arg == '+') { // +x option chars while (*++arg) { flag = find_option_char(*arg, arg_chars2); if (flag & RO_EXT) { flag = Get_Ext_Arg(flag, rargs, (i+1 >= argc) ? 0 : argv[i+1]); if ((flag & RO_EXT) == 0) i++; // used it else flag &= ~RO_EXT; } if (!flag) flag = RO_HELP; rargs->options |= flag; } } else { // script filename if (!rargs->script) rargs->script = arg; else { int len; if (!args) { args = MAKE_STR(ARG_BUF_SIZE); args[0] = 0; } len = ARG_BUF_SIZE - LEN_STR(args) - 2; // space remaining JOIN_STR(args, arg, len); JOIN_STR(args, TXT(" "), 1); } } } if (args) { args[LEN_STR(args)-1] = 0; // remove trailing space Get_Ext_Arg(RO_ARGS, rargs, args); } }