Bram Moolenaar | edf3f97 | 2016-08-29 22:49:24 +0200 | [diff] [blame] | 1 | /* vi:set ts=8 sts=4 sw=4 noet: |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 2 | * |
| 3 | * VIM - Vi IMproved by Bram Moolenaar |
| 4 | * VMS port by Henk Elbers |
| 5 | * VMS deport by Zoltan Arpadffy |
| 6 | * |
| 7 | * Do ":help uganda" in Vim to read copying and usage conditions. |
| 8 | * Do ":help credits" in Vim to see a list of people who contributed. |
| 9 | * See README.txt for an overview of the Vim source code. |
| 10 | */ |
| 11 | |
| 12 | #include "vim.h" |
| 13 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 14 | // define _generic_64 for use in time functions |
Bram Moolenaar | b8e0bdb | 2014-11-12 16:10:48 +0100 | [diff] [blame] | 15 | #if !defined(VAX) && !defined(PROTO) |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 16 | # include <gen64def.h> |
| 17 | #else |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 18 | // based on Alpha's gen64def.h; the file is absent on VAX |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 19 | typedef struct _generic_64 { |
| 20 | # pragma __nomember_alignment |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 21 | __union { // You can treat me as... |
| 22 | // long long is not available on VAXen |
| 23 | // unsigned __int64 gen64$q_quadword; ...a single 64-bit value, or |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 24 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 25 | unsigned int gen64$l_longword [2]; // ...two 32-bit values, or |
| 26 | unsigned short int gen64$w_word [4]; // ...four 16-bit values |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 27 | } gen64$r_quad_overlay; |
| 28 | } GENERIC_64; |
| 29 | #endif |
| 30 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 31 | typedef struct |
| 32 | { |
| 33 | char class; |
| 34 | char type; |
| 35 | short width; |
| 36 | union |
| 37 | { |
| 38 | struct |
| 39 | { |
| 40 | char _basic[3]; |
| 41 | char length; |
| 42 | } y; |
| 43 | int basic; |
| 44 | } x; |
| 45 | int extended; |
| 46 | } TT_MODE; |
| 47 | |
| 48 | typedef struct |
| 49 | { |
| 50 | short buflen; |
| 51 | short itemcode; |
| 52 | char *bufadrs; |
| 53 | int *retlen; |
| 54 | } ITEM; |
| 55 | |
| 56 | typedef struct |
| 57 | { |
| 58 | ITEM equ; |
| 59 | int nul; |
| 60 | } ITMLST1; |
| 61 | |
| 62 | typedef struct |
| 63 | { |
| 64 | ITEM index; |
| 65 | ITEM string; |
| 66 | int nul; |
| 67 | } ITMLST2; |
| 68 | |
| 69 | static TT_MODE orgmode; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 70 | static short iochan; // TTY I/O channel |
| 71 | static short iosb[4]; // IO status block |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 72 | |
| 73 | static int vms_match_num = 0; |
| 74 | static int vms_match_free = 0; |
| 75 | static char_u **vms_fmatch = NULL; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 76 | static char *Fspec_Rms; // rms file spec, passed implicitly between routines |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 77 | |
| 78 | |
| 79 | |
Bram Moolenaar | baaa7e9 | 2016-01-29 22:47:03 +0100 | [diff] [blame] | 80 | static TT_MODE get_tty(void); |
| 81 | static void set_tty(int row, int col); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 82 | |
| 83 | #define EXPL_ALLOC_INC 64 |
| 84 | |
| 85 | #define EQN(S1,S2,LN) (strncmp(S1,S2,LN) == 0) |
Bram Moolenaar | 6f47002 | 2018-04-10 18:47:20 +0200 | [diff] [blame] | 86 | #define SKIP_FOLLOWING_SLASHES(Str) do { while (Str[1] == '/') ++Str; } while (0) |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 87 | |
| 88 | |
| 89 | /* |
| 90 | * vul_desc vult een descriptor met een string en de lengte |
| 91 | * hier van. |
| 92 | */ |
| 93 | static void |
| 94 | vul_desc(DESC *des, char *str) |
| 95 | { |
| 96 | des->dsc$b_dtype = DSC$K_DTYPE_T; |
| 97 | des->dsc$b_class = DSC$K_CLASS_S; |
| 98 | des->dsc$a_pointer = str; |
| 99 | des->dsc$w_length = str ? strlen(str) : 0; |
| 100 | } |
| 101 | |
| 102 | /* |
| 103 | * vul_item vult een item met een aantal waarden |
| 104 | */ |
| 105 | static void |
| 106 | vul_item(ITEM *itm, short len, short cod, char *adr, int *ret) |
| 107 | { |
| 108 | itm->buflen = len; |
| 109 | itm->itemcode = cod; |
| 110 | itm->bufadrs = adr; |
| 111 | itm->retlen = ret; |
| 112 | } |
| 113 | |
| 114 | void |
Bram Moolenaar | 26e8644 | 2020-05-17 14:06:16 +0200 | [diff] [blame] | 115 | mch_settmode(tmode_T tmode) |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 116 | { |
| 117 | int status; |
| 118 | |
| 119 | if ( tmode == TMODE_RAW ) |
| 120 | set_tty(0, 0); |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 121 | else |
| 122 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 123 | switch (orgmode.width) |
| 124 | { |
| 125 | case 132: OUT_STR_NF((char_u *)"\033[?3h\033>"); break; |
| 126 | case 80: OUT_STR_NF((char_u *)"\033[?3l\033>"); break; |
| 127 | default: break; |
| 128 | } |
| 129 | out_flush(); |
| 130 | status = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, |
| 131 | &orgmode, sizeof(TT_MODE), 0,0,0,0); |
| 132 | if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) |
| 133 | return; |
| 134 | (void)sys$dassgn(iochan); |
| 135 | iochan = 0; |
| 136 | } |
| 137 | } |
| 138 | |
| 139 | static void |
| 140 | set_tty(int row, int col) |
| 141 | { |
| 142 | int status; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 143 | TT_MODE newmode; // New TTY mode bits |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 144 | static short first_time = TRUE; |
| 145 | |
| 146 | if (first_time) |
| 147 | { |
| 148 | orgmode = get_tty(); |
| 149 | first_time = FALSE; |
| 150 | } |
| 151 | newmode = get_tty(); |
| 152 | if (col) |
| 153 | newmode.width = col; |
| 154 | if (row) |
| 155 | newmode.x.y.length = row; |
| 156 | newmode.x.basic |= (TT$M_NOECHO | TT$M_HOSTSYNC); |
| 157 | newmode.x.basic &= ~TT$M_TTSYNC; |
| 158 | newmode.extended |= TT2$M_PASTHRU; |
| 159 | status = sys$qiow(0, iochan, IO$_SETMODE, iosb, 0, 0, |
| 160 | &newmode, sizeof(newmode), 0, 0, 0, 0); |
| 161 | if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) |
| 162 | return; |
| 163 | } |
| 164 | |
| 165 | static TT_MODE |
| 166 | get_tty(void) |
| 167 | { |
| 168 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 169 | static $DESCRIPTOR(odsc,"SYS$OUTPUT"); // output descriptor |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 170 | |
| 171 | int status; |
| 172 | TT_MODE tt_mode; |
| 173 | |
| 174 | if (!iochan) |
| 175 | status = sys$assign(&odsc,&iochan,0,0); |
| 176 | |
| 177 | status = sys$qiow(0, iochan, IO$_SENSEMODE, iosb, 0, 0, |
| 178 | &tt_mode, sizeof(tt_mode), 0, 0, 0, 0); |
| 179 | if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) |
| 180 | { |
| 181 | tt_mode.width = 0; |
| 182 | tt_mode.type = 0; |
| 183 | tt_mode.class = 0; |
| 184 | tt_mode.x.basic = 0; |
| 185 | tt_mode.x.y.length = 0; |
| 186 | tt_mode.extended = 0; |
| 187 | } |
| 188 | return(tt_mode); |
| 189 | } |
| 190 | |
| 191 | /* |
| 192 | * Get the current window size in Rows and Columns. |
| 193 | */ |
| 194 | int |
| 195 | mch_get_shellsize(void) |
| 196 | { |
| 197 | TT_MODE tmode; |
| 198 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 199 | tmode = get_tty(); // get size from VMS |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 200 | Columns = tmode.width; |
| 201 | Rows = tmode.x.y.length; |
| 202 | return OK; |
| 203 | } |
| 204 | |
| 205 | /* |
| 206 | * Try to set the window size to Rows and new_Columns. |
| 207 | */ |
| 208 | void |
| 209 | mch_set_shellsize(void) |
| 210 | { |
| 211 | set_tty(Rows, Columns); |
| 212 | switch (Columns) |
| 213 | { |
| 214 | case 132: OUT_STR_NF((char_u *)"\033[?3h\033>"); break; |
| 215 | case 80: OUT_STR_NF((char_u *)"\033[?3l\033>"); break; |
| 216 | default: break; |
| 217 | } |
| 218 | out_flush(); |
| 219 | screen_start(); |
| 220 | } |
| 221 | |
| 222 | char_u * |
| 223 | mch_getenv(char_u *lognam) |
| 224 | { |
| 225 | DESC d_file_dev, d_lognam ; |
| 226 | static char buffer[LNM$C_NAMLENGTH+1]; |
| 227 | char_u *cp = NULL; |
| 228 | unsigned long attrib; |
| 229 | int lengte = 0, dum = 0, idx = 0; |
| 230 | ITMLST2 itmlst; |
| 231 | char *sbuf = NULL; |
| 232 | |
| 233 | vul_desc(&d_lognam, (char *)lognam); |
| 234 | vul_desc(&d_file_dev, "LNM$FILE_DEV"); |
| 235 | attrib = LNM$M_CASE_BLIND; |
| 236 | vul_item(&itmlst.index, sizeof(int), LNM$_INDEX, (char *)&idx, &dum); |
| 237 | vul_item(&itmlst.string, LNM$C_NAMLENGTH, LNM$_STRING, buffer, &lengte); |
| 238 | itmlst.nul = 0; |
| 239 | if (sys$trnlnm(&attrib, &d_file_dev, &d_lognam, NULL,&itmlst) == SS$_NORMAL) |
| 240 | { |
| 241 | buffer[lengte] = '\0'; |
Bram Moolenaar | c799fe2 | 2019-05-28 23:08:19 +0200 | [diff] [blame] | 242 | if (cp = alloc(lengte + 1)) |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 243 | strcpy((char *)cp, buffer); |
| 244 | return(cp); |
| 245 | } |
| 246 | else if ((sbuf = getenv((char *)lognam))) |
| 247 | { |
| 248 | lengte = strlen(sbuf) + 1; |
Bram Moolenaar | c799fe2 | 2019-05-28 23:08:19 +0200 | [diff] [blame] | 249 | cp = alloc(lengte); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 250 | if (cp) |
| 251 | strcpy((char *)cp, sbuf); |
| 252 | return cp; |
| 253 | } |
| 254 | else |
| 255 | return(NULL); |
| 256 | } |
| 257 | |
| 258 | /* |
| 259 | * mch_setenv VMS version of setenv() |
| 260 | */ |
| 261 | int |
| 262 | mch_setenv(char *var, char *value, int x) |
| 263 | { |
| 264 | int res, dum; |
| 265 | long attrib = 0L; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 266 | char acmode = PSL$C_SUPER; // needs SYSNAM privilege |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 267 | DESC tabnam, lognam; |
| 268 | ITMLST1 itmlst; |
| 269 | |
| 270 | vul_desc(&tabnam, "LNM$JOB"); |
| 271 | vul_desc(&lognam, var); |
| 272 | vul_item(&itmlst.equ, value ? strlen(value) : 0, value ? LNM$_STRING : 0, |
| 273 | value, &dum); |
| 274 | itmlst.nul = 0; |
| 275 | res = sys$crelnm(&attrib, &tabnam, &lognam, &acmode, &itmlst); |
| 276 | return((res == 1) ? 0 : -1); |
| 277 | } |
| 278 | |
| 279 | int |
| 280 | vms_sys(char *cmd, char *out, char *inp) |
| 281 | { |
| 282 | DESC cdsc, odsc, idsc; |
| 283 | long status; |
| 284 | |
| 285 | if (cmd) |
| 286 | vul_desc(&cdsc, cmd); |
| 287 | if (out) |
| 288 | vul_desc(&odsc, out); |
| 289 | if (inp) |
| 290 | vul_desc(&idsc, inp); |
| 291 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 292 | lib$spawn(cmd ? &cdsc : NULL, // command string |
| 293 | inp ? &idsc : NULL, // input file |
| 294 | out ? &odsc : NULL, // output file |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 295 | 0, 0, 0, &status, 0, 0, 0, 0, 0, 0); |
| 296 | return status; |
| 297 | } |
| 298 | |
| 299 | /* |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 300 | * Convert string to lowercase - most often filename |
| 301 | */ |
| 302 | char * |
| 303 | vms_tolower( char *name ) |
| 304 | { |
| 305 | int i,nlen = strlen(name); |
| 306 | for (i = 0; i < nlen; i++) |
| 307 | name[i] = TOLOWER_ASC(name[i]); |
| 308 | return name; |
| 309 | } |
| 310 | |
| 311 | /* |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 312 | * Convert VMS system() or lib$spawn() return code to Unix-like exit value. |
| 313 | */ |
| 314 | int |
| 315 | vms_sys_status(int status) |
| 316 | { |
| 317 | if (status != SS$_NORMAL && (status & STS$M_SUCCESS) == 0) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 318 | return status; // Command failed. |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 319 | return 0; |
| 320 | } |
| 321 | |
| 322 | /* |
| 323 | * vms_read() |
| 324 | * function for low level char input |
| 325 | * |
| 326 | * Returns: input length |
| 327 | */ |
| 328 | int |
| 329 | vms_read(char *inbuf, size_t nbytes) |
| 330 | { |
Bram Moolenaar | a83c3e0 | 2006-03-17 23:10:44 +0000 | [diff] [blame] | 331 | int status, function, len; |
| 332 | TT_MODE tt_mode; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 333 | ITEM itmlst[2]; // terminates on everything |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 334 | static long trm_mask[8] = {-1, -1, -1, -1, -1, -1, -1, -1}; |
| 335 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 336 | // whatever happened earlier we need an iochan here |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 337 | if (!iochan) |
Bram Moolenaar | a83c3e0 | 2006-03-17 23:10:44 +0000 | [diff] [blame] | 338 | tt_mode = get_tty(); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 339 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 340 | // important: clean the inbuf |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 341 | memset(inbuf, 0, nbytes); |
| 342 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 343 | // set up the itemlist for the first read |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 344 | vul_item(&itmlst[0], 0, TRM$_MODIFIERS, |
Bram Moolenaar | a83c3e0 | 2006-03-17 23:10:44 +0000 | [diff] [blame] | 345 | (char *)( TRM$M_TM_NOECHO | TRM$M_TM_NOEDIT | |
| 346 | TRM$M_TM_NOFILTR | TRM$M_TM_TRMNOECHO | |
| 347 | TRM$M_TM_NORECALL) , 0); |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 348 | vul_item(&itmlst[1], sizeof(trm_mask), TRM$_TERM, (char *)&trm_mask, 0); |
| 349 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 350 | // wait forever for a char |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 351 | function = (IO$_READLBLK | IO$M_EXTEND); |
| 352 | status = sys$qiow(0, iochan, function, &iosb, 0, 0, |
Bram Moolenaar | a83c3e0 | 2006-03-17 23:10:44 +0000 | [diff] [blame] | 353 | inbuf, nbytes-1, 0, 0, &itmlst, sizeof(itmlst)); |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 354 | len = strlen(inbuf); // how many chars we got? |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 355 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 356 | // read immediately the rest in the IO queue |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 357 | function = (IO$_READLBLK | IO$M_TIMED | IO$M_ESCAPE | IO$M_NOECHO | IO$M_NOFILTR); |
| 358 | status = sys$qiow(0, iochan, function, &iosb, 0, 0, |
Bram Moolenaar | a83c3e0 | 2006-03-17 23:10:44 +0000 | [diff] [blame] | 359 | inbuf+len, nbytes-1-len, 0, 0, 0, 0); |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 360 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 361 | len = strlen(inbuf); // return the total length |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 362 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 363 | return len; |
| 364 | } |
| 365 | |
| 366 | /* |
| 367 | * vms_wproc() is called for each matching filename by decc$to_vms(). |
| 368 | * We want to save each match for later retrieval. |
| 369 | * |
| 370 | * Returns: 1 - continue finding matches |
Bram Moolenaar | 82038d7 | 2007-05-10 17:15:45 +0000 | [diff] [blame] | 371 | * 0 - stop trying to find any further matches |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 372 | */ |
| 373 | static int |
| 374 | vms_wproc(char *name, int val) |
| 375 | { |
| 376 | int i; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 377 | static int vms_match_alloced = 0; |
| 378 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 379 | if (val == DECC$K_FOREIGN ) // foreign non VMS files are not counting |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 380 | return 1; |
| 381 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 382 | // accept all DECC$K_FILE and DECC$K_DIRECTORY |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 383 | if (vms_match_num == 0) |
| 384 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 385 | // first time through, setup some things |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 386 | if (NULL == vms_fmatch) |
| 387 | { |
Bram Moolenaar | 0c5c3fa | 2019-11-30 22:38:16 +0100 | [diff] [blame] | 388 | vms_fmatch = ALLOC_MULT(char_u *, EXPL_ALLOC_INC); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 389 | if (!vms_fmatch) |
| 390 | return 0; |
| 391 | vms_match_alloced = EXPL_ALLOC_INC; |
| 392 | vms_match_free = EXPL_ALLOC_INC; |
| 393 | } |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 394 | else |
| 395 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 396 | // re-use existing space |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 397 | vms_match_free = vms_match_alloced; |
| 398 | } |
| 399 | } |
| 400 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 401 | // make matches look uniform |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 402 | vms_remove_version(name); |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 403 | name=vms_tolower(name); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 404 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 405 | // if name already exists, don't add it |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 406 | for (i = 0; i<vms_match_num; i++) |
| 407 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 408 | if (0 == STRCMP((char_u *)name,vms_fmatch[i])) |
| 409 | return 1; |
| 410 | } |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 411 | if (--vms_match_free == 0) |
| 412 | { |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 413 | char_u **old_vms_fmatch = vms_fmatch; |
| 414 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 415 | // add more space to store matches |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 416 | vms_match_alloced += EXPL_ALLOC_INC; |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 417 | vms_fmatch = vim_realloc(old_vms_fmatch, |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 418 | sizeof(char **) * vms_match_alloced); |
| 419 | if (!vms_fmatch) |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 420 | { |
| 421 | vim_free(old_vms_fmatch); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 422 | return 0; |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 423 | } |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 424 | vms_match_free = EXPL_ALLOC_INC; |
| 425 | } |
| 426 | vms_fmatch[vms_match_num] = vim_strsave((char_u *)name); |
| 427 | |
| 428 | ++vms_match_num; |
| 429 | return 1; |
| 430 | } |
| 431 | |
| 432 | /* |
| 433 | * mch_expand_wildcards this code does wild-card pattern |
| 434 | * matching NOT using the shell |
| 435 | * |
Bram Moolenaar | e37d50a | 2008-08-06 17:06:04 +0000 | [diff] [blame] | 436 | * return OK for success, FAIL for error (you may lose some |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 437 | * memory) and put an error message in *file. |
| 438 | * |
| 439 | * num_pat number of input patterns |
| 440 | * pat array of pointers to input patterns |
| 441 | * num_file pointer to number of matched file names |
| 442 | * file pointer to array of pointers to matched file names |
| 443 | * |
| 444 | */ |
| 445 | int |
| 446 | mch_expand_wildcards(int num_pat, char_u **pat, int *num_file, char_u ***file, int flags) |
| 447 | { |
Bram Moolenaar | 6440447 | 2010-06-26 06:24:45 +0200 | [diff] [blame] | 448 | int i, cnt = 0; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 449 | char_u buf[MAXPATHL]; |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 450 | char *result; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 451 | int dir; |
| 452 | int files_alloced, files_free; |
| 453 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 454 | *num_file = 0; // default: no files found |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 455 | files_alloced = EXPL_ALLOC_INC; |
| 456 | files_free = EXPL_ALLOC_INC; |
Bram Moolenaar | 0c5c3fa | 2019-11-30 22:38:16 +0100 | [diff] [blame] | 457 | *file = ALLOC_MULT(char_u *, files_alloced); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 458 | if (*file == NULL) |
| 459 | { |
| 460 | *num_file = 0; |
| 461 | return FAIL; |
| 462 | } |
| 463 | for (i = 0; i < num_pat; i++) |
| 464 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 465 | // expand environment var or home dir |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 466 | if (vim_strchr(pat[i],'$') || vim_strchr(pat[i],'~')) |
| 467 | expand_env(pat[i],buf,MAXPATHL); |
| 468 | else |
| 469 | STRCPY(buf,pat[i]); |
| 470 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 471 | vms_match_num = 0; // reset collection counter |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 472 | result = decc$translate_vms(vms_fixfilename(buf)); |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 473 | if ( (int) result == 0 || (int) result == -1 ) |
| 474 | { |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 475 | cnt = 0; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 476 | } |
| 477 | else |
| 478 | { |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 479 | cnt = decc$to_vms(result, vms_wproc, 1 /*allow wild*/ , (flags & EW_DIR ? 0:1 ) /*allow directory*/) ; |
| 480 | } |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 481 | if (cnt > 0) |
| 482 | cnt = vms_match_num; |
| 483 | |
| 484 | if (cnt < 1) |
| 485 | continue; |
| 486 | |
| 487 | for (i = 0; i < cnt; i++) |
| 488 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 489 | // files should exist if expanding interactively |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 490 | if (!(flags & EW_NOTFOUND) && mch_getperm(vms_fmatch[i]) < 0) |
| 491 | continue; |
Bram Moolenaar | a203182 | 2006-03-07 22:29:51 +0000 | [diff] [blame] | 492 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 493 | // do not include directories |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 494 | dir = (mch_isdir(vms_fmatch[i])); |
| 495 | if (( dir && !(flags & EW_DIR)) || (!dir && !(flags & EW_FILE))) |
| 496 | continue; |
Bram Moolenaar | a203182 | 2006-03-07 22:29:51 +0000 | [diff] [blame] | 497 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 498 | // Skip files that are not executable if we check for that. |
Bram Moolenaar | b597114 | 2015-03-21 17:32:19 +0100 | [diff] [blame] | 499 | if (!dir && (flags & EW_EXEC) |
| 500 | && !mch_can_exe(vms_fmatch[i], NULL, !(flags & EW_SHELLCMD))) |
Bram Moolenaar | a203182 | 2006-03-07 22:29:51 +0000 | [diff] [blame] | 501 | continue; |
| 502 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 503 | // allocate memory for pointers |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 504 | if (--files_free < 1) |
| 505 | { |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 506 | char_u **old_file = *file; |
| 507 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 508 | files_alloced += EXPL_ALLOC_INC; |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 509 | *file = vim_realloc(old_file, sizeof(char_u **) * files_alloced); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 510 | if (*file == NULL) |
| 511 | { |
Bram Moolenaar | 9625d3d | 2019-11-30 22:57:53 +0100 | [diff] [blame] | 512 | vim_free(old_file); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 513 | *file = (char_u **)""; |
| 514 | *num_file = 0; |
| 515 | return(FAIL); |
| 516 | } |
| 517 | files_free = EXPL_ALLOC_INC; |
| 518 | } |
| 519 | |
| 520 | (*file)[*num_file++] = vms_fmatch[i]; |
| 521 | } |
| 522 | } |
| 523 | return OK; |
| 524 | } |
| 525 | |
| 526 | int |
| 527 | mch_expandpath(garray_T *gap, char_u *path, int flags) |
| 528 | { |
| 529 | int i,cnt = 0; |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 530 | char *result; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 531 | |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 532 | vms_match_num = 0; |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 533 | // the result from the decc$translate_vms needs to be handled |
| 534 | // otherwise it might create ACCVIO error in decc$to_vms |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 535 | result = decc$translate_vms(vms_fixfilename(path)); |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 536 | if ( (int) result == 0 || (int) result == -1 ) |
| 537 | { |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 538 | cnt = 0; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 539 | } |
| 540 | else |
| 541 | { |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 542 | cnt = decc$to_vms(result, vms_wproc, 1 /*allow_wild*/, (flags & EW_DIR ? 0:1 ) /*allow directory*/); |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 543 | } |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 544 | if (cnt > 0) |
| 545 | cnt = vms_match_num; |
| 546 | for (i = 0; i < cnt; i++) |
| 547 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 548 | if (mch_getperm(vms_fmatch[i]) >= 0) // add existing file |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 549 | addfile(gap, vms_fmatch[i], flags); |
| 550 | } |
| 551 | return cnt; |
| 552 | } |
| 553 | |
| 554 | /* |
| 555 | * attempt to translate a mixed unix-vms file specification to pure vms |
| 556 | */ |
| 557 | static void |
| 558 | vms_unix_mixed_filespec(char *in, char *out) |
| 559 | { |
| 560 | char *lastcolon; |
| 561 | char *end_of_dir; |
| 562 | char ch; |
| 563 | int len; |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 564 | char *out_str=out; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 565 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 566 | // copy vms filename portion up to last colon |
| 567 | // (node and/or disk) |
| 568 | lastcolon = strrchr(in, ':'); // find last colon |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 569 | if (lastcolon != NULL) |
| 570 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 571 | len = lastcolon - in + 1; |
| 572 | strncpy(out, in, len); |
| 573 | out += len; |
| 574 | in += len; |
| 575 | } |
| 576 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 577 | end_of_dir = NULL; // default: no directory |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 578 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 579 | // start of directory portion |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 580 | ch = *in; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 581 | if ((ch == '[') || (ch == '/') || (ch == '<')) // start of directory(s) ? |
| 582 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 583 | ch = '['; |
| 584 | SKIP_FOLLOWING_SLASHES(in); |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 585 | } |
| 586 | else if (EQN(in, "../", 3)) // Unix parent directory? |
| 587 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 588 | *out++ = '['; |
| 589 | *out++ = '-'; |
| 590 | end_of_dir = out; |
| 591 | ch = '.'; |
| 592 | in += 2; |
| 593 | SKIP_FOLLOWING_SLASHES(in); |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 594 | } |
| 595 | else |
| 596 | { // not a special character |
| 597 | while (EQN(in, "./", 2)) // Ignore Unix "current dir" |
| 598 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 599 | in += 2; |
| 600 | SKIP_FOLLOWING_SLASHES(in); |
| 601 | } |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 602 | if (strchr(in, '/') == NULL) // any more Unix directories ? |
| 603 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 604 | strcpy(out, in); // No - get rest of the spec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 605 | return; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 606 | } |
| 607 | else |
| 608 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 609 | *out++ = '['; // Yes, denote a Vms subdirectory |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 610 | ch = '.'; |
| 611 | --in; |
| 612 | } |
| 613 | } |
| 614 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 615 | // if we get here, there is a directory part of the filename |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 616 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 617 | // initialize output file spec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 618 | *out++ = ch; |
| 619 | ++in; |
| 620 | |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 621 | while (*in != '\0') |
| 622 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 623 | ch = *in; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 624 | if ((ch == ']') || (ch == '/') || (ch == '>') ) // end of (sub)directory ? |
| 625 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 626 | end_of_dir = out; |
| 627 | ch = '.'; |
| 628 | SKIP_FOLLOWING_SLASHES(in); |
| 629 | } |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 630 | else if (EQN(in, "../", 3)) // Unix parent directory? |
| 631 | { |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 632 | *out++ = '-'; |
| 633 | end_of_dir = out; |
| 634 | ch = '.'; |
| 635 | in += 2; |
| 636 | SKIP_FOLLOWING_SLASHES(in); |
| 637 | } |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 638 | else |
| 639 | { |
| 640 | while (EQN(in, "./", 2)) // Ignore Unix "current dir" |
| 641 | { |
| 642 | end_of_dir = out; |
| 643 | in += 2; |
| 644 | SKIP_FOLLOWING_SLASHES(in); |
| 645 | ch = *in; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 646 | } |
| 647 | } |
| 648 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 649 | // Place next character into output file spec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 650 | *out++ = ch; |
| 651 | ++in; |
| 652 | } |
| 653 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 654 | *out = '\0'; // Terminate output file spec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 655 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 656 | if (end_of_dir != NULL) // Terminate directory portion |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 657 | *end_of_dir = ']'; |
| 658 | } |
| 659 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 660 | /* |
| 661 | * for decc$to_vms in vms_fixfilename |
| 662 | */ |
| 663 | static int |
| 664 | vms_fspec_proc(char *fil, int val) |
| 665 | { |
| 666 | strcpy(Fspec_Rms,fil); |
| 667 | return(1); |
| 668 | } |
| 669 | |
| 670 | /* |
| 671 | * change unix and mixed filenames to VMS |
| 672 | */ |
| 673 | void * |
| 674 | vms_fixfilename(void *instring) |
| 675 | { |
| 676 | static char *buf = NULL; |
| 677 | static size_t buflen = 0; |
| 678 | size_t len; |
| 679 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 680 | // get a big-enough buffer |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 681 | len = strlen(instring) + 1; |
| 682 | if (len > buflen) |
| 683 | { |
| 684 | buflen = len + 128; |
Bram Moolenaar | c799fe2 | 2019-05-28 23:08:19 +0200 | [diff] [blame] | 685 | buf = vim_realloc(buf, buflen * sizeof(char)); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 686 | } |
| 687 | |
| 688 | #ifdef DEBUG |
Yegappan Lakshmanan | e89aef3 | 2025-05-14 20:31:55 +0200 | [diff] [blame] | 689 | char *tmpbuf = NULL; |
| 690 | tmpbuf = ALLOC_MULT(char, buflen); |
| 691 | strcpy(tmpbuf, instring); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 692 | #endif |
| 693 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 694 | Fspec_Rms = buf; // for decc$to_vms |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 695 | |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 696 | if (strchr(instring,'/') == NULL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 697 | // It is already a VMS file spec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 698 | strcpy(buf, instring); |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 699 | else if (strchr(instring,'"') == NULL) // password in the path? |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 700 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 701 | // Seems it is a regular file, let guess that it is pure Unix fspec |
Bram Moolenaar | 9f1983d | 2022-05-12 20:35:35 +0100 | [diff] [blame] | 702 | if ( (strchr(instring,'[') == NULL) && (strchr(instring,'<') == NULL) && |
Bram Moolenaar | 82c38fe | 2021-01-04 10:47:26 +0100 | [diff] [blame] | 703 | (strchr(instring,']') == NULL) && (strchr(instring,'>') == NULL) && |
| 704 | (strchr(instring,':') == NULL) ) |
| 705 | { |
| 706 | // It must be a truly unix fspec |
| 707 | decc$to_vms(instring, vms_fspec_proc, 0, 0); |
| 708 | } |
| 709 | else |
| 710 | { |
| 711 | // It is a mixed fspec |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 712 | vms_unix_mixed_filespec(instring, buf); |
Bram Moolenaar | 82c38fe | 2021-01-04 10:47:26 +0100 | [diff] [blame] | 713 | } |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 714 | } |
| 715 | else |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 716 | // we have a password in the path |
| 717 | // decc$ functions can not handle |
| 718 | // this is our only hope to resolv |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 719 | vms_unix_mixed_filespec(instring, buf); |
| 720 | |
| 721 | return buf; |
| 722 | } |
Bram Moolenaar | 9964e46 | 2007-05-05 17:54:07 +0000 | [diff] [blame] | 723 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 724 | /* |
| 725 | * Remove version number from file name |
| 726 | * we need it in some special cases as: |
| 727 | * creating swap file name and writing new file |
| 728 | */ |
| 729 | void |
| 730 | vms_remove_version(void * fname) |
| 731 | { |
| 732 | char_u *cp; |
| 733 | char_u *fp; |
| 734 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 735 | if ((cp = vim_strchr( fname, ';')) != NULL) // remove version |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 736 | *cp = '\0'; |
| 737 | else if ((cp = vim_strrchr( fname, '.')) != NULL ) |
| 738 | { |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 739 | if ((fp = vim_strrchr( fname, ']')) != NULL ) |
| 740 | {;} |
| 741 | else if ((fp = vim_strrchr( fname, '>')) != NULL ) |
| 742 | {;} |
| 743 | else |
| 744 | fp = fname; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 745 | |
| 746 | while ( *fp != '\0' && fp < cp ) |
| 747 | if ( *fp++ == '.' ) |
| 748 | *cp = '\0'; |
| 749 | } |
| 750 | return ; |
| 751 | } |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 752 | |
| 753 | struct typeahead_st { |
| 754 | unsigned short numchars; |
| 755 | unsigned char firstchar; |
| 756 | unsigned char reserved0; |
| 757 | unsigned long reserved1; |
| 758 | } typeahead; |
| 759 | |
| 760 | /* |
| 761 | * Wait "msec" msec until a character is available from file descriptor "fd". |
| 762 | * "msec" == 0 will check for characters once. |
| 763 | * "msec" == -1 will block until a character is available. |
| 764 | */ |
| 765 | int |
Bram Moolenaar | 0554097 | 2016-01-30 20:31:25 +0100 | [diff] [blame] | 766 | RealWaitForChar( |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 767 | int fd UNUSED, // always read from iochan |
Bram Moolenaar | 0554097 | 2016-01-30 20:31:25 +0100 | [diff] [blame] | 768 | long msec, |
Bram Moolenaar | de5e2c2 | 2016-11-04 20:35:31 +0100 | [diff] [blame] | 769 | int *check_for_gpm UNUSED, |
| 770 | int *interrupted) |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 771 | { |
| 772 | int status; |
| 773 | struct _generic_64 time_curr; |
| 774 | struct _generic_64 time_diff; |
| 775 | struct _generic_64 time_out; |
| 776 | unsigned int convert_operation = LIB$K_DELTA_SECONDS_F; |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 777 | float sec =(float) msec/1000; |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 778 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 779 | // make sure the iochan is set |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 780 | if (!iochan) |
| 781 | get_tty(); |
| 782 | |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 783 | if (sec > 0) |
| 784 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 785 | // time-out specified; convert it to absolute time |
| 786 | // sec>0 requirement of lib$cvtf_to_internal_time() |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 787 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 788 | // get current time (number of 100ns ticks since the VMS Epoch) |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 789 | status = sys$gettim(&time_curr); |
| 790 | if (status != SS$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 791 | return 0; // error |
| 792 | // construct the delta time |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 793 | #if __G_FLOAT==0 |
| 794 | # ifndef VAX |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 795 | // IEEE is default on IA64, but can be used on Alpha too - but not on VAX |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 796 | status = lib$cvts_to_internal_time( |
| 797 | &convert_operation, &sec, &time_diff); |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 798 | # endif |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 799 | #else // default on Alpha and VAX |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 800 | status = lib$cvtf_to_internal_time( |
Bram Moolenaar | 206f011 | 2014-03-12 16:51:55 +0100 | [diff] [blame] | 801 | &convert_operation, &sec, &time_diff); |
| 802 | #endif |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 803 | if (status != LIB$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 804 | return 0; // error |
| 805 | // add them up |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 806 | status = lib$add_times( |
| 807 | &time_curr, |
| 808 | &time_diff, |
| 809 | &time_out); |
| 810 | if (status != LIB$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 811 | return 0; // error |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 812 | } |
| 813 | |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 814 | while (TRUE) |
| 815 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 816 | // select() |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 817 | status = sys$qiow(0, iochan, IO$_SENSEMODE | IO$M_TYPEAHDCNT, iosb, |
| 818 | 0, 0, &typeahead, 8, 0, 0, 0, 0); |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 819 | if (status != SS$_NORMAL || (iosb[0] & 0xFFFF) != SS$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 820 | return 0; // error |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 821 | |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 822 | if (typeahead.numchars) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 823 | return 1; // ready to read |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 824 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 825 | // there's nothing to read; what now? |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 826 | if (msec == 0) |
| 827 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 828 | // immediate time-out; return impatiently |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 829 | return 0; |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 830 | } |
| 831 | else if (msec < 0) |
| 832 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 833 | // no time-out; wait on indefinitely |
| 834 | return 1; // fakeout to force a wait in vms_read() |
Bram Moolenaar | ebfec1c | 2023-01-22 21:14:53 +0000 | [diff] [blame] | 835 | } |
| 836 | else |
| 837 | { |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 838 | // time-out needs to be checked |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 839 | status = sys$gettim(&time_curr); |
| 840 | if (status != SS$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 841 | return 0; // error |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 842 | |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 843 | status = lib$sub_times( |
| 844 | &time_out, |
| 845 | &time_curr, |
| 846 | &time_diff); |
| 847 | if (status != LIB$_NORMAL) |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 848 | return 0; // error, incl. time_diff < 0 (i.e. time-out) |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 849 | |
Bram Moolenaar | 0f87373 | 2019-12-05 20:28:46 +0100 | [diff] [blame] | 850 | // otherwise wait some more |
Bram Moolenaar | 792f0e3 | 2018-02-27 17:27:13 +0100 | [diff] [blame] | 851 | } |
Bram Moolenaar | 4ffa070 | 2013-12-11 17:12:37 +0100 | [diff] [blame] | 852 | } |
| 853 | } |