Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1 | /* vi:set ts=8 sts=4 sw=4: |
| 2 | * |
| 3 | * VIM - Vi IMproved by Bram Moolenaar |
| 4 | * |
| 5 | * Do ":help uganda" in Vim to read copying and usage conditions. |
| 6 | * Do ":help credits" in Vim to see a list of people who contributed. |
| 7 | * See README.txt for an overview of the Vim source code. |
| 8 | */ |
| 9 | |
| 10 | #include "vim.h" |
| 11 | |
| 12 | /* |
| 13 | * os_riscos.c |
| 14 | * |
| 15 | * Thomas Leonard <tal197@ecs.soton.ac.uk> |
| 16 | */ |
| 17 | |
| 18 | const char *__dynamic_da_name = "Vim heap"; /* Enable and name our dynamic area */ |
| 19 | int ro_line_mode = TRUE; /* For Ex mode we much echo chars to the screen ourselves */ |
| 20 | int windowed; /* Flag - are we running inside a text window? */ |
| 21 | int WinLeft, WinTop; /* We might be started inside a text window */ |
| 22 | int ScrollTop; /* Make cursor movements relative to ScrollTop. */ |
| 23 | |
| 24 | int old_escape_state = -1; |
| 25 | int old_cursor_state = -1; |
| 26 | |
| 27 | #define rgb(r,g,b) ((b<<24) + (g<<16) + (r<<8)) |
| 28 | #define NORMAL_FG 0x00000000 |
| 29 | #define NORMAL_BG 0xffffffff |
| 30 | |
| 31 | /* Convert a DOS colour number to an RGB palette entry. |
| 32 | * Mappings from X11 rgb/txt file. |
| 33 | */ |
| 34 | static int |
| 35 | map_colour(dos) |
| 36 | int dos; /* Standard DOS colour number. */ |
| 37 | { |
| 38 | switch (dos) |
| 39 | { |
| 40 | case 0: return 0; /* Black */ |
| 41 | case 1: return rgb(0,0,139); /* DarkBlue */ |
| 42 | case 2: return rgb(0,100,0); /* DarkGreen */ |
| 43 | case 3: return rgb(0,139,139); /* DarkCyan */ |
| 44 | case 4: return rgb(139,0,0); /* DarkRed */ |
| 45 | case 5: return rgb(139,0,139); /* DarkMagenta */ |
| 46 | case 6: return rgb(165,42,42); /* Brown, DarkYellow */ |
| 47 | case 7: return rgb(211,211,211); /* LightGray, LightGrey, Gray, Grey */ |
| 48 | case 8: return rgb(169,169,169); /* DarkGray, DarkGrey */ |
| 49 | case 9: return rgb(173,216,230); /* Blue, LightBlue */ |
| 50 | case 10: return rgb(144,238,144); /* Green, LightGreen */ |
| 51 | case 11: return rgb(224,255,255); /* Cyan, LightCyan */ |
| 52 | case 12: return rgb(255,0,0); /* Red, LightRed */ |
| 53 | case 13: return rgb(255,0,255); /* Magenta, LightMagenta */ |
| 54 | case 14: return rgb(255,255,0); /* Yellow, LightYellow */ |
| 55 | case 15: return rgb(255,255,255); /* White */ |
| 56 | } |
| 57 | return rgb(100,100,100); |
| 58 | } |
| 59 | |
| 60 | static void |
| 61 | text_fg(fg) |
| 62 | int fg; /* Foregound colour in the form &BBGGRR00 */ |
| 63 | { |
| 64 | xswi(ColourTrans_SetTextColour, fg, 0, 0, 0); |
| 65 | } |
| 66 | |
| 67 | static void |
| 68 | text_bg(bg) |
| 69 | int bg; /* Backgound colour in the form &BBGGRR00 */ |
| 70 | { |
| 71 | xswi(ColourTrans_SetTextColour, bg, 0, 0, 1 << 7); |
| 72 | } |
| 73 | |
| 74 | #define OUT_NORMAL 0 |
| 75 | #define OUT_NUMBER 1 /* Reading in a number */ |
| 76 | |
| 77 | void |
| 78 | mch_write(s, len) |
| 79 | char_u *s; |
| 80 | int len; |
| 81 | { |
| 82 | static int mode = OUT_NORMAL; |
| 83 | static int x, y; /* For reading numbers in. */ |
| 84 | |
| 85 | if (!term_console) |
| 86 | { |
| 87 | /* Maybe we are running Vim remotely - don't interpret chars */ |
| 88 | while (len--) |
| 89 | { |
| 90 | char_u c = *s++; |
| 91 | swi(OS_WriteC, c); |
| 92 | /* We might need to send a CR too. This shouldn't |
| 93 | * hurt if we don't need it, should it? |
| 94 | */ |
| 95 | if (c == 10) |
| 96 | swi(OS_WriteI + 13); |
| 97 | } |
| 98 | return; |
| 99 | } |
| 100 | |
| 101 | while (len--) |
| 102 | { |
| 103 | char_u c = *s++; |
| 104 | switch (mode) |
| 105 | { |
| 106 | case OUT_NUMBER: |
| 107 | if (c < '0' || c > '9') |
| 108 | { |
| 109 | mode = OUT_NORMAL; |
| 110 | } |
| 111 | else |
| 112 | { |
| 113 | x = (x * 10) + c - '0'; |
| 114 | continue; |
| 115 | } |
| 116 | /* note: no break here! */ |
| 117 | |
| 118 | case OUT_NORMAL: |
| 119 | switch (c) |
| 120 | { |
| 121 | case 1: |
| 122 | /* Number (in decimal) follows. */ |
| 123 | mode = OUT_NUMBER; |
| 124 | y = x; |
| 125 | x = 0; |
| 126 | break; |
| 127 | case 2: |
| 128 | /* Position cursor. */ |
| 129 | swi(OS_WriteI + 31); |
| 130 | swi(OS_WriteC, x); |
| 131 | swi(OS_WriteC, y - ScrollTop); |
| 132 | break; |
| 133 | case 3: |
| 134 | /* Set scroll region. */ |
| 135 | if (x == Rows -1 && y == 0 && !windowed) |
| 136 | { |
| 137 | /* Whole screen - remove text window. |
| 138 | * This is MUCH faster. |
| 139 | */ |
| 140 | swi(OS_WriteI + 26); |
| 141 | } |
| 142 | else |
| 143 | { |
| 144 | /* Create a text window. */ |
| 145 | swi(OS_WriteI + 28); |
| 146 | swi(OS_WriteC, WinLeft); |
| 147 | swi(OS_WriteC, WinTop + x); |
| 148 | swi(OS_WriteC, WinLeft + Columns - 1); |
| 149 | swi(OS_WriteC, WinTop + y); |
| 150 | } |
| 151 | ScrollTop = y; |
| 152 | break; |
| 153 | case 4: |
| 154 | /* Normal mode. */ |
| 155 | text_fg(NORMAL_FG); |
| 156 | text_bg(NORMAL_BG); |
| 157 | break; |
| 158 | case 5: |
| 159 | /* Reverse mode. */ |
| 160 | text_fg(NORMAL_BG); |
| 161 | text_bg(NORMAL_FG); |
| 162 | break; |
| 163 | case 10: |
| 164 | swi(OS_NewLine); |
| 165 | break; |
| 166 | case 14: |
| 167 | /* Cursor invisible. */ |
| 168 | swi(OS_WriteN, |
| 169 | "\027\001\000\000\000\000\000\000\000\000", |
| 170 | 10); |
| 171 | break; |
| 172 | case 15: |
| 173 | /* Cursor visible. */ |
| 174 | swi(OS_WriteN, |
| 175 | "\027\001\002\000\000\000\000\000\000\000", |
| 176 | 10); |
| 177 | break; |
| 178 | case 16: |
| 179 | /* Cursor very visible (flash) */ |
| 180 | swi(OS_WriteN, |
| 181 | "\027\001\003\000\000\000\000\000\000\000", |
| 182 | 10); |
| 183 | case 17: |
| 184 | /* Set foreground colour. */ |
| 185 | text_fg(map_colour(x)); |
| 186 | break; |
| 187 | case 18: |
| 188 | /* Set background colour. */ |
| 189 | text_bg(map_colour(x)); |
| 190 | break; |
| 191 | case 19: |
| 192 | /* Scroll text down. */ |
| 193 | swi(OS_WriteN, |
| 194 | "\027\007\000\002\000\000\000\000\000\000", |
| 195 | 10); |
| 196 | break; |
| 197 | default: |
| 198 | swi(OS_WriteC, c); |
| 199 | } |
| 200 | continue; |
| 201 | |
| 202 | default: |
| 203 | printf("[output error]"); |
| 204 | mode = OUT_NORMAL; |
| 205 | } |
| 206 | } |
| 207 | } |
| 208 | |
| 209 | /* |
| 210 | * mch_inchar(): low level input funcion. |
| 211 | * Get a characters from the keyboard. |
| 212 | * Return the number of characters that are available. |
| 213 | * If wtime == 0 do not wait for characters. |
| 214 | * If wtime == n wait n msecs for characters. |
| 215 | * If wtime == -1 wait forever for characters. |
| 216 | * |
| 217 | * TODO: call convert_input() for 'fileencoding' to 'encoding' conversion. |
| 218 | */ |
| 219 | int |
| 220 | mch_inchar(buf, maxlen, wtime, tb_change_cnt) |
| 221 | char_u *buf; |
| 222 | int maxlen; |
| 223 | long wtime; |
| 224 | int tb_change_cnt; |
| 225 | { |
| 226 | int got=0; |
| 227 | unsigned int start_time = clock(); |
| 228 | |
| 229 | if (ro_line_mode) |
| 230 | { |
| 231 | /* We're probably in Ex mode - get whole lines at a time. */ |
| 232 | |
| 233 | static char_u line_buffer[256]; |
| 234 | static int remaining_chars = 0; |
| 235 | static int buf_pos = 0; |
| 236 | |
| 237 | /* Do we need to fetch another line? */ |
| 238 | if (remaining_chars == 0) |
| 239 | { |
| 240 | int old_esc_state; |
| 241 | swi(OS_Byte, 200, 1, 0xfe); |
| 242 | old_esc_state = r1; |
| 243 | |
| 244 | buf_pos = 0; |
| 245 | if (xswi(OS_ReadLine, line_buffer, 255, 0, 255) & (c_flag | v_flag)) |
| 246 | { |
| 247 | got_int = TRUE; /* ESC pressed */ |
| 248 | r1 = 0; |
| 249 | } |
| 250 | line_buffer[r1] = 13; |
| 251 | remaining_chars = r1 + 1; /* Count CR as part of input */ |
| 252 | |
| 253 | swi(OS_Byte, 200, old_esc_state, 0); |
| 254 | } |
| 255 | |
| 256 | /* Can we send the rest of the buffer back in one go? */ |
| 257 | if (remaining_chars <= maxlen) |
| 258 | { |
| 259 | int got = remaining_chars; |
| 260 | |
| 261 | memcpy(buf, line_buffer + buf_pos, got); |
| 262 | remaining_chars = 0; |
| 263 | return got; |
| 264 | } |
| 265 | |
| 266 | /* Send as much as we can */ |
| 267 | memcpy(buf, line_buffer + buf_pos, maxlen); |
| 268 | buf_pos += maxlen; |
| 269 | remaining_chars -= maxlen; |
| 270 | |
| 271 | return maxlen; |
| 272 | } |
| 273 | |
| 274 | if (!term_console) |
| 275 | { |
| 276 | /* Use OS_ReadC for all input. |
| 277 | * Avoids problems with remote access getting interference from |
| 278 | * the keyboard. |
| 279 | */ |
| 280 | if (wtime == 0) |
| 281 | return 0; /* Ignore quick key checks */ |
| 282 | |
| 283 | if (xswi(OS_ReadC) & c_flag) |
| 284 | { |
| 285 | got_int = TRUE; /* ESC pressed - can this happen? */ |
| 286 | swi(OS_Byte, 124); /* Clear Escape state */ |
| 287 | r0 = 0x1b; /* It *might* not have been Escape! */ |
| 288 | } |
| 289 | buf[0] = r0; |
| 290 | return 1; |
| 291 | } |
| 292 | |
| 293 | /* |
| 294 | * OK, here's the plan: |
| 295 | * |
| 296 | * 1) Wait until wtime expires or we get a key |
| 297 | * 2) Get keys until the keyboard buffer is empty or buf is full |
| 298 | */ |
| 299 | |
| 300 | while (xswi(OS_Byte,145,0) & c_flag) |
| 301 | { |
| 302 | /* Nothing at all in the keyboard buffer. |
| 303 | * Has our time expired yet? |
| 304 | */ |
| 305 | if ( (wtime != -1) && (clock() - start_time) >= wtime ) |
| 306 | return 0; /* Nothing read - giving up */ |
| 307 | } |
| 308 | |
| 309 | /* We've got one char (in r2) - are there any more? */ |
| 310 | |
| 311 | while (got < maxlen) |
| 312 | { |
| 313 | buf[got++] = r2; |
| 314 | |
| 315 | if (xswi(OS_Byte,145,0) & c_flag) |
| 316 | return got; /* Keyboard buffer empty */ |
| 317 | } |
| 318 | return got; /* buf is full */ |
| 319 | } |
| 320 | |
| 321 | /* |
| 322 | * return non-zero if a character is available |
| 323 | */ |
| 324 | int |
| 325 | mch_char_avail() |
| 326 | { |
| 327 | if (!term_console) |
| 328 | return 0; /* Can't tell */ |
| 329 | if (xswi(OS_Byte, 152, 0) & c_flag) |
| 330 | return 0; |
| 331 | return 1; |
| 332 | } |
| 333 | |
| 334 | /* Find out how much free memory we have. |
| 335 | * I don't know how to work this out exactly but, since we can claim |
| 336 | * more memory from the OS, let's just report the free pool size. |
| 337 | * Dynamic area 6 doesn't exist pre 3.6 according to StrongHelp, so |
| 338 | * we'll use Wimp_SlotSize. If that fails (outside the desktop?) |
| 339 | * then just return a big number and hope. |
| 340 | */ |
| 341 | long_u |
| 342 | mch_avail_mem(special) |
| 343 | int special; |
| 344 | { |
| 345 | if (xswi(Wimp_SlotSize, -1, -1) & v_flag) |
| 346 | return 0x7fffffff; |
| 347 | return r2; |
| 348 | } |
| 349 | |
| 350 | void |
| 351 | mch_delay(msec, ignoreinput) |
| 352 | long msec; |
| 353 | int ignoreinput; |
| 354 | { |
| 355 | int start_time, time_now; |
| 356 | int csec = msec / 10; |
| 357 | |
| 358 | swi(OS_ReadMonotonicTime); |
| 359 | start_time = r0; |
| 360 | |
| 361 | for (;;) |
| 362 | { |
| 363 | swi(OS_ReadMonotonicTime); |
| 364 | time_now = r0; |
| 365 | if (time_now - start_time > csec) |
| 366 | return; |
| 367 | #ifdef FEAT_GUI |
| 368 | /* In the GUI, allow other programs to run while waiting. */ |
| 369 | if (gui.in_use) |
| 370 | gui_mch_wait_for_chars(start_time + csec); |
| 371 | #endif |
| 372 | } |
| 373 | } |
| 374 | |
| 375 | /* |
| 376 | * If the machine has job control, use it to suspend the program, |
| 377 | * otherwise fake it by starting a new shell. |
| 378 | */ |
| 379 | void |
| 380 | mch_suspend() |
| 381 | { |
| 382 | suspend_shell(); |
| 383 | } |
| 384 | |
| 385 | void |
| 386 | mch_init() |
| 387 | { |
| 388 | /* |
| 389 | * Read window size first. Calls to mch_get_shellsize() will |
| 390 | * simply return these values in future so that setting the |
| 391 | * text window (used for scrolling) won't give strange results. |
| 392 | */ |
| 393 | |
| 394 | int buf[7] = {132, 135, 256, 257, 1, 2, -1}; |
| 395 | |
| 396 | /* Command windows are no longer forced open, since if we are |
| 397 | * in the desktop then we'll use the GUI version. |
| 398 | * Opening a command window here messes up the GUI version startup |
| 399 | */ |
| 400 | #ifndef FEAT_GUI |
| 401 | swi(OS_WriteI); |
| 402 | #endif |
| 403 | swi(OS_ReadVduVariables, buf, buf); |
| 404 | WinLeft = buf[0]; |
| 405 | WinTop = buf[1]; |
| 406 | Columns = buf[2]; |
| 407 | Rows = buf[3] + 1; /* Seems to be one off (VduVars wrong?) */ |
| 408 | ScrollTop = 0; |
| 409 | |
| 410 | /* Are we running in a textwindow? */ |
| 411 | if (Rows == buf[5] + 1 && Columns == buf[4] + 1) |
| 412 | windowed = 0; |
| 413 | else |
| 414 | windowed = 1; |
| 415 | |
| 416 | /* Choose a nice colour scheme. */ |
| 417 | text_fg(NORMAL_FG); |
| 418 | text_bg(NORMAL_BG); |
| 419 | } |
| 420 | |
| 421 | /* |
| 422 | * Check_win checks whether we have an interactive stdout. |
| 423 | */ |
| 424 | /* ARGSUSED */ |
| 425 | int |
| 426 | mch_check_win(argc, argv) |
| 427 | int argc; |
| 428 | char **argv; |
| 429 | { |
| 430 | return OK; |
| 431 | } |
| 432 | |
| 433 | /* |
| 434 | * Return TRUE if the input comes from a terminal, FALSE otherwise. |
| 435 | */ |
| 436 | int |
| 437 | mch_input_isatty() |
| 438 | { |
| 439 | if (xswi(OS_ChangeRedirection, -1, -1) & v_flag) |
| 440 | return TRUE; /* Error - TRUE is probably correct though */ |
| 441 | if (r0 == 0) |
| 442 | return TRUE; |
| 443 | return FALSE; |
| 444 | } |
| 445 | |
| 446 | #ifdef FEAT_TITLE |
| 447 | int |
| 448 | mch_can_restore_title() |
| 449 | { |
| 450 | return FALSE; |
| 451 | } |
| 452 | |
| 453 | int |
| 454 | mch_can_restore_icon() |
| 455 | { |
| 456 | return FALSE; |
| 457 | } |
| 458 | |
| 459 | |
| 460 | /* |
| 461 | * Set the window title and icon. |
| 462 | */ |
| 463 | void |
| 464 | mch_settitle(title, icon) |
| 465 | char_u *title; |
| 466 | char_u *icon; |
| 467 | { |
| 468 | if (title == NULL) |
| 469 | title = (char_u *) "<untitled>"; |
| 470 | #ifdef FEAT_GUI |
| 471 | if (gui.in_use && strcmp(title, gui.window_title)) |
| 472 | { |
| 473 | int length; |
| 474 | length = strlen(title); |
| 475 | if (length >= gui.window_title_size) |
| 476 | length = gui.window_title_size - 1; |
| 477 | strncpy(gui.window_title, title, length); |
| 478 | gui.window_title[length] = 0; |
| 479 | ro_redraw_title(gui.window_handle); |
| 480 | } |
| 481 | #endif |
| 482 | return; |
| 483 | } |
| 484 | |
| 485 | /* |
| 486 | * Restore the window/icon title. |
| 487 | * "which" is one of: |
| 488 | * 1 only restore title |
| 489 | * 2 only restore icon |
| 490 | * 3 restore title and icon |
| 491 | */ |
| 492 | void |
| 493 | mch_restore_title(which) |
| 494 | int which; |
| 495 | { |
| 496 | return; |
| 497 | } |
| 498 | #endif |
| 499 | |
| 500 | /* |
| 501 | * Insert user name in s[len]. |
| 502 | * Return OK if a name found. |
| 503 | */ |
| 504 | int |
| 505 | mch_get_user_name(s, len) |
| 506 | char_u *s; |
| 507 | int len; |
| 508 | { |
| 509 | /* RISC OS doesn't support user names. */ |
| 510 | *s = NUL; |
| 511 | return FAIL; |
| 512 | } |
| 513 | |
| 514 | /* |
| 515 | * Insert host name in s[len]. |
| 516 | */ |
| 517 | |
| 518 | void |
| 519 | mch_get_host_name(s, len) |
| 520 | char_u *s; |
| 521 | int len; |
| 522 | { |
| 523 | if (xswi(OS_ReadVarVal, "Machine$Name", s, len, 0, 3) & v_flag) |
| 524 | { |
| 525 | /* Variable does not exist (normal operation) */ |
Bram Moolenaar | b635633 | 2005-07-18 21:40:44 +0000 | [diff] [blame] | 526 | vim_strncpy(s, "(unknown)", len - 1); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 527 | } |
| 528 | } |
| 529 | |
| 530 | /* |
| 531 | * return process ID |
| 532 | */ |
| 533 | long |
| 534 | mch_get_pid() |
| 535 | { |
| 536 | if (xswi(Wimp_ReadSysInfo, 5) & v_flag) |
| 537 | return 0; |
| 538 | return r0; |
| 539 | } |
| 540 | |
| 541 | /* |
| 542 | * Get name of current directory into buffer 'buf' of length 'len' bytes. |
| 543 | * Return OK for success, FAIL for failure. |
| 544 | */ |
| 545 | int |
| 546 | mch_dirname(buf, len) |
| 547 | char_u *buf; |
| 548 | int len; |
| 549 | { |
| 550 | if (xswi(OS_FSControl, 37, "@", buf, 0, 0, len) & v_flag) |
| 551 | return FAIL; |
| 552 | return OK; |
| 553 | } |
| 554 | |
| 555 | /* |
| 556 | * Get absolute file name into buffer 'buf' of length 'len' bytes. |
| 557 | * |
| 558 | * return FAIL for failure, OK for success |
| 559 | */ |
| 560 | int |
| 561 | mch_FullName(fname, buf, len, force) |
| 562 | char_u *fname, *buf; |
| 563 | int len; |
| 564 | int force; /* Also expand when already absolute path name. |
| 565 | * Not used under RISC OS. |
| 566 | */ |
| 567 | { |
| 568 | if (xswi(OS_FSControl, 37, fname, buf, 0, 0, len) & v_flag) |
| 569 | return FAIL; |
| 570 | return OK; |
| 571 | } |
| 572 | |
| 573 | /* |
| 574 | * Return TRUE if "fname" does not depend on the current directory. |
| 575 | */ |
| 576 | int |
| 577 | mch_isFullName(fname) |
| 578 | char_u *fname; |
| 579 | { |
| 580 | if (strstr(fname, "::") && strstr(fname,".$.")) |
| 581 | return TRUE; |
| 582 | return FALSE; |
| 583 | } |
| 584 | |
| 585 | /* |
| 586 | * Get file permissions for 'name'. |
| 587 | * Returns -1 when it doesn't exist. |
| 588 | */ |
| 589 | long |
| 590 | mch_getperm(name) |
| 591 | char_u *name; |
| 592 | { |
| 593 | struct stat statb; |
| 594 | |
| 595 | if (stat((char *)name, &statb)) |
| 596 | return -1; |
| 597 | return statb.st_mode; |
| 598 | } |
| 599 | |
| 600 | /* |
| 601 | * set file permission for 'name' to 'perm' |
| 602 | * |
| 603 | * return FAIL for failure, OK otherwise |
| 604 | */ |
| 605 | int |
| 606 | mch_setperm(name, perm) |
| 607 | char_u *name; |
| 608 | long perm; |
| 609 | { |
| 610 | return (chmod((char *)name, (mode_t)perm) == 0 ? OK : FAIL); |
| 611 | } |
| 612 | |
| 613 | /* |
| 614 | * Set hidden flag for "name". |
| 615 | */ |
| 616 | /* ARGSUSED */ |
| 617 | void |
| 618 | mch_hide(name) |
| 619 | char_u *name; |
| 620 | { |
| 621 | /* can't hide a file */ |
| 622 | } |
| 623 | |
| 624 | /* |
| 625 | * return TRUE if "name" is a directory |
| 626 | * return FALSE if "name" is not a directory |
| 627 | * return FALSE for error |
| 628 | */ |
| 629 | int |
| 630 | mch_isdir(name) |
| 631 | char_u *name; |
| 632 | { |
| 633 | if (xswi(OS_File, 17, name) & v_flag) |
| 634 | return FALSE; |
| 635 | if (r0 == 2 || r0 == 3) |
| 636 | return TRUE; /* Count image files as directories. */ |
| 637 | return FALSE; |
| 638 | } |
| 639 | |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 640 | /* |
| 641 | * Return 1 if "name" can be executed, 0 if not. |
| 642 | * Return -1 if unknown. Requires which to work. |
| 643 | */ |
| 644 | int |
| 645 | mch_can_exe(name) |
| 646 | char_u *name; |
| 647 | { |
| 648 | char_u *buf; |
| 649 | char_u *p; |
| 650 | int retval; |
| 651 | |
| 652 | buf = alloc((unsigned)STRLEN(name) + 7); |
| 653 | if (buf == NULL) |
| 654 | return -1; |
| 655 | sprintf((char *)buf, "which %s", name); |
Bram Moolenaar | c0197e2 | 2004-09-13 20:26:32 +0000 | [diff] [blame] | 656 | p = get_cmd_output(buf, NULL, SHELL_SILENT); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 657 | vim_free(buf); |
| 658 | if (p == NULL) |
| 659 | return -1; |
| 660 | /* result can be: "name: Command not found" */ |
| 661 | retval = (*p != NUL && strstr((char *)p, "not found") == NULL); |
| 662 | vim_free(p); |
| 663 | return retval; |
| 664 | } |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 665 | |
| 666 | /* |
| 667 | * Check what "name" is: |
| 668 | * NODE_NORMAL: file or directory (or doesn't exist) |
| 669 | * NODE_WRITABLE: writable device, socket, fifo, etc. |
| 670 | * NODE_OTHER: non-writable things |
| 671 | */ |
| 672 | int |
| 673 | mch_nodetype(name) |
| 674 | char_u *name; |
| 675 | { |
| 676 | /* TODO */ |
| 677 | return NODE_NORMAL; |
| 678 | } |
| 679 | |
| 680 | void |
| 681 | mch_early_init() |
| 682 | { |
| 683 | /* Turn off all the horrible filename munging in UnixLib. */ |
Bram Moolenaar | 741b07e | 2004-12-09 21:09:42 +0000 | [diff] [blame] | 684 | int __riscosify_control = __RISCOSIFY_NO_PROCESS; |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 685 | } |
| 686 | |
| 687 | void |
| 688 | mch_exit(r) |
| 689 | int r; |
| 690 | { |
| 691 | settmode(TMODE_COOK); |
| 692 | exiting = TRUE; |
| 693 | out_flush(); |
| 694 | ml_close_all(TRUE); /* remove all memfiles */ |
| 695 | |
| 696 | #ifdef FEAT_GUI |
| 697 | if (gui.in_use) |
| 698 | gui_exit(r); |
| 699 | #endif |
| 700 | swi(OS_NewLine); |
| 701 | if (old_escape_state != -1) |
| 702 | swi(OS_Byte, 229, old_escape_state, 0); |
| 703 | if (old_cursor_state != -1) |
| 704 | swi(OS_Byte, 4, old_cursor_state); |
| 705 | exit(r); |
| 706 | } |
| 707 | |
| 708 | void |
| 709 | mch_settmode(tmode) |
| 710 | int tmode; /* TMODE_RAW or TMODE_COOK */ |
| 711 | { |
| 712 | if (tmode == TMODE_COOK) |
| 713 | { |
| 714 | ro_line_mode = TRUE; |
| 715 | return; |
| 716 | } |
| 717 | |
| 718 | ro_line_mode = FALSE; |
| 719 | |
| 720 | if (term_console) |
| 721 | { |
| 722 | /* Block cursor. */ |
| 723 | swi(OS_WriteN, |
| 724 | "\027\000\012\000\000\000\000\000\000\000", |
| 725 | 10); |
| 726 | |
| 727 | /* Disable the standard cursor key actions. */ |
| 728 | swi(OS_Byte, 4, 1); |
| 729 | if (old_cursor_state == -1) |
| 730 | old_cursor_state = r1; |
| 731 | } |
| 732 | |
| 733 | /* Stop Escape from quitting Vim! */ |
| 734 | swi(OS_Byte, 229, 1, 0); |
| 735 | if (old_escape_state == -1) |
| 736 | old_escape_state = r1; |
| 737 | } |
| 738 | |
| 739 | /* |
| 740 | * set mouse clicks on or off (only works for xterms) |
| 741 | */ |
| 742 | void |
| 743 | mch_setmouse(on) |
| 744 | int on; |
| 745 | { |
| 746 | } |
| 747 | |
| 748 | /* |
| 749 | * set screen mode, always fails. |
| 750 | */ |
| 751 | /* ARGSUSED */ |
| 752 | int |
| 753 | mch_screenmode(arg) |
| 754 | char_u *arg; |
| 755 | { |
Bram Moolenaar | 741b07e | 2004-12-09 21:09:42 +0000 | [diff] [blame] | 756 | EMSG(_(e_screenmode)); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 757 | return FAIL; |
| 758 | } |
| 759 | |
| 760 | /* |
| 761 | * Try to get the current window size. |
| 762 | * Return OK when size could be determined, FAIL otherwise. |
| 763 | * Simply return results stored by mch_init() if we are the |
| 764 | * machine's console. If not, we don't know how big the screen is. |
| 765 | */ |
| 766 | int |
| 767 | mch_get_shellsize() |
| 768 | { |
| 769 | /* if size changed: screenalloc will allocate new screen buffers */ |
| 770 | return term_console ? OK : FAIL; |
| 771 | } |
| 772 | |
| 773 | /* |
| 774 | * Can't change the size. |
| 775 | * Assume the user knows what he's doing and use the new values. |
| 776 | */ |
| 777 | void |
| 778 | mch_set_shellsize() |
| 779 | { |
| 780 | /* Assume the user knows what he's doing and use the new values. */ |
| 781 | } |
| 782 | |
| 783 | /* |
| 784 | * Rows and/or Columns has changed. |
| 785 | */ |
| 786 | void |
| 787 | mch_new_shellsize() |
| 788 | { |
| 789 | /* Nothing to do. */ |
| 790 | } |
| 791 | |
| 792 | int |
| 793 | mch_call_shell(cmd, options) |
| 794 | char_u *cmd; |
| 795 | int options; /* SHELL_*, see vim.h */ |
| 796 | { |
| 797 | int retval; |
| 798 | int tmode = cur_tmode; |
| 799 | |
| 800 | if (cmd == NULL) |
| 801 | cmd = (char_u *) "GOS"; |
| 802 | |
| 803 | #ifdef FEAT_GUI |
| 804 | if (gui.in_use) |
| 805 | return gui_mch_call_shell(cmd, options); |
| 806 | #endif |
| 807 | if (options & SHELL_COOKED) |
| 808 | settmode(TMODE_COOK); /* set to normal mode */ |
| 809 | MSG_PUTS("\n"); |
| 810 | |
| 811 | /* I don't even want to think about what UnixLib must |
| 812 | * be doing to allow this to work... |
| 813 | */ |
| 814 | retval = system(cmd); |
| 815 | if (retval && !(options & SHELL_SILENT)) |
| 816 | EMSG(strerror(EOPSYS)); /* Doesn't seem to set errno? */ |
| 817 | |
| 818 | swi(OS_Byte, 229, 1, 0); /* Re-disable escape */ |
| 819 | if (tmode == TMODE_RAW) |
| 820 | settmode(TMODE_RAW); /* set to raw mode */ |
| 821 | return retval ? FAIL : OK; |
| 822 | } |
| 823 | |
| 824 | /* |
| 825 | * Check for Escape being pressed right now. |
| 826 | * [ different if !term_console? ] |
| 827 | */ |
| 828 | void |
| 829 | mch_breakcheck() |
| 830 | { |
| 831 | if (xswi(OS_Byte, 121, 0xf0) & v_flag) |
| 832 | return; |
| 833 | if (r1 == 0xff) |
| 834 | { |
| 835 | got_int = TRUE; |
| 836 | swi(OS_Byte, 15, 1); /* Flush input buffer */ |
| 837 | } |
| 838 | } |
| 839 | |
| 840 | /* |
| 841 | * Recursively expand one path component into all matching files and/or |
| 842 | * directories. |
| 843 | * "path" has backslashes before chars that are not to be expanded. |
| 844 | * Return the number of matches found. |
| 845 | */ |
| 846 | int |
| 847 | mch_expandpath(gap, path, flags) |
| 848 | garray_T *gap; /* Grow array for results. */ |
| 849 | char_u *path; |
| 850 | int flags; /* EW_* flags */ |
| 851 | { |
| 852 | int got; /* Number of matches. */ |
| 853 | char_u *pattern; |
| 854 | |
| 855 | /* Plan: |
| 856 | * |
| 857 | * 1) Get first part of path - no wildcards |
| 858 | * 2) Get next path element (wildcarded) |
| 859 | * 3) Get rest of path |
| 860 | * |
| 861 | * If (3) is nothing then only the leaf is wildcarded - add to gap |
| 862 | * Otherwise call recursively for each path in (2), passing (3) |
| 863 | * |
| 864 | * This is just the header function. |
| 865 | */ |
| 866 | |
| 867 | /* We must be able to modifiy path, so make a copy */ |
| 868 | pattern = vim_strsave(path); |
| 869 | if (pattern == NULL) |
| 870 | return 0; |
| 871 | got = expand_section(gap, (char_u *)"", pattern, flags); |
| 872 | vim_free(pattern); |
| 873 | return got; |
| 874 | } |
| 875 | |
| 876 | /* |
| 877 | * expand_section(gap, "$.Dir1.Dir2", "ABBA*.myleaf##") |
| 878 | * |
| 879 | * calls expand_section(gap, "$.Dir1.Dir2.ABBA_Gold", "myleaf##") |
| 880 | * and expand_section(gap, "$.Dir1.Dir2.ABBA_Live", "myleaf##") |
| 881 | * |
| 882 | * If rest is just a leaf then all matches are added to gap. |
| 883 | * |
| 884 | * Returns number of items added to gap. |
| 885 | */ |
| 886 | int |
| 887 | expand_section(gap, root, rest, flags) |
| 888 | garray_T *gap; |
| 889 | char_u *root; /* Non-wildcarded path to search */ |
| 890 | char_u *rest; /* Wildcarded remainder of path */ |
| 891 | int flags; /* Add dirs/files/missing objects. */ |
| 892 | { |
| 893 | static char_u buf[MAXPATHL]; /* Temporary buffer. */ |
| 894 | char_u dir[MAXPATHL]; |
| 895 | int start_element = -1; /* Start of wildcarded element */ |
| 896 | char_u c; |
| 897 | int i; |
| 898 | int got, dir_pos; |
| 899 | int buflen; /* Chars used in buf[] */ |
| 900 | int colon = 0; /* Dir ends in ':' */ |
| 901 | |
| 902 | buflen = strlen(root); |
| 903 | STRNCPY(buf, root, buflen); /* Copy root into buffer. */ |
| 904 | |
| 905 | /* |
| 906 | * Find end of nonwildcarded section. |
| 907 | * Count ':' as a path sep since Vim:Bug* is a valid pathname. |
| 908 | */ |
| 909 | |
| 910 | for (i = 0; c = rest[i]; i++) |
| 911 | { |
| 912 | if (c == PATHSEP) |
| 913 | { |
| 914 | start_element = i; |
| 915 | colon = 0; |
| 916 | } |
| 917 | if (c == ':') |
| 918 | { |
| 919 | start_element = i + 1; |
| 920 | colon = 1; |
| 921 | } |
| 922 | if (c == '#' || c == '*') |
| 923 | break; |
| 924 | } |
| 925 | if (c == 0) |
| 926 | start_element = i; |
| 927 | |
| 928 | /* |
| 929 | * start_element +> terminator for non-wildcarded section. |
| 930 | * Transfer this bit into buf. |
| 931 | */ |
| 932 | if (buflen + start_element + 4 >= MAXPATHL) |
| 933 | return 0; /* Buffer full */ |
| 934 | if (start_element >= 0) |
| 935 | { |
| 936 | if (*root && !colon) |
| 937 | buf[buflen++] = PATHSEP; |
| 938 | strncpy(buf + buflen, rest, start_element); |
| 939 | buflen += start_element; |
| 940 | } |
| 941 | buf[buflen] = 0; |
| 942 | |
| 943 | /* |
| 944 | * Did we reach the end of the string without hitting any wildcards? |
| 945 | */ |
| 946 | if (c == 0) |
| 947 | { |
| 948 | /* Yes - add combined path to grow array and return. */ |
| 949 | addfile(gap, buf, flags); |
| 950 | return 1; |
| 951 | } |
| 952 | |
| 953 | if (start_element < 0 || !colon) |
| 954 | start_element++; |
| 955 | rest += start_element; |
| 956 | |
| 957 | /* |
| 958 | * rest does contain wildcards if we get here. |
| 959 | * |
| 960 | * Now : have we reached the leaf names part yet? |
| 961 | * If so, add all matches (files and dirs) to gap. |
| 962 | * If not, get next path element and scan all matching directories. |
| 963 | */ |
| 964 | |
| 965 | start_element = -1; |
| 966 | for (i = 0; rest[i]; i++) |
| 967 | { |
| 968 | if (rest[i] == '.') |
| 969 | { |
| 970 | start_element = i; |
| 971 | rest[i] = 0; /* Break string here. */ |
| 972 | break; |
| 973 | } |
| 974 | } |
| 975 | |
| 976 | /* If start_element is -1 then we are matching leaf names */ |
| 977 | |
| 978 | r3 = 0; /* Number of objs read. */ |
| 979 | dir_pos = 0; /* Position through directory. */ |
| 980 | got = 0; /* Files added so far. */ |
| 981 | while (dir_pos != -1) |
| 982 | { |
| 983 | buf[buflen] = 0; |
| 984 | if (xswi(OS_GBPB, 9, |
| 985 | buf, /* Directory to scan. */ |
| 986 | buf + buflen + (1 - colon), /* Buffer for result. */ |
| 987 | 1, /* Number of objects to read. */ |
| 988 | dir_pos, /* Search position. */ |
| 989 | MAXPATHL - 2 - buflen, /* Size of result buffer. */ |
| 990 | rest) /* Wildcarded leafname. */ |
| 991 | & v_flag) |
| 992 | { |
| 993 | EMSG(r0 + 4); |
| 994 | r4 = -1; |
| 995 | } |
| 996 | dir_pos = r4; /* r4 corrupted by addfile() */ |
| 997 | if (r3 > 0) |
| 998 | { |
| 999 | char_u *path = buf; |
| 1000 | if (buflen == 0) |
| 1001 | path++; /* Don't do '.File' */ |
| 1002 | else if (!colon) |
| 1003 | buf[buflen] = '.'; /* Join path and leaf */ |
| 1004 | |
| 1005 | /* Path -> full path of object found */ |
| 1006 | if (start_element == -1) |
| 1007 | { |
| 1008 | addfile(gap, path, flags); |
| 1009 | got++; |
| 1010 | } |
| 1011 | else |
| 1012 | { |
| 1013 | /* Scan into subdirectories and images; ignore files */ |
| 1014 | swi(OS_File, 17, path); |
| 1015 | if (r0 == 2 || r0 == 3) |
| 1016 | got += expand_section(gap, |
| 1017 | path, |
| 1018 | rest + start_element + 1, |
| 1019 | flags); |
| 1020 | } |
| 1021 | } |
| 1022 | } |
| 1023 | |
| 1024 | /* Restore the dot if we removed it. */ |
| 1025 | if (start_element >= 0) |
| 1026 | rest[start_element] = '.'; |
| 1027 | return got; |
| 1028 | } |
| 1029 | |
| 1030 | /* |
| 1031 | * mch_expand_wildcards() - this code does wild-card pattern matching using |
| 1032 | * the shell. It isn't used under RISC OS. |
| 1033 | * |
| 1034 | * return OK for success, FAIL for error (you may lose some memory) and put |
| 1035 | * an error message in *file. |
| 1036 | * |
| 1037 | * num_pat is number of input patterns |
| 1038 | * pat is array of pointers to input patterns |
| 1039 | * num_file is pointer to number of matched file names |
| 1040 | * file is pointer to array of pointers to matched file names |
| 1041 | */ |
| 1042 | int |
| 1043 | mch_expand_wildcards(num_pat, pat, num_file, file, flags) |
| 1044 | int num_pat; |
| 1045 | char_u **pat; |
| 1046 | int *num_file; |
| 1047 | char_u ***file; |
| 1048 | int flags; /* EW_* flags */ |
| 1049 | { |
| 1050 | /* This doesn't get called unless SPECIAL_WILDCHAR is defined. */ |
| 1051 | return FAIL; |
| 1052 | } |
| 1053 | |
| 1054 | /* |
| 1055 | * Return TRUE if "p" contains wildcards which can be expanded by |
| 1056 | * mch_expandpath(). |
| 1057 | */ |
| 1058 | int |
| 1059 | mch_has_exp_wildcard(p) |
| 1060 | char_u *p; |
| 1061 | { |
| 1062 | if (vim_strpbrk((char_u *)"*#", p)) |
| 1063 | return TRUE; |
| 1064 | return FALSE; |
| 1065 | } |
| 1066 | |
| 1067 | /* Return TRUE if "p" contains wildcards. */ |
| 1068 | int |
| 1069 | mch_has_wildcard(p) |
| 1070 | char_u *p; |
| 1071 | { |
| 1072 | if (vim_strpbrk((char_u *)"*#`", p)) |
| 1073 | return TRUE; |
| 1074 | return FALSE; |
| 1075 | } |
| 1076 | |
| 1077 | int /* see Unix unlink(2) */ |
| 1078 | mch_remove(file) |
| 1079 | char_u *file; /* Name of file to delete. */ |
| 1080 | { |
| 1081 | if (xswi(OS_FSControl, 27, file, 0, 0) & v_flag) |
| 1082 | return EXIT_FAILURE; |
| 1083 | return EXIT_SUCCESS; |
| 1084 | } |
| 1085 | |
| 1086 | /* Try to make existing scripts work without modification. |
| 1087 | * Return a pointer to the new string (freed by caller), or NULL |
| 1088 | * |
| 1089 | * Two main cases: |
| 1090 | * - Absolute : $VIM/syntax/help.vim |
| 1091 | * - Relative : Adfs::4.$.!Vim.Resources.Syntax/help.vim |
| 1092 | */ |
| 1093 | char_u * |
| 1094 | mch_munge_fname(fname) |
| 1095 | char_u *fname; |
| 1096 | { |
| 1097 | char_u c; |
| 1098 | int len; |
| 1099 | char_u *retval; |
| 1100 | |
| 1101 | retval = fname = vim_strsave(fname); |
| 1102 | if (fname == NULL) |
| 1103 | return NULL; |
| 1104 | |
| 1105 | if (strncmp(fname, "$VIM/", 5) == 0) |
| 1106 | { |
| 1107 | strncpy(fname, "Vim:", 4); |
| 1108 | for (fname += 5; c = *fname; fname++) |
| 1109 | { |
| 1110 | if (c == '.') |
| 1111 | break; |
| 1112 | if (c == '/') |
| 1113 | fname[-1] = '.'; |
| 1114 | else |
| 1115 | fname[-1] = c; |
| 1116 | } |
| 1117 | fname[-1] = '\0'; |
| 1118 | } |
| 1119 | else |
| 1120 | { |
| 1121 | /* Check to see if the file exists without modification. */ |
| 1122 | if (xswi(OS_File, 17, fname) & v_flag) |
| 1123 | r0 == 0; /* Invalid filename? */ |
| 1124 | if (r0) |
| 1125 | return retval; |
| 1126 | |
| 1127 | len = strlen(fname); |
| 1128 | if (strcmp(fname + len - 4, ".vim") == 0) |
| 1129 | { |
| 1130 | fname[len - 4] = '\0'; |
| 1131 | for (; c = *fname; fname++) |
| 1132 | { |
| 1133 | if (c == '/') |
| 1134 | *fname = '.'; |
| 1135 | } |
| 1136 | } |
| 1137 | } |
| 1138 | return retval; |
| 1139 | } |
| 1140 | |
| 1141 | /* QuickFix reads munged names from the error file. |
| 1142 | * Correct them. |
| 1143 | */ |
| 1144 | int |
| 1145 | ro_buflist_add(old_name) |
| 1146 | char_u *old_name; /* Name of file found by quickfix */ |
| 1147 | { |
| 1148 | char_u *fname; |
| 1149 | char_u *leaf; /* Pointer to start of leaf in old_name */ |
| 1150 | char_u *ptr; |
| 1151 | char_u c; |
| 1152 | int retval; |
| 1153 | |
| 1154 | if (old_name == NULL) |
| 1155 | return buflist_add(NULL, 0); |
| 1156 | |
| 1157 | /* Copy the name so we can mess around with it. */ |
| 1158 | fname = vim_strsave(old_name); |
| 1159 | if (fname == NULL) |
| 1160 | /* Out of memory - can't modify name */ |
| 1161 | return buflist_add(old_name, 0); |
| 1162 | |
| 1163 | /* Change `dir/main.c' into `dir.c.main' */ |
| 1164 | leaf = fname; |
| 1165 | for (ptr = fname; c = *ptr; ptr++) |
| 1166 | { |
| 1167 | if (c == '/') |
| 1168 | { |
| 1169 | leaf = ptr + 1; |
| 1170 | *ptr = '.'; |
| 1171 | } |
| 1172 | else if (c == '.') |
| 1173 | break; |
| 1174 | } |
| 1175 | if (c == '.') |
| 1176 | { |
| 1177 | /* Change `main.c' into `c.main' |
| 1178 | * | | |
| 1179 | * leaf ptr |
| 1180 | */ |
| 1181 | ptr += old_name - fname; |
| 1182 | *ptr = '\0'; |
| 1183 | sprintf(leaf, |
| 1184 | "%s.%s", |
| 1185 | ptr + 1, |
| 1186 | leaf - fname + old_name); |
| 1187 | } |
| 1188 | |
| 1189 | retval = buflist_add(fname, 0); |
| 1190 | free(fname); |
| 1191 | return retval; |
| 1192 | } |
| 1193 | |
| 1194 | /* Change the current directory. |
| 1195 | * Strip trailing dots to make it easier to use with filename completion. |
| 1196 | * Return 0 for success, -1 for failure. |
| 1197 | */ |
| 1198 | int |
| 1199 | mch_chdir(dir) |
| 1200 | char_u *dir; |
| 1201 | { |
| 1202 | int length; |
| 1203 | int retval; |
| 1204 | char_u *new_dir; |
| 1205 | |
| 1206 | length = strlen(dir); |
| 1207 | if (dir[length - 1] != '.') |
| 1208 | return chdir(dir); /* No trailing dots - nothing to do. */ |
| 1209 | new_dir = vim_strsave(dir); |
| 1210 | if (new_dir == NULL) |
| 1211 | return chdir(dir); /* Can't allocate memory. */ |
| 1212 | |
| 1213 | while (new_dir[--length] == '.') |
| 1214 | new_dir[length] = '\0'; |
| 1215 | |
| 1216 | retval = chdir(new_dir); |
| 1217 | vim_free(new_dir); |
| 1218 | return retval; |
| 1219 | } |
| 1220 | |
| 1221 | /* Examine the named file, and set the 'osfiletype' option |
| 1222 | * (in curbuf) to the file's type. |
| 1223 | */ |
| 1224 | void |
| 1225 | mch_read_filetype(file) |
| 1226 | char_u *file; |
| 1227 | { |
| 1228 | int type; |
| 1229 | char_u type_string[9]; |
| 1230 | int i; |
| 1231 | |
| 1232 | if (xswi(OS_File, 23, file) & v_flag) |
| 1233 | type = 0xfff; /* Default to Text */ |
| 1234 | else |
| 1235 | type = r6; |
| 1236 | |
| 1237 | /* Type is the numerical value - see if we have a textual equivalent */ |
| 1238 | swi(OS_FSControl, 18, 0, type); |
| 1239 | ((int *) type_string)[0] = r2; |
| 1240 | ((int *) type_string)[1] = r3; |
| 1241 | type_string[8] = 0; |
| 1242 | for (i = 0; type_string[i] > ' '; i++) |
| 1243 | ; |
| 1244 | type_string[i] = 0; |
| 1245 | |
Bram Moolenaar | 5e3cb7e | 2006-02-27 23:58:35 +0000 | [diff] [blame] | 1246 | set_string_option_direct("osfiletype", -1, type_string, OPT_FREE, 0); |
Bram Moolenaar | 071d427 | 2004-06-13 20:20:40 +0000 | [diff] [blame] | 1247 | return; |
| 1248 | } |
| 1249 | |
| 1250 | void |
| 1251 | mch_set_filetype(file, type) |
| 1252 | char_u *file; |
| 1253 | char_u *type; |
| 1254 | { |
| 1255 | if (xswi(OS_FSControl, 31, type) & v_flag) |
| 1256 | { |
| 1257 | EMSG(_("E366: Invalid 'osfiletype' option - using Text")); |
| 1258 | r2 = 0xfff; |
| 1259 | } |
| 1260 | |
| 1261 | swi(OS_File, 18, file, r2); |
| 1262 | } |
| 1263 | |
| 1264 | /* Return TRUE if the file's type matches 'type' |
| 1265 | * RISC OS types always start with '&' |
| 1266 | */ |
| 1267 | int |
| 1268 | mch_check_filetype(fname, type) |
| 1269 | char_u *fname; |
| 1270 | char_u *type; |
| 1271 | { |
| 1272 | int value; |
| 1273 | char *end; |
| 1274 | |
| 1275 | if (*type != '&') |
| 1276 | return FALSE; |
| 1277 | |
| 1278 | value = strtol(type + 1, &end, 16); |
| 1279 | if (*end) |
| 1280 | return FALSE; /* Invalid type (report error?) */ |
| 1281 | |
| 1282 | if (xswi(OS_File, 23, fname) & v_flag) |
| 1283 | return FALSE; /* Invalid filename? */ |
| 1284 | |
| 1285 | return (r0 && r6 == value); |
| 1286 | } |