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/* 11 * os_amiga.c 12 * 13 * Amiga system-dependent routines. 14 */ 15 16#include "vim.h" 17 18#ifdef Window 19# undef Window /* Amiga has its own Window definition */ 20#endif 21 22#undef TRUE /* will be redefined by exec/types.h */ 23#undef FALSE 24 25#ifndef LATTICE 26# include <exec/types.h> 27# include <exec/exec.h> 28# include <libraries/dos.h> 29# include <intuition/intuition.h> 30#endif 31 32/* XXX These are included from os_amiga.h 33#include <proto/exec.h> 34#include <proto/dos.h> 35#include <proto/intuition.h> 36*/ 37 38#include <exec/memory.h> 39#include <libraries/dosextens.h> 40 41#include <dos/dostags.h> /* for 2.0 functions */ 42#include <dos/dosasl.h> 43 44/* From version 4 of AmigaOS, several system structures must be allocated 45 * and freed using system functions. "struct AnchorPath" is one. 46 */ 47#ifdef __amigaos4__ 48# include <dos/anchorpath.h> 49# define free_fib(x) FreeDosObject(DOS_FIB, x) 50#else 51# define free_fib(x) vim_free(fib) 52#endif 53 54#if defined(LATTICE) && !defined(SASC) && defined(FEAT_ARP) 55# include <libraries/arp_pragmas.h> 56#endif 57 58/* 59 * At this point TRUE and FALSE are defined as 1L and 0L, but we want 1 and 0. 60 */ 61#undef TRUE 62#define TRUE (1) 63#undef FALSE 64#define FALSE (0) 65 66#ifdef __amigaos4__ 67# define dos_packet(a, b, c) DoPkt(a, b, c, 0, 0, 0, 0) 68#elif !defined(AZTEC_C) && !defined(__AROS__) 69static long dos_packet __ARGS((struct MsgPort *, long, long)); 70#endif 71static int lock2name __ARGS((BPTR lock, char_u *buf, long len)); 72static void out_num __ARGS((long n)); 73static struct FileInfoBlock *get_fib __ARGS((char_u *)); 74static int sortcmp __ARGS((const void *a, const void *b)); 75 76static BPTR raw_in = (BPTR)NULL; 77static BPTR raw_out = (BPTR)NULL; 78static int close_win = FALSE; /* set if Vim opened the window */ 79 80#ifndef __amigaos4__ /* Use autoopen for AmigaOS4 */ 81struct IntuitionBase *IntuitionBase = NULL; 82#endif 83#ifdef FEAT_ARP 84struct ArpBase *ArpBase = NULL; 85#endif 86 87static struct Window *wb_window; 88static char_u *oldwindowtitle = NULL; 89 90#ifdef FEAT_ARP 91int dos2 = FALSE; /* Amiga DOS 2.0x or higher */ 92#endif 93int size_set = FALSE; /* set to TRUE if window size was set */ 94 95 void 96win_resize_on() 97{ 98 OUT_STR_NF("\033[12{"); 99} 100 101 void 102win_resize_off() 103{ 104 OUT_STR_NF("\033[12}"); 105} 106 107 void 108mch_write(p, len) 109 char_u *p; 110 int len; 111{ 112 Write(raw_out, (char *)p, (long)len); 113} 114 115/* 116 * mch_inchar(): low level input funcion. 117 * Get a characters from the keyboard. 118 * If time == 0 do not wait for characters. 119 * If time == n wait a short time for characters. 120 * If time == -1 wait forever for characters. 121 * 122 * Return number of characters read. 123 */ 124 int 125mch_inchar(buf, maxlen, time, tb_change_cnt) 126 char_u *buf; 127 int maxlen; 128 long time; /* milli seconds */ 129 int tb_change_cnt; 130{ 131 int len; 132 long utime; 133 134 if (time >= 0) 135 { 136 if (time == 0) 137 utime = 100L; /* time = 0 causes problems in DOS 1.2 */ 138 else 139 utime = time * 1000L; /* convert from milli to micro secs */ 140 if (WaitForChar(raw_in, utime) == 0) /* no character available */ 141 return 0; 142 } 143 else /* time == -1 */ 144 { 145 /* 146 * If there is no character available within 2 seconds (default) 147 * write the autoscript file to disk. Or cause the CursorHold event 148 * to be triggered. 149 */ 150 if (WaitForChar(raw_in, p_ut * 1000L) == 0) 151 { 152#ifdef FEAT_AUTOCMD 153 if (trigger_cursorhold() && maxlen >= 3) 154 { 155 buf[0] = K_SPECIAL; 156 buf[1] = KS_EXTRA; 157 buf[2] = (int)KE_CURSORHOLD; 158 return 3; 159 } 160#endif 161 before_blocking(); 162 } 163 } 164 165 for (;;) /* repeat until we got a character */ 166 { 167# ifdef FEAT_MBYTE 168 len = Read(raw_in, (char *)buf, (long)maxlen / input_conv.vc_factor); 169# else 170 len = Read(raw_in, (char *)buf, (long)maxlen); 171# endif 172 if (len > 0) 173 { 174#ifdef FEAT_MBYTE 175 /* Convert from 'termencoding' to 'encoding'. */ 176 if (input_conv.vc_type != CONV_NONE) 177 len = convert_input(buf, len, maxlen); 178#endif 179 return len; 180 } 181 } 182} 183 184/* 185 * return non-zero if a character is available 186 */ 187 int 188mch_char_avail() 189{ 190 return (WaitForChar(raw_in, 100L) != 0); 191} 192 193/* 194 * Return amount of memory still available. 195 */ 196 long_u 197mch_avail_mem(special) 198 int special; 199{ 200#ifdef __amigaos4__ 201 return (long_u)AvailMem(MEMF_ANY); 202#else 203 return (long_u)AvailMem(special ? (long)MEMF_CHIP : (long)MEMF_ANY); 204#endif 205} 206 207/* 208 * Waits a specified amount of time, or until input arrives if 209 * ignoreinput is FALSE. 210 */ 211 void 212mch_delay(msec, ignoreinput) 213 long msec; 214 int ignoreinput; 215{ 216#ifndef LATTICE /* SAS declares void Delay(ULONG) */ 217 void Delay __ARGS((long)); 218#endif 219 220 if (msec > 0) 221 { 222 if (ignoreinput) 223 Delay(msec / 20L); /* Delay works with 20 msec intervals */ 224 else 225 WaitForChar(raw_in, msec * 1000L); 226 } 227} 228 229/* 230 * We have no job control, fake it by starting a new shell. 231 */ 232 void 233mch_suspend() 234{ 235 suspend_shell(); 236} 237 238#ifndef DOS_LIBRARY 239# define DOS_LIBRARY ((UBYTE *)"dos.library") 240#endif 241 242 void 243mch_init() 244{ 245 static char intlibname[] = "intuition.library"; 246 247#ifdef AZTEC_C 248 Enable_Abort = 0; /* disallow vim to be aborted */ 249#endif 250 Columns = 80; 251 Rows = 24; 252 253 /* 254 * Set input and output channels, unless we have opened our own window 255 */ 256 if (raw_in == (BPTR)NULL) 257 { 258 raw_in = Input(); 259 raw_out = Output(); 260 /* 261 * If Input() is not interactive, then Output() will be (because of 262 * check in mch_check_win()). Used for "Vim -". 263 * Also check the other way around, for "Vim -h | more". 264 */ 265 if (!IsInteractive(raw_in)) 266 raw_in = raw_out; 267 else if (!IsInteractive(raw_out)) 268 raw_out = raw_in; 269 } 270 271 out_flush(); 272 273 wb_window = NULL; 274#ifndef __amigaos4__ 275 if ((IntuitionBase = (struct IntuitionBase *) 276 OpenLibrary((UBYTE *)intlibname, 0L)) == NULL) 277 { 278 mch_errmsg(_("cannot open ")); 279 mch_errmsg(intlibname); 280 mch_errmsg("!?\n"); 281 mch_exit(3); 282 } 283#endif 284} 285 286#include <workbench/startup.h> 287 288/* 289 * Check_win checks whether we have an interactive window. 290 * If not, a new window is opened with the newcli command. 291 * If we would open a window ourselves, the :sh and :! commands would not 292 * work properly (Why? probably because we are then running in a background 293 * CLI). This also is the best way to assure proper working in a next 294 * Workbench release. 295 * 296 * For the -f option (foreground mode) we open our own window and disable :sh. 297 * Otherwise the calling program would never know when editing is finished. 298 */ 299#define BUF2SIZE 320 /* length of buffer for argument with complete path */ 300 301 int 302mch_check_win(argc, argv) 303 int argc; 304 char **argv; 305{ 306 int i; 307 BPTR nilfh, fh; 308 char_u buf1[24]; 309 char_u buf2[BUF2SIZE]; 310 static char_u *(constrings[3]) = {(char_u *)"con:0/0/662/210/", 311 (char_u *)"con:0/0/640/200/", 312 (char_u *)"con:0/0/320/200/"}; 313 static char_u *winerr = (char_u *)N_("VIM: Can't open window!\n"); 314 struct WBArg *argp; 315 int ac; 316 char *av; 317 char_u *device = NULL; 318 int exitval = 4; 319#ifndef __amigaos4__ 320 struct Library *DosBase; 321#endif 322 int usewin = FALSE; 323 324/* 325 * check if we are running under DOS 2.0x or higher 326 */ 327#ifndef __amigaos4__ 328 DosBase = OpenLibrary(DOS_LIBRARY, 37L); 329 if (DosBase != NULL) 330 /* if (((struct Library *)DOSBase)->lib_Version >= 37) */ 331 { 332 CloseLibrary(DosBase); 333# ifdef FEAT_ARP 334 dos2 = TRUE; 335# endif 336 } 337 else /* without arp functions we NEED 2.0 */ 338 { 339# ifndef FEAT_ARP 340 mch_errmsg(_("Need Amigados version 2.04 or later\n")); 341 exit(3); 342# else 343 /* need arp functions for dos 1.x */ 344 if (!(ArpBase = (struct ArpBase *) OpenLibrary((UBYTE *)ArpName, ArpVersion))) 345 { 346 fprintf(stderr, _("Need %s version %ld\n"), ArpName, ArpVersion); 347 exit(3); 348 } 349# endif 350 } 351#endif /* __amigaos4__ */ 352 353 /* 354 * scan argv[] for the "-f" and "-d" arguments 355 */ 356 for (i = 1; i < argc; ++i) 357 if (argv[i][0] == '-') 358 { 359 switch (argv[i][1]) 360 { 361 case 'f': 362 usewin = TRUE; 363 break; 364 365 case 'd': 366 if (i < argc - 1 367#ifdef FEAT_DIFF 368 /* require using "-dev", "-d" means diff mode */ 369 && argv[i][2] == 'e' && argv[i][3] == 'v' 370#endif 371 ) 372 device = (char_u *)argv[i + 1]; 373 break; 374 } 375 } 376 377/* 378 * If we were not started from workbench, do not have a "-d" or "-dev" 379 * argument and we have been started with an interactive window, use that 380 * window. 381 */ 382 if (argc != 0 383 && device == NULL 384 && (IsInteractive(Input()) || IsInteractive(Output()))) 385 return OK; 386 387/* 388 * When given the "-f" argument, we open our own window. We can't use the 389 * newcli trick below, because the calling program (mail, rn, etc.) would not 390 * know when we are finished. 391 */ 392 if (usewin) 393 { 394 /* 395 * Try to open a window. First try the specified device. 396 * Then try a 24 line 80 column window. 397 * If that fails, try two smaller ones. 398 */ 399 for (i = -1; i < 3; ++i) 400 { 401 if (i >= 0) 402 device = constrings[i]; 403 if (device != NULL && (raw_in = Open((UBYTE *)device, 404 (long)MODE_NEWFILE)) != (BPTR)NULL) 405 break; 406 } 407 if (raw_in == (BPTR)NULL) /* all three failed */ 408 { 409 mch_errmsg(_(winerr)); 410 goto exit; 411 } 412 raw_out = raw_in; 413 close_win = TRUE; 414 return OK; 415 } 416 417 if ((nilfh = Open((UBYTE *)"NIL:", (long)MODE_NEWFILE)) == (BPTR)NULL) 418 { 419 mch_errmsg(_("Cannot open NIL:\n")); 420 goto exit; 421 } 422 423 /* 424 * Make a unique name for the temp file (which we will not delete!). 425 * Use a pointer on the stack (nobody else will be using it). 426 * Under AmigaOS4, this assumption might change in the future, so 427 * we use a pointer to the current task instead. This should be a 428 * shared structure and thus globally unique. 429 */ 430#ifdef __amigaos4__ 431 sprintf((char *)buf1, "t:nc%p", FindTask(0)); 432#else 433 sprintf((char *)buf1, "t:nc%ld", (long)buf1); 434#endif 435 if ((fh = Open((UBYTE *)buf1, (long)MODE_NEWFILE)) == (BPTR)NULL) 436 { 437 mch_errmsg(_("Cannot create ")); 438 mch_errmsg((char *)buf1); 439 mch_errmsg("\n"); 440 goto exit; 441 } 442 /* 443 * Write the command into the file, put quotes around the arguments that 444 * have a space in them. 445 */ 446 if (argc == 0) /* run from workbench */ 447 ac = ((struct WBStartup *)argv)->sm_NumArgs; 448 else 449 ac = argc; 450 for (i = 0; i < ac; ++i) 451 { 452 if (argc == 0) 453 { 454 *buf2 = NUL; 455 argp = &(((struct WBStartup *)argv)->sm_ArgList[i]); 456 if (argp->wa_Lock) 457 (void)lock2name(argp->wa_Lock, buf2, (long)(BUF2SIZE - 1)); 458#ifdef FEAT_ARP 459 if (dos2) /* use 2.0 function */ 460#endif 461 AddPart((UBYTE *)buf2, (UBYTE *)argp->wa_Name, (long)(BUF2SIZE - 1)); 462#ifdef FEAT_ARP 463 else /* use arp function */ 464 TackOn((char *)buf2, argp->wa_Name); 465#endif 466 av = (char *)buf2; 467 } 468 else 469 av = argv[i]; 470 471 /* skip '-d' or "-dev" option */ 472 if (av[0] == '-' && av[1] == 'd' 473#ifdef FEAT_DIFF 474 && av[2] == 'e' && av[3] == 'v' 475#endif 476 ) 477 { 478 ++i; 479 continue; 480 } 481 if (vim_strchr((char_u *)av, ' ')) 482 Write(fh, "\"", 1L); 483 Write(fh, av, (long)strlen(av)); 484 if (vim_strchr((char_u *)av, ' ')) 485 Write(fh, "\"", 1L); 486 Write(fh, " ", 1L); 487 } 488 Write(fh, "\nendcli\n", 8L); 489 Close(fh); 490 491/* 492 * Try to open a new cli in a window. If "-d" or "-dev" argument was given try 493 * to open the specified device. Then try a 24 line 80 column window. If that 494 * fails, try two smaller ones. 495 */ 496 for (i = -1; i < 3; ++i) 497 { 498 if (i >= 0) 499 device = constrings[i]; 500 else if (device == NULL) 501 continue; 502 sprintf((char *)buf2, "newcli <nil: >nil: %s from %s", (char *)device, (char *)buf1); 503#ifdef FEAT_ARP 504 if (dos2) 505 { 506#endif 507 if (!SystemTags((UBYTE *)buf2, SYS_UserShell, TRUE, TAG_DONE)) 508 break; 509#ifdef FEAT_ARP 510 } 511 else 512 { 513 if (Execute((UBYTE *)buf2, nilfh, nilfh)) 514 break; 515 } 516#endif 517 } 518 if (i == 3) /* all three failed */ 519 { 520 DeleteFile((UBYTE *)buf1); 521 mch_errmsg(_(winerr)); 522 goto exit; 523 } 524 exitval = 0; /* The Execute succeeded: exit this program */ 525 526exit: 527#ifdef FEAT_ARP 528 if (ArpBase) 529 CloseLibrary((struct Library *) ArpBase); 530#endif 531 exit(exitval); 532 /* NOTREACHED */ 533 return FAIL; 534} 535 536/* 537 * Return TRUE if the input comes from a terminal, FALSE otherwise. 538 * We fake there is a window, because we can always open one! 539 */ 540 int 541mch_input_isatty() 542{ 543 return TRUE; 544} 545 546/* 547 * fname_case(): Set the case of the file name, if it already exists. 548 * This will cause the file name to remain exactly the same 549 * if the file system ignores, but preserves case. 550 */ 551/*ARGSUSED*/ 552 void 553fname_case(name, len) 554 char_u *name; 555 int len; /* buffer size, ignored here */ 556{ 557 struct FileInfoBlock *fib; 558 size_t flen; 559 560 fib = get_fib(name); 561 if (fib != NULL) 562 { 563 flen = STRLEN(name); 564 /* TODO: Check if this fix applies to AmigaOS < 4 too.*/ 565#ifdef __amigaos4__ 566 if (fib->fib_DirEntryType == ST_ROOT) 567 strcat(fib->fib_FileName, ":"); 568#endif 569 if (flen == strlen(fib->fib_FileName)) /* safety check */ 570 mch_memmove(name, fib->fib_FileName, flen); 571 free_fib(fib); 572 } 573} 574 575/* 576 * Get the FileInfoBlock for file "fname" 577 * The returned structure has to be free()d. 578 * Returns NULL on error. 579 */ 580 static struct FileInfoBlock * 581get_fib(fname) 582 char_u *fname; 583{ 584 BPTR flock; 585 struct FileInfoBlock *fib; 586 587 if (fname == NULL) /* safety check */ 588 return NULL; 589#ifdef __amigaos4__ 590 fib = AllocDosObject(DOS_FIB,0); 591#else 592 fib = (struct FileInfoBlock *)alloc(sizeof(struct FileInfoBlock)); 593#endif 594 if (fib != NULL) 595 { 596 flock = Lock((UBYTE *)fname, (long)ACCESS_READ); 597 if (flock == (BPTR)NULL || !Examine(flock, fib)) 598 { 599 free_fib(fib); /* in case of an error the memory is freed here */ 600 fib = NULL; 601 } 602 if (flock) 603 UnLock(flock); 604 } 605 return fib; 606} 607 608#ifdef FEAT_TITLE 609/* 610 * set the title of our window 611 * icon name is not set 612 */ 613 void 614mch_settitle(title, icon) 615 char_u *title; 616 char_u *icon; 617{ 618 if (wb_window != NULL && title != NULL) 619 SetWindowTitles(wb_window, (UBYTE *)title, (UBYTE *)-1L); 620} 621 622/* 623 * Restore the window/icon title. 624 * which is one of: 625 * 1 Just restore title 626 * 2 Just restore icon (which we don't have) 627 * 3 Restore title and icon (which we don't have) 628 */ 629 void 630mch_restore_title(which) 631 int which; 632{ 633 if (which & 1) 634 mch_settitle(oldwindowtitle, NULL); 635} 636 637 int 638mch_can_restore_title() 639{ 640 return (wb_window != NULL); 641} 642 643 int 644mch_can_restore_icon() 645{ 646 return FALSE; 647} 648#endif 649 650/* 651 * Insert user name in s[len]. 652 */ 653 int 654mch_get_user_name(s, len) 655 char_u *s; 656 int len; 657{ 658 /* TODO: Implement this. */ 659 *s = NUL; 660 return FAIL; 661} 662 663/* 664 * Insert host name is s[len]. 665 */ 666 void 667mch_get_host_name(s, len) 668 char_u *s; 669 int len; 670{ 671#if defined(__amigaos4__) && defined(__CLIB2__) 672 gethostname(s, len); 673#else 674 vim_strncpy(s, "Amiga", len - 1); 675#endif 676} 677 678/* 679 * return process ID 680 */ 681 long 682mch_get_pid() 683{ 684#ifdef __amigaos4__ 685 /* This is as close to a pid as we can come. We could use CLI numbers also, 686 * but then we would have two different types of process identifiers. 687 */ 688 return((long)FindTask(0)); 689#else 690 return (long)0; 691#endif 692} 693 694/* 695 * Get name of current directory into buffer 'buf' of length 'len' bytes. 696 * Return OK for success, FAIL for failure. 697 */ 698 int 699mch_dirname(buf, len) 700 char_u *buf; 701 int len; 702{ 703 return mch_FullName((char_u *)"", buf, len, FALSE); 704} 705 706/* 707 * get absolute file name into buffer 'buf' of length 'len' bytes 708 * 709 * return FAIL for failure, OK otherwise 710 */ 711 int 712mch_FullName(fname, buf, len, force) 713 char_u *fname, *buf; 714 int len; 715 int force; 716{ 717 BPTR l; 718 int retval = FAIL; 719 int i; 720 721 /* Lock the file. If it exists, we can get the exact name. */ 722 if ((l = Lock((UBYTE *)fname, (long)ACCESS_READ)) != (BPTR)0) 723 { 724 retval = lock2name(l, buf, (long)len - 1); 725 UnLock(l); 726 } 727 else if (force || !mch_isFullName(fname)) /* not a full path yet */ 728 { 729 /* 730 * If the file cannot be locked (doesn't exist), try to lock the 731 * current directory and concatenate the file name. 732 */ 733 if ((l = Lock((UBYTE *)"", (long)ACCESS_READ)) != (BPTR)NULL) 734 { 735 retval = lock2name(l, buf, (long)len); 736 UnLock(l); 737 if (retval == OK) 738 { 739 i = STRLEN(buf); 740 /* Concatenate the fname to the directory. Don't add a slash 741 * if fname is empty, but do change "" to "/". */ 742 if (i == 0 || *fname != NUL) 743 { 744 if (i < len - 1 && (i == 0 || buf[i - 1] != ':')) 745 buf[i++] = '/'; 746 vim_strncpy(buf + i, fname, len - i - 1); 747 } 748 } 749 } 750 } 751 if (*buf == 0 || *buf == ':') 752 retval = FAIL; /* something failed; use the file name */ 753 return retval; 754} 755 756/* 757 * Return TRUE if "fname" does not depend on the current directory. 758 */ 759 int 760mch_isFullName(fname) 761 char_u *fname; 762{ 763 return (vim_strchr(fname, ':') != NULL && *fname != ':'); 764} 765 766/* 767 * Get the full file name from a lock. Use 2.0 function if possible, because 768 * the arp function has more restrictions on the path length. 769 * 770 * return FAIL for failure, OK otherwise 771 */ 772 static int 773lock2name(lock, buf, len) 774 BPTR lock; 775 char_u *buf; 776 long len; 777{ 778#ifdef FEAT_ARP 779 if (dos2) /* use 2.0 function */ 780#endif 781 return ((int)NameFromLock(lock, (UBYTE *)buf, len) ? OK : FAIL); 782#ifdef FEAT_ARP 783 else /* use arp function */ 784 return ((int)PathName(lock, (char *)buf, (long)(len/32)) ? OK : FAIL); 785#endif 786} 787 788/* 789 * get file permissions for 'name' 790 * Returns -1 when it doesn't exist. 791 */ 792 long 793mch_getperm(name) 794 char_u *name; 795{ 796 struct FileInfoBlock *fib; 797 long retval = -1; 798 799 fib = get_fib(name); 800 if (fib != NULL) 801 { 802 retval = fib->fib_Protection; 803 free_fib(fib); 804 } 805 return retval; 806} 807 808/* 809 * set file permission for 'name' to 'perm' 810 * 811 * return FAIL for failure, OK otherwise 812 */ 813 int 814mch_setperm(name, perm) 815 char_u *name; 816 long perm; 817{ 818 perm &= ~FIBF_ARCHIVE; /* reset archived bit */ 819 return (SetProtection((UBYTE *)name, (long)perm) ? OK : FAIL); 820} 821 822/* 823 * Set hidden flag for "name". 824 */ 825 void 826mch_hide(name) 827 char_u *name; 828{ 829 /* can't hide a file */ 830} 831 832/* 833 * return FALSE if "name" is not a directory 834 * return TRUE if "name" is a directory. 835 * return FALSE for error. 836 */ 837 int 838mch_isdir(name) 839 char_u *name; 840{ 841 struct FileInfoBlock *fib; 842 int retval = FALSE; 843 844 fib = get_fib(name); 845 if (fib != NULL) 846 { 847#ifdef __amigaos4__ 848 retval = (FIB_IS_DRAWER(fib)) ? TRUE : FALSE; 849#else 850 retval = ((fib->fib_DirEntryType >= 0) ? TRUE : FALSE); 851#endif 852 free_fib(fib); 853 } 854 return retval; 855} 856 857/* 858 * Create directory "name". 859 */ 860 int 861mch_mkdir(name) 862 char_u *name; 863{ 864 BPTR lock; 865 866 lock = CreateDir(name); 867 if (lock != NULL) 868 { 869 UnLock(lock); 870 return 0; 871 } 872 return -1; 873} 874 875/* 876 * Return 1 if "name" can be executed, 0 if not. 877 * Return -1 if unknown. 878 */ 879 int 880mch_can_exe(name) 881 char_u *name; 882{ 883 /* TODO */ 884 return -1; 885} 886 887/* 888 * Check what "name" is: 889 * NODE_NORMAL: file or directory (or doesn't exist) 890 * NODE_WRITABLE: writable device, socket, fifo, etc. 891 * NODE_OTHER: non-writable things 892 */ 893 int 894mch_nodetype(name) 895 char_u *name; 896{ 897 /* TODO */ 898 return NODE_NORMAL; 899} 900 901 void 902mch_early_init() 903{ 904} 905 906/* 907 * Careful: mch_exit() may be called before mch_init()! 908 */ 909 void 910mch_exit(r) 911 int r; 912{ 913 if (raw_in) /* put terminal in 'normal' mode */ 914 { 915 settmode(TMODE_COOK); 916 stoptermcap(); 917 } 918 out_char('\n'); 919 if (raw_out) 920 { 921 if (term_console) 922 { 923 win_resize_off(); /* window resize events de-activated */ 924 if (size_set) 925 OUT_STR("\233t\233u"); /* reset window size (CSI t CSI u) */ 926 } 927 out_flush(); 928 } 929 930#ifdef FEAT_TITLE 931 mch_restore_title(3); /* restore window title */ 932#endif 933 934 ml_close_all(TRUE); /* remove all memfiles */ 935 936#ifdef FEAT_ARP 937 if (ArpBase) 938 CloseLibrary((struct Library *) ArpBase); 939#endif 940 if (close_win) 941 Close(raw_in); 942 if (r) 943 printf(_("Vim exiting with %d\n"), r); /* somehow this makes :cq work!? */ 944 exit(r); 945} 946 947/* 948 * This is a routine for setting a given stream to raw or cooked mode on the 949 * Amiga . This is useful when you are using Lattice C to produce programs 950 * that want to read single characters with the "getch()" or "fgetc" call. 951 * 952 * Written : 18-Jun-87 By Chuck McManis. 953 */ 954 955#define MP(xx) ((struct MsgPort *)((struct FileHandle *) (BADDR(xx)))->fh_Type) 956 957/* 958 * Function mch_settmode() - Convert the specified file pointer to 'raw' or 959 * 'cooked' mode. This only works on TTY's. 960 * 961 * Raw: keeps DOS from translating keys for you, also (BIG WIN) it means 962 * getch() will return immediately rather than wait for a return. You 963 * lose editing features though. 964 * 965 * Cooked: This function returns the designate file pointer to it's normal, 966 * wait for a <CR> mode. This is exactly like raw() except that 967 * it sends a 0 to the console to make it back into a CON: from a RAW: 968 */ 969 void 970mch_settmode(tmode) 971 int tmode; 972{ 973#if defined(__AROS__) || defined(__amigaos4__) 974 if (!SetMode(raw_in, tmode == TMODE_RAW ? 1 : 0)) 975#else 976 if (dos_packet(MP(raw_in), (long)ACTION_SCREEN_MODE, 977 tmode == TMODE_RAW ? -1L : 0L) == 0) 978#endif 979 mch_errmsg(_("cannot change console mode ?!\n")); 980} 981 982/* 983 * set screen mode, always fails. 984 */ 985 int 986mch_screenmode(arg) 987 char_u *arg; 988{ 989 EMSG(_(e_screenmode)); 990 return FAIL; 991} 992 993/* 994 * Code for this routine came from the following : 995 * 996 * ConPackets.c - C. Scheppner, A. Finkel, P. Lindsay CBM 997 * DOS packet example 998 * Requires 1.2 999 * 1000 * Found on Fish Disk 56. 1001 * 1002 * Heavely modified by mool. 1003 */ 1004 1005#include <devices/conunit.h> 1006 1007/* 1008 * try to get the real window size 1009 * return FAIL for failure, OK otherwise 1010 */ 1011 int 1012mch_get_shellsize() 1013{ 1014 struct ConUnit *conUnit; 1015#ifndef __amigaos4__ 1016 char id_a[sizeof(struct InfoData) + 3]; 1017#endif 1018 struct InfoData *id=0; 1019 1020 if (!term_console) /* not an amiga window */ 1021 goto out; 1022 1023 /* insure longword alignment */ 1024#ifdef __amigaos4__ 1025 if(!(id = AllocDosObject(DOS_INFODATA, 0))) 1026 goto out; 1027#else 1028 id = (struct InfoData *)(((long)id_a + 3L) & ~3L); 1029#endif 1030 1031 /* 1032 * Should make console aware of real window size, not the one we set. 1033 * Unfortunately, under DOS 2.0x this redraws the window and it 1034 * is rarely needed, so we skip it now, unless we changed the size. 1035 */ 1036 if (size_set) 1037 OUT_STR("\233t\233u"); /* CSI t CSI u */ 1038 out_flush(); 1039 1040#ifdef __AROS__ 1041 if (!Info(raw_out, id) 1042 || (wb_window = (struct Window *) id->id_VolumeNode) == NULL) 1043#else 1044 if (dos_packet(MP(raw_out), (long)ACTION_DISK_INFO, ((ULONG) id) >> 2) == 0 1045 || (wb_window = (struct Window *)id->id_VolumeNode) == NULL) 1046#endif 1047 { 1048 /* it's not an amiga window, maybe aux device */ 1049 /* terminal type should be set */ 1050 term_console = FALSE; 1051 goto out; 1052 } 1053 if (oldwindowtitle == NULL) 1054 oldwindowtitle = (char_u *)wb_window->Title; 1055 if (id->id_InUse == (BPTR)NULL) 1056 { 1057 mch_errmsg(_("mch_get_shellsize: not a console??\n")); 1058 return FAIL; 1059 } 1060 conUnit = (struct ConUnit *) ((struct IOStdReq *) id->id_InUse)->io_Unit; 1061 1062 /* get window size */ 1063 Rows = conUnit->cu_YMax + 1; 1064 Columns = conUnit->cu_XMax + 1; 1065 if (Rows < 0 || Rows > 200) /* cannot be an amiga window */ 1066 { 1067 Columns = 80; 1068 Rows = 24; 1069 term_console = FALSE; 1070 return FAIL; 1071 } 1072 1073 return OK; 1074out: 1075#ifdef __amigaos4__ 1076 FreeDosObject(DOS_INFODATA, id); /* Safe to pass NULL */ 1077#endif 1078 1079 return FAIL; 1080} 1081 1082/* 1083 * Try to set the real window size to Rows and Columns. 1084 */ 1085 void 1086mch_set_shellsize() 1087{ 1088 if (term_console) 1089 { 1090 size_set = TRUE; 1091 out_char(CSI); 1092 out_num((long)Rows); 1093 out_char('t'); 1094 out_char(CSI); 1095 out_num((long)Columns); 1096 out_char('u'); 1097 out_flush(); 1098 } 1099} 1100 1101/* 1102 * Rows and/or Columns has changed. 1103 */ 1104 void 1105mch_new_shellsize() 1106{ 1107 /* Nothing to do. */ 1108} 1109 1110/* 1111 * out_num - output a (big) number fast 1112 */ 1113 static void 1114out_num(n) 1115 long n; 1116{ 1117 OUT_STR_NF(tltoa((unsigned long)n)); 1118} 1119 1120#if !defined(AZTEC_C) && !defined(__AROS__) && !defined(__amigaos4__) 1121/* 1122 * Sendpacket.c 1123 * 1124 * An invaluable addition to your Amiga.lib file. This code sends a packet to 1125 * the given message port. This makes working around DOS lots easier. 1126 * 1127 * Note, I didn't write this, those wonderful folks at CBM did. I do suggest 1128 * however that you may wish to add it to Amiga.Lib, to do so, compile it and 1129 * say 'oml lib:amiga.lib -r sendpacket.o' 1130 */ 1131 1132/* #include <proto/exec.h> */ 1133/* #include <proto/dos.h> */ 1134#include <exec/memory.h> 1135 1136/* 1137 * Function - dos_packet written by Phil Lindsay, Carolyn Scheppner, and Andy 1138 * Finkel. This function will send a packet of the given type to the Message 1139 * Port supplied. 1140 */ 1141 1142 static long 1143dos_packet(pid, action, arg) 1144 struct MsgPort *pid; /* process identifier ... (handlers message port) */ 1145 long action, /* packet type ... (what you want handler to do) */ 1146 arg; /* single argument */ 1147{ 1148# ifdef FEAT_ARP 1149 struct MsgPort *replyport; 1150 struct StandardPacket *packet; 1151 long res1; 1152 1153 if (dos2) 1154# endif 1155 return DoPkt(pid, action, arg, 0L, 0L, 0L, 0L); /* use 2.0 function */ 1156# ifdef FEAT_ARP 1157 1158 replyport = (struct MsgPort *) CreatePort(NULL, 0); /* use arp function */ 1159 if (!replyport) 1160 return (0); 1161 1162 /* Allocate space for a packet, make it public and clear it */ 1163 packet = (struct StandardPacket *) 1164 AllocMem((long) sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR); 1165 if (!packet) { 1166 DeletePort(replyport); 1167 return (0); 1168 } 1169 packet->sp_Msg.mn_Node.ln_Name = (char *) &(packet->sp_Pkt); 1170 packet->sp_Pkt.dp_Link = &(packet->sp_Msg); 1171 packet->sp_Pkt.dp_Port = replyport; 1172 packet->sp_Pkt.dp_Type = action; 1173 packet->sp_Pkt.dp_Arg1 = arg; 1174 1175 PutMsg(pid, (struct Message *)packet); /* send packet */ 1176 1177 WaitPort(replyport); 1178 GetMsg(replyport); 1179 1180 res1 = packet->sp_Pkt.dp_Res1; 1181 1182 FreeMem(packet, (long) sizeof(struct StandardPacket)); 1183 DeletePort(replyport); 1184 1185 return (res1); 1186# endif 1187} 1188#endif /* !defined(AZTEC_C) && !defined(__AROS__) */ 1189 1190/* 1191 * Call shell. 1192 * Return error number for failure, 0 otherwise 1193 */ 1194 int 1195mch_call_shell(cmd, options) 1196 char_u *cmd; 1197 int options; /* SHELL_*, see vim.h */ 1198{ 1199 BPTR mydir; 1200 int x; 1201 int tmode = cur_tmode; 1202#ifdef AZTEC_C 1203 int use_execute; 1204 char_u *shellcmd = NULL; 1205 char_u *shellarg; 1206#endif 1207 int retval = 0; 1208 1209 if (close_win) 1210 { 1211 /* if Vim opened a window: Executing a shell may cause crashes */ 1212 EMSG(_("E360: Cannot execute shell with -f option")); 1213 return -1; 1214 } 1215 1216 if (term_console) 1217 win_resize_off(); /* window resize events de-activated */ 1218 out_flush(); 1219 1220 if (options & SHELL_COOKED) 1221 settmode(TMODE_COOK); /* set to normal mode */ 1222 mydir = Lock((UBYTE *)"", (long)ACCESS_READ); /* remember current dir */ 1223 1224#if !defined(AZTEC_C) /* not tested very much */ 1225 if (cmd == NULL) 1226 { 1227# ifdef FEAT_ARP 1228 if (dos2) 1229# endif 1230 x = SystemTags(p_sh, SYS_UserShell, TRUE, TAG_DONE); 1231# ifdef FEAT_ARP 1232 else 1233 x = Execute(p_sh, raw_in, raw_out); 1234# endif 1235 } 1236 else 1237 { 1238# ifdef FEAT_ARP 1239 if (dos2) 1240# endif 1241 x = SystemTags((char *)cmd, SYS_UserShell, TRUE, TAG_DONE); 1242# ifdef FEAT_ARP 1243 else 1244 x = Execute((char *)cmd, 0L, raw_out); 1245# endif 1246 } 1247# ifdef FEAT_ARP 1248 if ((dos2 && x < 0) || (!dos2 && !x)) 1249# else 1250 if (x < 0) 1251# endif 1252 { 1253 MSG_PUTS(_("Cannot execute ")); 1254 if (cmd == NULL) 1255 { 1256 MSG_PUTS(_("shell ")); 1257 msg_outtrans(p_sh); 1258 } 1259 else 1260 msg_outtrans(cmd); 1261 msg_putchar('\n'); 1262 retval = -1; 1263 } 1264# ifdef FEAT_ARP 1265 else if (!dos2 || x) 1266# else 1267 else if (x) 1268# endif 1269 { 1270 if ((x = IoErr()) != 0) 1271 { 1272 if (!(options & SHELL_SILENT)) 1273 { 1274 msg_putchar('\n'); 1275 msg_outnum((long)x); 1276 MSG_PUTS(_(" returned\n")); 1277 } 1278 retval = x; 1279 } 1280 } 1281#else /* else part is for AZTEC_C */ 1282 if (p_st >= 4 || (p_st >= 2 && !(options & SHELL_FILTER))) 1283 use_execute = 1; 1284 else 1285 use_execute = 0; 1286 if (!use_execute) 1287 { 1288 /* 1289 * separate shell name from argument 1290 */ 1291 shellcmd = vim_strsave(p_sh); 1292 if (shellcmd == NULL) /* out of memory, use Execute */ 1293 use_execute = 1; 1294 else 1295 { 1296 shellarg = skiptowhite(shellcmd); /* find start of arguments */ 1297 if (*shellarg != NUL) 1298 { 1299 *shellarg++ = NUL; 1300 shellarg = skipwhite(shellarg); 1301 } 1302 } 1303 } 1304 if (cmd == NULL) 1305 { 1306 if (use_execute) 1307 { 1308# ifdef FEAT_ARP 1309 if (dos2) 1310# endif 1311 x = SystemTags((UBYTE *)p_sh, SYS_UserShell, TRUE, TAG_DONE); 1312# ifdef FEAT_ARP 1313 else 1314 x = !Execute((UBYTE *)p_sh, raw_in, raw_out); 1315# endif 1316 } 1317 else 1318 x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, NULL); 1319 } 1320 else if (use_execute) 1321 { 1322# ifdef FEAT_ARP 1323 if (dos2) 1324# endif 1325 x = SystemTags((UBYTE *)cmd, SYS_UserShell, TRUE, TAG_DONE); 1326# ifdef FEAT_ARP 1327 else 1328 x = !Execute((UBYTE *)cmd, 0L, raw_out); 1329# endif 1330 } 1331 else if (p_st & 1) 1332 x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, 1333 (char *)cmd, NULL); 1334 else 1335 x = fexecl((char *)shellcmd, (char *)shellcmd, (char *)shellarg, 1336 (char *)p_shcf, (char *)cmd, NULL); 1337# ifdef FEAT_ARP 1338 if ((dos2 && x < 0) || (!dos2 && x)) 1339# else 1340 if (x < 0) 1341# endif 1342 { 1343 MSG_PUTS(_("Cannot execute ")); 1344 if (use_execute) 1345 { 1346 if (cmd == NULL) 1347 msg_outtrans(p_sh); 1348 else 1349 msg_outtrans(cmd); 1350 } 1351 else 1352 { 1353 MSG_PUTS(_("shell ")); 1354 msg_outtrans(shellcmd); 1355 } 1356 msg_putchar('\n'); 1357 retval = -1; 1358 } 1359 else 1360 { 1361 if (use_execute) 1362 { 1363# ifdef FEAT_ARP 1364 if (!dos2 || x) 1365# else 1366 if (x) 1367# endif 1368 x = IoErr(); 1369 } 1370 else 1371 x = wait(); 1372 if (x) 1373 { 1374 if (!(options & SHELL_SILENT) && !emsg_silent) 1375 { 1376 msg_putchar('\n'); 1377 msg_outnum((long)x); 1378 MSG_PUTS(_(" returned\n")); 1379 } 1380 retval = x; 1381 } 1382 } 1383 vim_free(shellcmd); 1384#endif /* AZTEC_C */ 1385 1386 if ((mydir = CurrentDir(mydir)) != 0) /* make sure we stay in the same directory */ 1387 UnLock(mydir); 1388 if (tmode == TMODE_RAW) 1389 settmode(TMODE_RAW); /* set to raw mode */ 1390#ifdef FEAT_TITLE 1391 resettitle(); 1392#endif 1393 if (term_console) 1394 win_resize_on(); /* window resize events activated */ 1395 return retval; 1396} 1397 1398/* 1399 * check for an "interrupt signal" 1400 * We only react to a CTRL-C, but also clear the other break signals to avoid 1401 * trouble with lattice-c programs. 1402 */ 1403 void 1404mch_breakcheck() 1405{ 1406 if (SetSignal(0L, (long)(SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F)) & SIGBREAKF_CTRL_C) 1407 got_int = TRUE; 1408} 1409 1410/* this routine causes manx to use this Chk_Abort() rather than it's own */ 1411/* otherwise it resets our ^C when doing any I/O (even when Enable_Abort */ 1412/* is zero). Since we want to check for our own ^C's */ 1413 1414#ifdef _DCC 1415#define Chk_Abort chkabort 1416#endif 1417 1418#ifdef LATTICE 1419void __regargs __chkabort(void); 1420 1421void __regargs __chkabort(void) 1422{} 1423 1424#else 1425 long 1426Chk_Abort(void) 1427{ 1428 return(0L); 1429} 1430#endif 1431 1432/* 1433 * mch_expandpath() - this code does wild-card pattern matching using the arp 1434 * routines. 1435 * 1436 * "pat" has backslashes before chars that are not to be expanded. 1437 * Returns the number of matches found. 1438 * 1439 * This is based on WildDemo2.c (found in arp1.1 distribution). 1440 * That code's copyright follows: 1441 * Copyright (c) 1987, Scott Ballantyne 1442 * Use and abuse as you please. 1443 */ 1444 1445#ifdef __amigaos4__ 1446# define ANCHOR_BUF_SIZE 1024 1447#else 1448# define ANCHOR_BUF_SIZE (512) 1449# define ANCHOR_SIZE (sizeof(struct AnchorPath) + ANCHOR_BUF_SIZE) 1450#endif 1451 1452 int 1453mch_expandpath(gap, pat, flags) 1454 garray_T *gap; 1455 char_u *pat; 1456 int flags; /* EW_* flags */ 1457{ 1458 struct AnchorPath *Anchor; 1459 LONG Result; 1460 char_u *starbuf, *sp, *dp; 1461 int start_len; 1462 int matches; 1463#ifdef __amigaos4__ 1464 struct TagItem AnchorTags[] = { 1465 {ADO_Strlen, ANCHOR_BUF_SIZE}, 1466 {ADO_Flags, APF_DODOT|APF_DOWILD|APF_MultiAssigns}, 1467 {TAG_DONE, 0L} 1468 }; 1469#endif 1470 1471 start_len = gap->ga_len; 1472 1473 /* Get our AnchorBase */ 1474#ifdef __amigaos4__ 1475 Anchor = AllocDosObject(DOS_ANCHORPATH, AnchorTags); 1476#else 1477 Anchor = (struct AnchorPath *)alloc_clear((unsigned)ANCHOR_SIZE); 1478#endif 1479 if (Anchor == NULL) 1480 return 0; 1481 1482#ifndef __amigaos4__ 1483 Anchor->ap_Strlen = ANCHOR_BUF_SIZE; /* ap_Length not supported anymore */ 1484# ifdef APF_DODOT 1485 Anchor->ap_Flags = APF_DODOT | APF_DOWILD; /* allow '.' for current dir */ 1486# else 1487 Anchor->ap_Flags = APF_DoDot | APF_DoWild; /* allow '.' for current dir */ 1488# endif 1489#endif 1490 1491#ifdef FEAT_ARP 1492 if (dos2) 1493 { 1494#endif 1495 /* hack to replace '*' by '#?' */ 1496 starbuf = alloc((unsigned)(2 * STRLEN(pat) + 1)); 1497 if (starbuf == NULL) 1498 goto Return; 1499 for (sp = pat, dp = starbuf; *sp; ++sp) 1500 { 1501 if (*sp == '*') 1502 { 1503 *dp++ = '#'; 1504 *dp++ = '?'; 1505 } 1506 else 1507 *dp++ = *sp; 1508 } 1509 *dp = NUL; 1510 Result = MatchFirst((UBYTE *)starbuf, Anchor); 1511 vim_free(starbuf); 1512#ifdef FEAT_ARP 1513 } 1514 else 1515 Result = FindFirst((char *)pat, Anchor); 1516#endif 1517 1518 /* 1519 * Loop to get all matches. 1520 */ 1521 while (Result == 0) 1522 { 1523#ifdef __amigaos4__ 1524 addfile(gap, (char_u *)Anchor->ap_Buffer, flags); 1525#else 1526 addfile(gap, (char_u *)Anchor->ap_Buf, flags); 1527#endif 1528#ifdef FEAT_ARP 1529 if (dos2) 1530#endif 1531 Result = MatchNext(Anchor); 1532#ifdef FEAT_ARP 1533 else 1534 Result = FindNext(Anchor); 1535#endif 1536 } 1537 matches = gap->ga_len - start_len; 1538 1539 if (Result == ERROR_BUFFER_OVERFLOW) 1540 EMSG(_("ANCHOR_BUF_SIZE too small.")); 1541 else if (matches == 0 && Result != ERROR_OBJECT_NOT_FOUND 1542 && Result != ERROR_DEVICE_NOT_MOUNTED 1543 && Result != ERROR_NO_MORE_ENTRIES) 1544 EMSG(_("I/O ERROR")); 1545 1546 /* 1547 * Sort the files for this pattern. 1548 */ 1549 if (matches) 1550 qsort((void *)(((char_u **)gap->ga_data) + start_len), 1551 (size_t)matches, sizeof(char_u *), sortcmp); 1552 1553 /* Free the wildcard stuff */ 1554#ifdef FEAT_ARP 1555 if (dos2) 1556#endif 1557 MatchEnd(Anchor); 1558#ifdef FEAT_ARP 1559 else 1560 FreeAnchorChain(Anchor); 1561#endif 1562 1563Return: 1564#ifdef __amigaos4__ 1565 FreeDosObject(DOS_ANCHORPATH, Anchor); 1566#else 1567 vim_free(Anchor); 1568#endif 1569 1570 return matches; 1571} 1572 1573 static int 1574sortcmp(a, b) 1575 const void *a, *b; 1576{ 1577 char *s = *(char **)a; 1578 char *t = *(char **)b; 1579 1580 return pathcmp(s, t, -1); 1581} 1582 1583/* 1584 * Return TRUE if "p" has wildcards that can be expanded by mch_expandpath(). 1585 */ 1586 int 1587mch_has_exp_wildcard(p) 1588 char_u *p; 1589{ 1590 for ( ; *p; mb_ptr_adv(p)) 1591 { 1592 if (*p == '\\' && p[1] != NUL) 1593 ++p; 1594 else if (vim_strchr((char_u *)"*?[(#", *p) != NULL) 1595 return TRUE; 1596 } 1597 return FALSE; 1598} 1599 1600 int 1601mch_has_wildcard(p) 1602 char_u *p; 1603{ 1604 for ( ; *p; mb_ptr_adv(p)) 1605 { 1606 if (*p == '\\' && p[1] != NUL) 1607 ++p; 1608 else 1609 if (vim_strchr((char_u *) 1610# ifdef VIM_BACKTICK 1611 "*?[(#$`" 1612# else 1613 "*?[(#$" 1614# endif 1615 , *p) != NULL 1616 || (*p == '~' && p[1] != NUL)) 1617 return TRUE; 1618 } 1619 return FALSE; 1620} 1621 1622/* 1623 * With AmigaDOS 2.0 support for reading local environment variables 1624 * 1625 * Two buffers are allocated: 1626 * - A big one to do the expansion into. It is freed before returning. 1627 * - A small one to hold the return value. It is kept until the next call. 1628 */ 1629 char_u * 1630mch_getenv(var) 1631 char_u *var; 1632{ 1633 int len; 1634 UBYTE *buf; /* buffer to expand in */ 1635 char_u *retval; /* return value */ 1636 static char_u *alloced = NULL; /* allocated memory */ 1637 1638#ifdef FEAT_ARP 1639 if (!dos2) 1640 retval = (char_u *)getenv((char *)var); 1641 else 1642#endif 1643 { 1644 vim_free(alloced); 1645 alloced = NULL; 1646 retval = NULL; 1647 1648 buf = alloc(IOSIZE); 1649 if (buf == NULL) 1650 return NULL; 1651 1652 len = GetVar((UBYTE *)var, buf, (long)(IOSIZE - 1), (long)0); 1653 if (len >= 0) 1654 { 1655 retval = vim_strsave((char_u *)buf); 1656 alloced = retval; 1657 } 1658 1659 vim_free(buf); 1660 } 1661 1662 /* if $VIM is not defined, use "vim:" instead */ 1663 if (retval == NULL && STRCMP(var, "VIM") == 0) 1664 retval = (char_u *)"vim:"; 1665 1666 return retval; 1667} 1668 1669/* 1670 * Amiga version of setenv() with AmigaDOS 2.0 support. 1671 */ 1672/* ARGSUSED */ 1673 int 1674mch_setenv(var, value, x) 1675 char *var; 1676 char *value; 1677 int x; 1678{ 1679#ifdef FEAT_ARP 1680 if (!dos2) 1681 return setenv(var, value); 1682#endif 1683 1684 if (SetVar((UBYTE *)var, (UBYTE *)value, (LONG)-1, (ULONG)GVF_LOCAL_ONLY)) 1685 return 0; /* success */ 1686 return -1; /* failure */ 1687} 1688