diff -rcP emacs-18.59-fsf/cpp/SCOPTIONS emacs-18.59-amiga/cpp/SCOPTIONS *** emacs-18.59-fsf/cpp/SCOPTIONS Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/cpp/SCOPTIONS Sat Jun 5 12:01:06 1993 *************** *** 0 **** --- 1,7 ---- + IGNORE=161 + IGNORE=154 + IGNORE=100 + IGNORE=181 + IGNORE=84 + IGNORE=93 + IGNORE=72 \ No newline at end of file diff -rcP emacs-18.59-fsf/cpp/cccp.c emacs-18.59-amiga/cpp/cccp.c *** emacs-18.59-fsf/cpp/cccp.c Fri Sep 28 20:17:57 1990 --- emacs-18.59-amiga/cpp/cccp.c Sat Jun 5 12:07:16 1993 *************** *** 97,103 **** --- 97,113 ---- #ifdef EMACS #define NO_SHORTNAMES + #ifdef AMIGA + #include "/src/config.h" + #undef fflush + #undef fwrite + #undef main + #undef putchar + #undef AMIGA_DUMP + #include + #else #include "../src/config.h" + #endif #ifdef static #undef static #endif *************** *** 115,121 **** --- 125,135 ---- #include #include #ifndef USG + #ifdef AMIGA + #include + #else #include /* for __DATE__ and __TIME__ */ + #endif #else #define index strchr #define rindex strrchr *************** *** 123,130 **** --- 137,146 ---- #include #endif /* USG */ + #ifndef AMIGA void bcopy (), bzero (); int bcmp (); + #endif char *xmalloc (), *xrealloc (), *xcalloc (); void fatal (), pfatal_with_name (), perror_with_name (); *************** *** 142,156 **** --- 158,186 ---- /* #include "file" starts with the first entry in the stack */ /* #include starts with the second. */ /* -I directories are added after the first */ + #ifdef AMIGA + struct directory_stack default_includes[2] = + { + { &default_includes[1], "" }, + { 0, "include:" } + }; + #else struct directory_stack default_includes[2] = { { &default_includes[1], "." }, { 0, "/usr/include" } }; + #endif + struct directory_stack *include = &default_includes[0]; + #ifdef AMIGA int max_include_len = 14; /* strlen (default_include) + 2 (for / and null) */ + #else + int max_include_len = 9; /* strlen (default_include) + 1 + (for null) */ + #endif char STDIN_FILE[] = ""; /* Empty, like real cpp */ int put_out_comments = 0; /* JF non-zero means leave comments in the *************** *** 379,385 **** dirtmp->next = include->next; include->next = dirtmp; dirtmp->fname = argv[i]+2; - include = dirtmp; if (strlen (argv[i]) > max_include_len) max_include_len = strlen (argv[i]); break; --- 409,414 ---- *************** *** 405,415 **** else if ((f = open (in_fname, O_RDONLY)) < 0) goto perror; ! fstat (f, &sbuf); fp->fname = in_fname; fp->lineno = 1; /* JF all this is mine about reading pipes and ttys */ ! if ((sbuf.st_mode & S_IFMT) != S_IFREG) { int size; int bsize; int cnt; --- 434,444 ---- else if ((f = open (in_fname, O_RDONLY)) < 0) goto perror; ! if (f) fstat (f, &sbuf); fp->fname = in_fname; fp->lineno = 1; /* JF all this is mine about reading pipes and ttys */ ! if (!f || (sbuf.st_mode & S_IFMT) != S_IFREG) { int size; int bsize; int cnt; *************** *** 478,488 **** struct keyword_table *handle_directive (); int excess_newlines = 0; int escaped = 0; ! U_CHAR *bp; ! check_expand(op, ip->length); ! ip->bufp = ip->buf; limit = ip->buf + ip->length; while (1) { --- 507,517 ---- struct keyword_table *handle_directive (); int excess_newlines = 0; int escaped = 0; ! U_CHAR *bp; ! check_expand(op, ip->length); ! ip->bufp = ip->buf; limit = ip->buf + ip->length; while (1) { *************** *** 615,639 **** *op->bufp++ = '/'; ip->bufp = bp + 1; break; ! case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* if digit is not part of identifier, it is random */ if (ident_length == 0) goto randomchar; /* fall through */ ! case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': ! case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': ! case 'Y': case 'Z': ident_length++; /* compute step of hash function, to avoid a proc call on every token */ hash = HASHSTEP(hash, c); --- 644,668 ---- *op->bufp++ = '/'; ip->bufp = bp + 1; break; ! case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /* if digit is not part of identifier, it is random */ if (ident_length == 0) goto randomchar; /* fall through */ ! case '_': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': ! case 'y': case 'z': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': ! case 'Y': case 'Z': ident_length++; /* compute step of hash function, to avoid a proc call on every token */ hash = HASHSTEP(hash, c); *************** *** 646,676 **** for (hp = hashtab[MAKE_POS(hash) % HASHSIZE]; hp != NULL; hp = hp->next) { U_CHAR *save_ibufp; /* kludge, see below */ ! if (hp->length == ident_length) { register int i = ident_length; register U_CHAR *p = hp->name; register U_CHAR *q = op->bufp - i; ! if (c != (U_CHAR) -1) q--; do { /* all this to avoid a strncmp() */ if (*p++ != *q++) goto hashcollision; } while (--i); ! save_ibufp = ip->bufp; /* back up over identifier, then expand token */ op->bufp -= ident_length; ! if (c != (U_CHAR) -1) op->bufp--; macroexpand (hp, ip, op, &excess_newlines); check_expand(op, ip->length - (ip->bufp - ip->buf)); ! /* If we just processed an identifier at end of input, return right away. */ ! if (c == (U_CHAR) -1) return; /* if the expansion routine has not moved the input --- 675,705 ---- for (hp = hashtab[MAKE_POS(hash) % HASHSIZE]; hp != NULL; hp = hp->next) { U_CHAR *save_ibufp; /* kludge, see below */ ! if (hp->length == ident_length) { register int i = ident_length; register U_CHAR *p = hp->name; register U_CHAR *q = op->bufp - i; ! if (c != -1) q--; do { /* all this to avoid a strncmp() */ if (*p++ != *q++) goto hashcollision; } while (--i); ! save_ibufp = ip->bufp; /* back up over identifier, then expand token */ op->bufp -= ident_length; ! if (c != -1) op->bufp--; macroexpand (hp, ip, op, &excess_newlines); check_expand(op, ip->length - (ip->bufp - ip->buf)); ! /* If we just processed an identifier at end of input, return right away. */ ! if (c == -1) return; /* if the expansion routine has not moved the input *************** *** 679,685 **** reason to put it back or not put it back. */ if (ip->bufp == save_ibufp) *op->bufp++ = c; ! break; /* out of for loop */ } hashcollision: --- 708,714 ---- reason to put it back or not put it back. */ if (ip->bufp == save_ibufp) *op->bufp++ = c; ! break; /* out of for loop */ } hashcollision: *************** *** 687,693 **** } /* end for loop */ ident_length = hash = 0; /* stop collecting identifier */ } ! /* If we just processed an identifier at end of input, return right away. */ if (c == -1) --- 716,722 ---- } /* end for loop */ ident_length = hash = 0; /* stop collecting identifier */ } ! /* If we just processed an identifier at end of input, return right away. */ if (c == -1) *************** *** 746,752 **** while (is_idchar[*cp]) cp++; ident_length = cp - bp; ! /* * Decode the keyword and call the appropriate expansion * routine, after moving the input pointer up to the next line. --- 775,781 ---- while (is_idchar[*cp]) cp++; ident_length = cp - bp; ! /* * Decode the keyword and call the appropriate expansion * routine, after moving the input pointer up to the next line. *************** *** 758,770 **** register U_CHAR *buf; register U_CHAR *limit = ip->buf + ip->length; U_CHAR *skip_to_end_of_comment(); ! buf = bp = bp + ident_length; while (bp < limit) { if (*bp == '\'' || *bp == '\"') { /* JF handle quotes right */ U_CHAR quotec; ! for (quotec = *bp++; bp < limit && *bp != quotec; bp++) { if (*bp == '\\') bp++; if (*bp == '\n') { if (bp[-1] == '\\') --- 787,804 ---- register U_CHAR *buf; register U_CHAR *limit = ip->buf + ip->length; U_CHAR *skip_to_end_of_comment(); ! buf = bp = bp + ident_length; while (bp < limit) { if (*bp == '\'' || *bp == '\"') { /* JF handle quotes right */ U_CHAR quotec; ! for (quotec = *bp++; bp < limit; bp++) { ! if (*bp == quotec) ! { ! bp++; ! break; ! } if (*bp == '\\') bp++; if (*bp == '\n') { if (bp[-1] == '\\') *************** *** 801,813 **** some slop */ bp = buf; buf = cp; ! while (bp < limit) { if (*bp == '\'' || *bp == '\"') { /* JF handle quotes right */ U_CHAR quotec; *cp++ = *bp; ! for (quotec = *bp++; bp < limit && *bp != quotec; *cp++ = *bp++) { if (*bp == '\\') *cp++ = *bp++; if (*bp == '\n') { --- 835,852 ---- some slop */ bp = buf; buf = cp; ! while (bp < limit) { if (*bp == '\'' || *bp == '\"') { /* JF handle quotes right */ U_CHAR quotec; *cp++ = *bp; ! for (quotec = *bp++; bp < limit; *cp++ = *bp++) { ! if (*bp == quotec) ! { ! *cp++ = *bp++; ! break; ! } if (*bp == '\\') *cp++ = *bp++; if (*bp == '\n') { *************** *** 939,950 **** ++ip->bufp; } break; ! oops: ! error ("`defined' must be followed by IDENT or (IDENT)"); break; ! default: error("CCCP error: illegal special hash type"); /* time for gdb */ abort (); --- 978,989 ---- ++ip->bufp; } break; ! oops: ! error ("`defined' must be followed by IDENT or (IDENT)"); break; ! default: error("CCCP error: illegal special hash type"); /* time for gdb */ abort (); *************** *** 953,959 **** check_expand(op, len); bcopy (buf, op->bufp, len); op->bufp += len; ! return; } --- 992,998 ---- check_expand(op, len); bcopy (buf, op->bufp, len); op->bufp += len; ! return; } *************** *** 978,984 **** struct stat sbuf; /* to stat the include file */ FILE_BUF *fp; /* for input stack frame */ struct directory_stack *stackp; ! int flen; int save_indepth = indepth; /* in case of errors */ --- 1017,1023 ---- struct stat sbuf; /* to stat the include file */ FILE_BUF *fp; /* for input stack frame */ struct directory_stack *stackp; ! int flen, maxlen; int save_indepth = indepth; /* in case of errors */ *************** *** 1019,1025 **** --- 1058,1068 ---- if (err) goto nope; + /* DG: This doesn't handle includes of aa:... on the Amiga */ + /* It doesn't seem worth it. */ other_dir = NULL; + maxlen = max_include_len; + #if 0 if (stackp == include) { fp = &instack[indepth]; *************** *** 1037,1049 **** other_dir = (char *) alloca (n + 1); strncpy (other_dir, nam, n); other_dir[n] = '\0'; } break; } } } /* JF search directory path */ ! fname = (char *) alloca (max_include_len + flen); for (; stackp; stackp = stackp->next) { if (other_dir) --- 1080,1094 ---- other_dir = (char *) alloca (n + 1); strncpy (other_dir, nam, n); other_dir[n] = '\0'; + if (n + 4 > maxlen) maxlen = n + 4; } break; } } } + #endif /* JF search directory path */ ! fname = (char *) alloca (maxlen + flen); for (; stackp; stackp = stackp->next) { if (other_dir) *************** *** 1053,1058 **** --- 1098,1107 ---- } else strcpy (fname, stackp->fname); + #ifdef AMIGA + if (fname[0] != 0 && fname[strlen(fname) - 1] != ':') + /* Don't add / after : or empty strings */ + #endif strcat (fname, "/"); strncat (fname, fbeg, flen); if ((f = open (fname, O_RDONLY)) >= 0) *************** *** 1064,1070 **** --- 1113,1123 ---- goto nope; } + #ifdef AMIGA + if (stat(fname, &sbuf) < 0) + #else if (fstat(f, &sbuf) < 0) + #endif { perror_with_name (fname); goto nope; /* impossible? */ *************** *** 1202,1208 **** ++bp; /* skip paren */ /* Skip exactly one space or tab if any. */ if (bp < limit && (*bp == ' ' || *bp == '\t')) ++bp; ! /* now everything from bp before limit is the definition. */ defn = collect_expansion(bp, limit - bp, arg_ptrs); } else { --- 1255,1261 ---- ++bp; /* skip paren */ /* Skip exactly one space or tab if any. */ if (bp < limit && (*bp == ' ' || *bp == '\t')) ++bp; ! /* now everything from bp before limit is the definition. */ defn = collect_expansion(bp, limit - bp, arg_ptrs); } else { *************** *** 1226,1235 **** } } } ! install (symname, T_MACRO, defn); return 0; ! nope: return 1; --- 1279,1288 ---- } } } ! install (symname, T_MACRO, defn); return 0; ! nope: return 1; *************** *** 1308,1314 **** if (is_idstart[*p] && (p==buf || !is_idchar[*(p-1)])) { ! for (id_len = 0; is_idchar[p[id_len]]; id_len++) ; for (arg = arglist; arg != NULL; arg = arg->next) { struct reflist *tpat; --- 1361,1367 ---- if (is_idstart[*p] && (p==buf || !is_idchar[*(p-1)])) { ! for (id_len = 0; p+id_len < buf+size && is_idchar[p[id_len]]; id_len++) ; for (arg = arglist; arg != NULL; arg = arg->next) { struct reflist *tpat; *************** *** 1341,1347 **** *exp_p++ = '\0'; defn->length = exp_p - defn->expansion - 1; ! /* give back excess storage */ defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1); --- 1394,1400 ---- *exp_p++ = '\0'; defn->length = exp_p - defn->expansion - 1; ! /* give back excess storage */ defn->expansion = (U_CHAR *) xrealloc (defn->expansion, defn->length + 1); *************** *** 1456,1462 **** delete (hp); } ! /* handle #error command later */ do_error() { } --- 1509,1515 ---- delete (hp); } ! /* handle #error command later */ do_error() { } *************** *** 1465,1470 **** --- 1518,1538 ---- * the behavior of the #pragma directive is implementation defined. * this implementation defines it as follows. */ + #ifdef AMIGA + do_pragma(buf, limit, op, keyword) + U_CHAR *buf, *limit; + FILE_BUF *op; + struct keyword_table *keyword; + { + /* Just copy the pragma directibe back out */ + int len2 = limit - buf, len1 = sizeof("#pragma") - 1; + + check_expand(op, len1 + len2); + bcopy("#pragma", op->bufp, len1); + bcopy(buf, op->bufp + len1, len2); + op->bufp += len1 + len2; + } + #else do_pragma() { close (0); *************** *** 1479,1484 **** --- 1547,1553 ---- nope: fatal ("You are in a maze of twisty compiler features, all different"); } + #endif typedef struct if_stack { struct if_stack *next; /* for chaining to the next stack frame */ *************** *** 1541,1547 **** } if_stack->type = T_ELIF; } ! value = eval_if_expression (buf, limit - buf); conditional_skip (ip, value == 0, T_ELIF); } --- 1610,1616 ---- } if_stack->type = T_ELIF; } ! value = eval_if_expression (buf, limit - buf); conditional_skip (ip, value == 0, T_ELIF); } *************** *** 1574,1580 **** delete (save_defined); /* clean up special symbol */ free (temp_obuf.buf); ! return value; } --- 1643,1649 ---- delete (save_defined); /* clean up special symbol */ free (temp_obuf.buf); ! return value; } *************** *** 1614,1620 **** if_stack = temp; if_stack->type = type; ! if (skip != 0) { skip_if_group(ip); return; --- 1683,1689 ---- if_stack = temp; if_stack->type = type; ! if (skip != 0) { skip_if_group(ip); return; *************** *** 1724,1730 **** * without changing if_stack ; this is so that the error message * for missing #endif's etc. will point to the original #if. It * is possible that something different would be better. ! */ do_else(buf, limit, op, keyword) U_CHAR *buf, *limit; FILE_BUF *op; --- 1793,1799 ---- * without changing if_stack ; this is so that the error message * for missing #endif's etc. will point to the original #if. It * is possible that something different would be better. ! */ do_else(buf, limit, op, keyword) U_CHAR *buf, *limit; FILE_BUF *op; *************** *** 1915,1921 **** int totlen; /* total amount of exp buffer filled so far */ register struct reflist *ap; ! struct argptrs { U_CHAR *argstart; int length; } *args; --- 1984,1990 ---- int totlen; /* total amount of exp buffer filled so far */ register struct reflist *ap; ! struct argptrs { U_CHAR *argstart; int length; } *args; *************** *** 1999,2005 **** ip2->buf = ip2->bufp = defn->expansion; ip2->length = defn->length; } ! rescan (ip2, op); --indepth; *excess_newlines_ptr += newlines_found; --- 2068,2074 ---- ip2->buf = ip2->bufp = defn->expansion; ip2->length = defn->length; } ! rescan (ip2, op); --indepth; *excess_newlines_ptr += newlines_found; *************** *** 2024,2030 **** { int paren = 0; int quotec = 0; ! while (bp < ip->buf + ip->length) { switch (*bp) { case '(': --- 2093,2099 ---- { int paren = 0; int quotec = 0; ! while (bp < ip->buf + ip->length) { switch (*bp) { case '(': *************** *** 2084,2092 **** } if (ip != NULL) ! fprintf(stdout, "file %s, offset %d (line %d): ", ip->fname, ip->bufp - ip->buf, ip->lineno); ! fprintf(stdout, "%s\n", msg); return 0; } --- 2153,2161 ---- } if (ip != NULL) ! fprintf(stderr, "file %s, offset %d (line %d): ", ip->fname, ip->bufp - ip->buf, ip->lineno); ! fprintf(stderr, "%s\n", msg); return 0; } *************** *** 2109,2115 **** { register int i; register U_CHAR *p; ! if (obuf->length - (obuf->bufp - obuf->buf) > needed) return obuf->buf; --- 2178,2184 ---- { register int i; register U_CHAR *p; ! if (obuf->length - (obuf->bufp - obuf->buf) > needed) return obuf->buf; *************** *** 2125,2131 **** return p; } ! /* * install a name in the main hash table, even if it is already there. * name stops with first non alphanumeric, except leading '#'. --- 2194,2200 ---- return p; } ! /* * install a name in the main hash table, even if it is already there. * name stops with first non alphanumeric, except leading '#'. *************** *** 2198,2204 **** delete(hp) HASHNODE *hp; { ! if (hp->prev != NULL) hp->prev->next = hp->next; if (hp->next != NULL) --- 2267,2273 ---- delete(hp) HASHNODE *hp; { ! if (hp->prev != NULL) hp->prev->next = hp->next; if (hp->next != NULL) *************** *** 2232,2241 **** int hashsize; { register int r = 0; ! while (len--) r = HASHSTEP(r, *name++); ! return MAKE_POS(r) % hashsize; } --- 2301,2310 ---- int hashsize; { register int r = 0; ! while (len--) r = HASHSTEP(r, *name++); ! return MAKE_POS(r) % hashsize; } *************** *** 2282,2288 **** #endif /* is there more? */ ! } /* --- 2351,2357 ---- #endif /* is there more? */ ! } /* *************** *** 2357,2363 **** #endif /* not VMS */ } ! void bcopy (b1, b2, length) register char *b1; register char *b2; --- 2426,2432 ---- #endif /* not VMS */ } ! void bcopy (b1, b2, length) register char *b1; register char *b2; *************** *** 2379,2385 **** *b2++ = *b1++; #endif /* not VMS */ } ! int bcmp (b1, b2, length) /* This could be a macro! */ register char *b1; --- 2448,2454 ---- *b2++ = *b1++; #endif /* not VMS */ } ! int bcmp (b1, b2, length) /* This could be a macro! */ register char *b1; diff -rcP emacs-18.59-fsf/cpp/smakefile emacs-18.59-amiga/cpp/smakefile *** emacs-18.59-fsf/cpp/smakefile Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/cpp/smakefile Sat Oct 2 15:30:13 1993 *************** *** 0 **** --- 1,23 ---- + # Makefile for cccp in the Emacs distribution only. + # Here we assume that you are using SASC + # (since cccp is used by Emacs only to deal with long strings in macros. + + CFLAGS=DEF EMACS idir //unix/include/ def STACK_DIRECTION=-1 def OUTPUT_LINE_COMMANDS nowvret debug sf + + cpp: cccp + -delete cpp + makelink cpp cccp + cccp: cccp.o cexp.tab.o alloca.o + sc link cccp.o alloca.o cexp.tab.o to cccp lib //unix/src/unix.lib + + testexp: y.tab.c + cc -g -DTEST_EXP_READER y.tab.c -o testexp + + cexp.tab.c: cexp.y + echo "expect 40 shift/reduce conflicts" + bin:bison cexp.y >bison.debug + + cccp.o: cccp.c + cexp.tab.o: cexp.tab.c + alloca.o: /src/alloca.c + $(CC) $(CFLAGS) objname alloca.o /src/alloca.c diff -rcP emacs-18.59-fsf/etc/SCOPTIONS emacs-18.59-amiga/etc/SCOPTIONS *** emacs-18.59-fsf/etc/SCOPTIONS Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/etc/SCOPTIONS Sat Dec 5 18:07:36 1992 *************** *** 0 **** --- 1,15 ---- + STRINGMERGE + STRUCTUREEQUIVALENCE + NOWARNVOIDRETURN + NOVERSION + MEMORYSIZE=HUGE + INCLUDEDIR=src:unix/include + IGNORE=147 + IGNORE=62 + IGNORE=132 + IGNORE=154 + IGNORE=104 + IGNORE=100 + IGNORE=161 + IGNORE=84 + IGNORE=93 diff -rcP emacs-18.59-fsf/etc/amiga-env.c emacs-18.59-amiga/etc/amiga-env.c *** emacs-18.59-fsf/etc/amiga-env.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/etc/amiga-env.c Sat Jun 5 16:55:12 1993 *************** *** 0 **** --- 1,439 ---- + /* env.c - manipulate environment and execute a program + in that environment + Mly 861126 + + Copyright (C) 1986 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + In other words, you are welcome to use, share and improve this program. + You are forbidden to forbid anyone else to use, share and improve + what you give them. Help stamp out software-hoarding! */ + + /* + + If first argument is "-", then a new environment is constructed + from scratch; otherwise the environment is inherited from the parent + process, except as modified by other options. + + So, "env - foo" will invoke the "foo" program in a null environment, + whereas "env foo" would invoke "foo" in the same environment as that + passed to "env" itself. + + Subsequent arguments are interpreted as follows: + + * "variable=value" (ie an arg containing a "=" character) + means to set the specified environment variable to that value. + `value' may be of zero length ("variable="). Note that setting + a variable to a zero-length value is different from unsetting it. + + * "-u variable" or "-unset variable" + means to unset that variable + If that variable isn't set, does nothing. + + * "-s variable value" or "-set variable value" + same as "variable=value" + + * "-" or "--" + are used to indicate that the following argument is the program + to invoke. This is only necessary when the program's name + begins with "-" or contains a "=" + + * anything else + The first remaining argument specifies a program to invoke + (it is searched for according to the specification of the PATH + environment variable) and any arguments following that are + passed as arguments to that program + + If no program-name is specified following the environment + specifications the the resulting environment is printed + (The is like specifying a program-name of "printenv") + + Examples: + If the environment passed to "env" is + { USER=rms EDITOR=emacs PATH=.:/gnubin:/hacks } + + * "env DISPLAY=gnu:0 nemacs" + calls "nemacs" in the envionment + { EDITOR=emacs USER=rms DISPLAY=gnu } + + * "env - USER=foo /hacks/hack bar baz" + will call the "hack" program on arguments "bar" and "baz" + in an environment in which the only variable is "USER" + Note that the "-" option will clear out the PATH variable, + so one should be careful to specify in which directory + to find the program to call + + * "env -u EDITOR USER=foo PATH=/energy -- e=mc2 bar baz" + The program "/energy/e=mc2" is called with environment + { USER=foo PATH=/energy } + + */ + + #include + #include + #include + #include + #include + + #ifdef EMACS + #define NO_SHORTNAMES + #include "../src/config.h" + #endif /* EMACS */ + + #include + #include + #include + + extern int execvp (); + extern char *index (); + + char *xmalloc (), *xrealloc (); + char *concat (); + + char *progname; + void setenv (); + void fatal (); + + #define index strchr + + struct MsgPort *end_port; + struct { + struct Message msg; + int rc; + } end_msg; + int gargc; + char **gargv; + jmp_buf unixexit_buf; + + void __saveds unix_start(void) + { + int rc; + + if (!(rc = setjmp(unixexit_buf))) + { + unixmain(gargc, gargv); + rc = 1; + } + end_msg.rc = rc - 1; + end_msg.msg.mn_Length = sizeof(end_msg); + end_msg.msg.mn_Node.ln_Type = NT_MESSAGE; + PutMsg(end_port, &end_msg); + } + + void unixexit(int rc) + { + longjmp(unixexit_buf, rc + 1); + } + + main(int argc, char **argv) + { + int rc = 1; + long stacksize; + struct Process *us = (struct Process *)FindTask(0); + + if (us->pr_CLI) stacksize = ((struct CommandLineInterface *)BADDR(us->pr_CLI))->cli_DefaultStack << 2; + else stacksize = us->pr_StackSize; + + gargc = argc; + gargv = argv; + + end_port = CreateMsgPort(); + + if (end_port && CreateNewProcTags(NP_Entry, unix_start, + NP_Input, Input(), NP_CloseInput, 0UL, + NP_Output, Output(), NP_CloseOutput, 0UL, + NP_StackSize, stacksize, + NP_Cli, TRUE, TAG_END)) + { + while (!GetMsg(end_port)) WaitPort(end_port); + rc = end_msg.rc; + } + if (end_port) DeleteMsgPort(end_port); + Delay(1); + exit(rc); + } + + #define exit unixexit + + unixmain (argc, argv) + register int argc; + register char **argv; + { + register char *tem; + + progname = argv[0]; + argc--; + argv++; + + /* "-" flag means to not inherit parent's environment */ + /* This is ignored on the amiga */ + if (argc && !strcmp (*argv, "-")) + { + argc--; + argv++; + } + + while (argc > 0) + { + tem = index (*argv, '='); + if (tem) + /* If arg contains a "=" it specifies to set a variable */ + { + *tem = '\000'; + setenv (*argv, tem + 1); + argc--; argv++; + continue; + } + + if (**argv != '-') + /* Remaining args are program name and args to pass it */ + break; + + if (argc < 2) + fatal ("No argument following \"%s\" switch", *argv); + if (!strcmp (*argv, "-u") || + !strcmp (*argv, "-unset")) + /* Unset a variable */ + { + argc--; argv++; + setenv (*argv, 0); + argc--; argv++; + } + else if (!strcmp (*argv, "-s") || + !strcmp (*argv, "-set")) + /* Set a variable */ + { + argc--; argv++; + tem = *argv; + if (argc < 2) + fatal ("No value specified for variable \"%s\"", + tem); + argc--; argv++; + setenv (tem, *argv); + argc--; argv++; + } + else if (!strcmp (*argv, "-") || !strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else + { + fatal ("unknown switch \"%s\"", *argv); + } + } + + /* If no program specified print the environment and exit */ + if (argc <= 0) + { + printenv(); + exit (0); + } + else + { + extern int errno, sys_nerr; + extern char *sys_errlist[]; + + (void) execvp (*argv, argv); + + fprintf (stderr, "%s: Cannot execute \"%s\"", + progname, *argv); + if (errno < sys_nerr) + fprintf (stderr, ": %s\n" , sys_errlist[errno]); + else + putc ('\n', stderr); + exit (errno != 0 ? errno : 1); + } + } + + int execvp(program, argv) + char *program, **argv; + { + int index, comsize; + char *combuf, *bp; + long err, rc; + + combuf = xmalloc(256); + comsize = 256; + + bp = combuf; + for (index = 0; argv[index] != 0; index++) + { + char *s = argv[index]; + int len; + + len = 3; + while (*s) len += 1 + 2 * (*s++ == '"'); + if (bp + len + 1 >= combuf + comsize) + { + char *newbuf; + int new_comsize; + + new_comsize = 2 * comsize + len; + newbuf = xmalloc(new_comsize); + memcpy(newbuf, combuf, comsize); + + bp = newbuf + (bp - combuf); + combuf = newbuf; + comsize = new_comsize; + } + *bp++ = ' '; + *bp++ = '"'; + s = argv[index]; + while (*s) + { + if (*s == '"' || *s == '*') *bp++ = '*'; + *bp++ = *s++; + } + *bp++ = '"'; + } + *bp = '\0'; + rc = SystemTags(combuf, + SYS_UserShell, 1UL, + TAG_END); + err = IoErr(); + free(combuf); + if (rc != -1) exit(rc); + + errno = convert_oserr(err); + return -1; + } + + int convert_oserr(int ioerr) + { + extern int _OSERR; + + _OSERR = ioerr; + switch (ioerr) + { + case 0: return 0; + case ERROR_NO_FREE_STORE: return ENOMEM; + case ERROR_TASK_TABLE_FULL: return EAGAIN; + case ERROR_BAD_TEMPLATE: case ERROR_REQUIRED_ARG_MISSING: + case ERROR_KEY_NEEDS_ARG: case ERROR_TOO_MANY_ARGS: + case ERROR_UNMATCHED_QUOTES: case ERROR_LINE_TOO_LONG: return EINVAL; + case ERROR_OBJECT_IN_USE: return EBUSY; + case ERROR_OBJECT_EXISTS: return EEXIST; + case ERROR_DIR_NOT_FOUND: return ENOENT; + case ERROR_OBJECT_NOT_FOUND: return ENOENT; + case ERROR_BAD_STREAM_NAME: return EINVAL; + case ERROR_OBJECT_TOO_LARGE: return E2BIG; + case ERROR_ACTION_NOT_KNOWN: return EINVAL; + case ERROR_INVALID_COMPONENT_NAME: return EINVAL; + case ERROR_INVALID_LOCK: return EINVAL; + case ERROR_OBJECT_WRONG_TYPE: return EINVAL; + case ERROR_DISK_WRITE_PROTECTED: return EACCES; + case ERROR_SEEK_ERROR: return EIO; + case ERROR_DISK_FULL: return ENOSPC; + case ERROR_DELETE_PROTECTED: return EACCES; + case ERROR_WRITE_PROTECTED: return EACCES; + case ERROR_READ_PROTECTED: return EACCES; + case ERROR_RENAME_ACROSS_DEVICES: return EXDEV; + default: return EOSERR; + } + } + + printenv(void) + /* Effect: Prints a UNIX style environment from the AmigaDOS environment. + */ + { + struct LocalVar *scan_env; + struct Process *us = (struct Process *)FindTask(0); + + for (scan_env = (struct LocalVar *)us->pr_LocalVars.mlh_Head; + scan_env->lv_Node.ln_Succ; + scan_env = (struct LocalVar *)scan_env->lv_Node.ln_Succ) + if (scan_env->lv_Node.ln_Type == LV_VAR && + !(scan_env->lv_Flags & (GVF_GLOBAL_ONLY | GVF_BINARY_VAR))) + { + /* We only handle local text variables */ + printf("%s=", scan_env->lv_Node.ln_Name); + fwrite(scan_env->lv_Value, 1, scan_env->lv_Len, stdout); + putchar('\n'); + } + } + + void + setenv (var, val) + register char *var, *val; + { + if (val) SetVar(var, val, -1, LV_VAR | GVF_LOCAL_ONLY); + else DeleteVar(var, LV_VAR | GVF_LOCAL_ONLY); + } + + void + fatal (msg, arg1, arg2) + char *msg, *arg1, *arg2; + { + fprintf (stderr, "%s: ", progname); + fprintf (stderr, msg, arg1, arg2); + putc ('\n', stderr); + exit (1); + } + + + extern char *malloc (), *realloc (); + + void + memory_fatal () + { + fatal ("Out of memory"); + } + + char * + xmalloc (size) + int size; + { + register char *value; + value = (char *) malloc (size); + if (!value) memory_fatal (); + return (value); + } + + char * + xrealloc (ptr, size) + char *ptr; + int size; + { + register char *value; + value = (char *) realloc (ptr, size); + if (!value) memory_fatal (); + return (value); + } + + /* Return a newly-allocated string whose contents concatenate those of s1, s2, s3. */ + + char * + concat (s1, s2, s3) + char *s1, *s2, *s3; + { + int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3); + char *result = (char *) xmalloc (len1 + len2 + len3 + 1); + + strcpy (result, s1); + strcpy (result + len1, s2); + strcpy (result + len1 + len2, s3); + *(result + len1 + len2 + len3) = 0; + + return result; + } + + + /* + * Local variables: + * compile-command: "lc -L -v amiga-env.c" + * end: + */ diff -rcP emacs-18.59-fsf/etc/etags.c emacs-18.59-amiga/etc/etags.c *** emacs-18.59-fsf/etc/etags.c Thu Aug 20 05:11:01 1992 --- emacs-18.59-amiga/etc/etags.c Sun May 9 18:35:40 1993 *************** *** 338,347 **** --- 338,354 ---- { for (i=1; i%s -v '\t%s\t' OTAGS", outfile, av[i]); + system(cmd); + unlink("OTAGS"); + #else sprintf(cmd, "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS", outfile, av[i], outfile); system(cmd); + #endif } aflag++; } *************** *** 357,363 **** --- 364,374 ---- #ifndef VMS if (uflag) { + #ifdef AMIGA + sprintf(cmd, "c:sort from %s to %s", outfile, outfile); + #else sprintf(cmd, "sort %s -o %s", outfile, outfile); + #endif system(cmd); } #endif diff -rcP emacs-18.59-fsf/etc/make-docfile.c emacs-18.59-amiga/etc/make-docfile.c *** emacs-18.59-fsf/etc/make-docfile.c Fri Oct 25 18:43:28 1991 --- emacs-18.59-amiga/etc/make-docfile.c Sun May 9 18:35:46 1993 *************** *** 57,64 **** --- 57,86 ---- i += 2; } + #ifdef AMIGA + { + char fn[512], *fpos; + int c; + + c = getchar(); + do + { + while (c == ' ' || c == '\n' || c == '\t') c = getchar(); + if (c == EOF) break; + fpos = fn; + do *fpos++ = c; + while ((c = getchar()) != EOF && c != ' ' && c != '\t' && c != '\n'); + *fpos = 0; + + fprintf(stderr, "doc file %s\n", fn); + err_count += scan_file (fn); /* err_count seems to be {mis,un}used */ + } + while (1); + } + #else for (; i < argc; i++) err_count += scan_file (argv[i]); /* err_count seems to be {mis,un}used */ + #endif #ifndef VMS exit (err_count); /* see below - shane */ #endif /* VMS */ diff -rcP emacs-18.59-fsf/etc/sh.c emacs-18.59-amiga/etc/sh.c *** emacs-18.59-fsf/etc/sh.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/etc/sh.c Sat Jun 5 11:44:06 1993 *************** *** 0 **** --- 1,145 ---- + ;/* + SC LINK NOSTKCHK DEF SASC=1 sh.c + QUIT + */ + /* + * original version: David Gay + * + * 05/18/93 ch added SAS support, external verbose flag and primitive_parse + */ + #include + #include + #include + + #ifdef SASC + #include + #include + #endif + + #include + + /* + translates: + + echo "string1;string2" ; cd xx:c ; copy xx yy + + into + + echo "string1;string2" \n cd xx:c \n copy xx yy + + note: + this is a really primitive function ;-) , it may be + changed if necessary + + */ + + #define QUOTE '"' + + void primitive_parse(char *s) + { + int c; + + while(c = *s++) + { + if(c == QUOTE) + { + while((c = *s++) && (c != QUOTE)) + ; + if(!c) + break; + } + else if(c == ';') + *(s-1) = '\n'; + } + } + + int execute(char *cmd, int debug) + { + long rc; + char *s; + + while (*cmd == ' ') cmd++; + if (strncmp(cmd, "exec", 4) == 0 && (cmd[4] == ' ' || cmd[4] == '\t')) + cmd += 4; + + s = cmd; + primitive_parse(s); + + if(debug) + fprintf(stderr,"/etc/sh: preparsed line:\n%s\n", cmd); + + if ((rc = SystemTags(cmd, SYS_UserShell, TRUE, TAG_END)) == -1) + { + fprintf(stderr, "Failed to execute command %s\n", cmd); + return 20; + } + return rc; + } + + void main(int argc, char **argv) + { + int command; + char *command_string; + char *program_name = argv[0]; + struct RDArgs *args; + long opts[1]; + static char options[] = ""; + long debug = 0; + char *shenv; + + /* Throw out AmigaDOS args so that Input() is clean */ + if (args = ReadArgs(options, opts, NULL)) FreeArgs(args); + + shenv = getenv("EMACS_SH_DEBUG"); + + if(shenv) + if(strstr(shenv, "-v")) /* external verbose flag */ + debug = 1; + + command = 0; + /* Simplistic argument parsing */ + argv++; + argc--; + while (argc > 0 && argv[0][0] == '-') + { + switch (argv[0][1]) + { + case 'c': + if (argc == 1) goto usage; + command = 1; + command_string = argv[1]; + argv++; + argc--; + break; + case 'v': + debug = 1; + break; + case 'i': + /* ignored for now */ + break; + default: goto usage; + } + argc--; + argv++; + } + if (argc != 0) goto usage; + + if (command) + { + if(debug) + fprintf(stderr,"%s: command_string = %s\n", argv[0], command_string); + exit(execute(command_string, debug)); + } + else exit(Execute("", Input(), NULL) ? 0 : 1); + + usage: + fprintf(stderr, "%s [-i] [-v] [-c command]\n", program_name); + exit(1); + } + + + /* + * Local variables: + * compile-command: "sc link nostkchk def SASC=1 sh.c" + * end: + */ diff -rcP emacs-18.59-fsf/etc/smakefile emacs-18.59-amiga/etc/smakefile *** emacs-18.59-fsf/etc/smakefile Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/etc/smakefile Sat Oct 2 15:30:23 1993 *************** *** 0 **** --- 1,17 ---- + all: etags sh wakeup make-docfile # env + + env: amiga-env.c + echo "'sc link to env nostkchk amiga-env.c' should work (but doesn't)." + echo "You're welcome to try ..." + + make-docfile: make-docfile.c + sc link make-docfile.c + + sh: sh.c + sc link sh.c + + wakeup: wakeup.c + sc link wakeup.c + + etags: etags.c + sc link idir //unix/include def ETAGS etags.c lib //unix/src/unix.lib diff -rcP emacs-18.59-fsf/etc/termcap.amiga emacs-18.59-amiga/etc/termcap.amiga *** emacs-18.59-fsf/etc/termcap.amiga Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/etc/termcap.amiga Sun May 9 18:35:58 1993 *************** *** 0 **** --- 1,12 ---- + Amiga termcap by Kent Polk and David Gay + AA|amiga|Amiga ANSI:\ + :co#80:li#23:am:bs:bw:MT:\ + :AL=\E[%dL:DC=\E[%dP:DL=\E[%dM:DO=\E[%dB:IC=\E[%d@:\ + :LE=\E[%dD:RI=\E[%dC:SF=\E[%dS:SR=\E[%dT:UP=\E[%dA:\ + :ae=\017:al=\E[L:as=\016:bl=\007:bt=\E[Z:cd=\E[J:ce=\E[K:cl=\E[H\E[J:\ + :cm=\E[%i%d;%dH:dc=\E[P:dl=\E[M:do=\E[B:ho=\E[H:ic=\E[@:is=\E[20l:\ + :k1=\E0~:k2=\E1~:k3=\E2~:k4=\E3~:k5=\E4~:k6=\E5~:k7=\E6~:k8=\E7~:k9=\E8~:\ + :k0=\E9~:kb=^H:kd=\EB:kl=\ED:kr=\EC:ku=\EA:le=\E[D:\ + :mb=\E[7;2m:md=\E[1m:me=\E[0m:mh=\E[2m:mk=\E[8m:mr=\E[7m:nd=\E[C:nl=\E[B:\ + :rs=\Ec:se=\E[0m:sf=\E[S:so=\E[7m:sr=\E[T:ue=\E[0m:up=\E[A:us=\E[4m:\ + :ve=\E[\040p:vi=\E[\060\040p:xn: diff -rcP emacs-18.59-fsf/etc/wakeup.c emacs-18.59-amiga/etc/wakeup.c *** emacs-18.59-fsf/etc/wakeup.c Tue Jul 30 21:03:39 1991 --- emacs-18.59-amiga/etc/wakeup.c Sun May 9 18:36:20 1993 *************** *** 18,28 **** --- 18,34 ---- while (1) { + #ifdef AMIGA + if (Write(Output(), "Wake up!\n", 9) != 9) exit(0); + chkabort(); + #define sleep(n) Delay(50 * (n)) + #else /* Make sure wakeup stops when Emacs goes away. */ if (getppid () == 1) exit (0); printf ("Wake up!\n"); fflush (stdout); + #endif /* If using a period of 60, produce the output when the minute changes. */ if (period == 60) diff -rcP emacs-18.59-fsf/lisp/amiga-init.el emacs-18.59-amiga/lisp/amiga-init.el *** emacs-18.59-fsf/lisp/amiga-init.el Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/lisp/amiga-init.el Sat Jun 5 11:35:42 1993 *************** *** 0 **** --- 1,206 ---- + (global-set-key "\C-z" 'amiga-iconify) + (setq amiga-map (make-keymap)) + (global-set-key "\C-x\C-^" amiga-map) + + (load "amiga-mouse") + (load "amiga-menu") + + (define-key amiga-map "A" 'previous-line) + (define-key amiga-map "B" 'next-line) + (define-key amiga-map "D" 'backward-char) + (define-key amiga-map "C" 'forward-char) + (define-key amiga-map "?~" 'info) + (define-key amiga-map "T" 'scroll-down) + (define-key amiga-map "S" 'scroll-up) + (define-key amiga-map " @" 'forward-word) + (define-key amiga-map " A" 'backward-word) + (define-key amiga-map "\M-A" 'beginning-of-buffer) + (define-key amiga-map "\M-B" 'end-of-buffer) + (define-key amiga-map "\M-D" 'beginning-of-line) + (define-key amiga-map "\M-C" 'end-of-line) + (define-key amiga-map "\M- \M-@" 'forward-sexp) + (define-key amiga-map "\M- \M-A" 'backward-sexp) + (define-key amiga-map "\M-T" 'scroll-down-1) + (define-key amiga-map "\M-S" 'scroll-up-1) + ; Keypad sequences are handled like normal ones + (define-key amiga-map "K" 'do-nothing) + + (defun do-nothing () (interactive)) + + (defun scroll-down-1 () + "Move up one line on screen" + (interactive) + (scroll-down 1)) + + (defun scroll-up-1 () + "Move down one line on screen" + (interactive) + (scroll-up 1)) + + ;; ARexx stuff + + ;;; This function needs to be re-written to handle rexx returned results. + ;;; + (setq amiga-arexx-processing nil) + (setq amiga-arexx-errors nil) + + (defvar amiga-arexx-failat 5 + "Return level from which arexx commands returns cause errors") + + ;; + ;; process incoming rexx messages + ;; + (defun amiga-arexx-process () + (interactive) + (if (not amiga-arexx-processing) + (progn + (setq amiga-arexx-processing t) + (condition-case nil ; Avoid blocking of processing in case of bugs + (let (arexxcmd) + (while (setq arexxcmd (amiga-arexx-get-next-msg)) + (let ((rc 0) result) + (condition-case err ; detect errors in arexx command + (let ((expr (car (read-from-string arexxcmd)))) + (setq result (prin1-to-string (eval expr)))) + (error (progn + (setq rc 20) + (setq result (prin1-to-string err))))) + (amiga-arexx-reply rc result)))) + (error nil)) + (setq amiga-arexx-processing nil)))) + + (defun amiga-arexx-wait-command (id) + "Waits for a pending ARexx commands (MSGID) to complete. + Also processes any pending ARexx requests during this interval. + returns the result list associated with this id, which takes the + form: (msgid result-code error-or-string) + ``error-or-string'' depends on ``result-code''. + if ``result-code'' is 0 the command finished successfully and + ``error-or-string'' will be a string or nil, otherwise the command + returned with an error and ``error-or-string'' will be an interger + that is the secondary error code of the arexx command." + (amiga-arexx-process) + (while (not (amiga-arexx-check-command id)) + (amiga-arexx-wait) + (amiga-arexx-process)) + (amiga-arexx-get-msg-results id)) + + (defconst amiga-arexx-error-messages + ["No cause" + "Program not found" + "Execution halted" + "Insufficient memory" + "Invalid character" + "Unmatched quote" + "Unterminated comment" + "Clause too long" + "Invalid token" + "Symbol or string too long" + "Invalid message packet" + "Command string error" + "Error return from function" + "Host environment not found" + "Requested library not found" + "Function not found" + "Function did not return value" + "Wrong number of arguments" + "Invalid argument to function" + "Invalid PROCEDURE" + "Unexpected THEN or WHEN" + "Unexpected ELSE or OTHERWISE" + "Unexpected BREAK, LEAVE or ITERATE" + "Invalid statement in SELECT" + "Missing or multiple THEN" + "Missing OTHERWISE" + "Missing or unexpected END" + "Symbol mismatch" + "Invalid DO syntax" + "Incomplete IF or SELECT" + "Label not found" + "Symbol expected" + "Symbol or string expected" + "Invalid keyword" + "Required keyword missing" + "Extraneous characters" + "Keyword conflict" + "Invalid template" + "Invalid TRACE request" + "Unitialized variable" + "Invalid variable name" + "Invalid expression" + "Unbalanced parentheses" + "Nesting limit exceeded" + "Invalid expression result" + "Expression required" + "Boolean value not 0 or 1" + "Arithmetic conversion error" + "Invalid operand" + ] + "The arexx error messages, sorted by number") + + (defun amiga-arexx-do-command (str as-file) + "Sends ARexx command STR (like amiga-arexx-send-command). + If AS-FILE is true, STR is an arexx command, otherwise it is a file name. + Waits for the command to return. If the arexx command fails an error will + be caused. + + If you would like to get result strings and errors (ie. not cause + a lisp error) use: (amiga-arexx-do-command-with-results)" + (interactive "sARexx command: + P") + (let ((id (amiga-arexx-send-command str as-file))) + (if (not id) + (error "Failed to send arexx command.") + (let ((reslist (amiga-arexx-wait-command id))) + (let ((rc (nth 1 reslist)) (second (nth 2 reslist))) + (if (> rc 0) + (progn ; error + (let ((error-message + (if (< second (length amiga-arexx-error-messages)) + (aref amiga-arexx-error-messages second) + (format nil "Unknown error %d" second)))) + (error "Arexx command failed, level %d, cause %s" rc error-message)) + reslist) + second)))))) + + (defun amiga-arexx-do-command-with-results (str as-file) + "Sends ARexx command STR (like amiga-arexx-do-command). + If AS-FILE is true, STR is an arexx command, otherwise it is a file name. + Waits for the command to return. + + The return value is one of three things: + - the command executed succesfully: nil or a result string. + - the command failed: a list of the form (RC ERROR-CODE) + where RC is the severity and ERROR-CODE is the secondary error." + (interactive "sARexx command: + P") + (let ((id (amiga-arexx-send-command str as-file))) + (if (not id) + (error "Failed to send arexx command.") + (let ((reslist (amiga-arexx-wait-command id))) + (let ((rc (nth 1 reslist)) (second (nth 2 reslist))) + (if (and rc (> rc 0)) + (list rc second) + second)))))) + + (define-key amiga-map "X" 'amiga-arexx-process) + (setq amiga-arexx-initialized t) ;; ARexx commands can now be processed. + + (defun amiga-wb-process () + "Process all pending workbench events, ie load all files requested" + (interactive) + (let (file) + (condition-case nil + (while (setq file (amiga-get-wb-event t)) + (condition-case nil + (find-file file) + (error nil))) + (error nil)))) + + (define-key amiga-map "W" 'amiga-wb-process) + (setq amiga-wb-initialized t) ;; WB events can now be processed. + + (setq completion-ignore-case t) + ;; Default is no numbered versions on Amiga, because directory searches are too + ;; slow. + (setq version-control 'never) Binary files emacs-18.59-fsf/lisp/amiga-init.elc and emacs-18.59-amiga/lisp/amiga-init.elc differ diff -rcP emacs-18.59-fsf/lisp/amiga-menu.el emacs-18.59-amiga/lisp/amiga-menu.el *** emacs-18.59-fsf/lisp/amiga-menu.el Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/lisp/amiga-menu.el Sat Nov 21 16:13:18 1992 *************** *** 0 **** --- 1,135 ---- + ;(provide 'amiga-menu) + + (defconst amiga-menu-pick (char-to-string 3)) + (defconst amiga-menu-help (char-to-string 7)) + + (defvar amiga-menus-description nil + "Variable containing the menus setup for Emacs") + + (defun amiga-menus-set (menus) + "Setup menus for emacs (parameter as for amiga-menus)" + (define-key mouse-map amiga-menu-pick 'amiga-menus-dispatch) + (define-key mouse-map amiga-menu-help 'amiga-menus-help) + (setq amiga-menus-description menus) + (amiga-menus menus)) + + (defun amiga-menus-dispatch (selection) + (let* ((menu (car selection)) + (item (cadr selection)) + (code (cadr (nth item (cadr (nth menu amiga-menus-description)))))) + (if (and (listp code) (eq (car code) 'call-interactively) + (listp (cadr code)) (eq (car (cadr code)) 'quote)) + (setq this-command (cadr (cadr code)))) + (eval code))) + + (defun amiga-menus-help (selection) + (let* ((menu (car selection)) + (item (cadr selection)) + (cmd (cadr (nth item (cadr (nth menu amiga-menus-description)))))) + (if (and (listp cmd) (eq (car cmd) 'call-interactively) + (listp (car (cdr cmd))) (eq (car (car (cdr cmd))) 'quote)) + (describe-function (car (cdr (car (cdr cmd))))) + (error "Don't know how to describe %s" cmd)))) + + (defun make-explicit-string (str) + (if (and (>= (length str) 2) (= (elt str 0) 27) (< (elt str 1) 128)) + (key-description (concat (char-to-string (+ 128 (elt str 1))) + (substring str 2))) + (key-description str))) + + (defun make-command-name (command str width) + (let ((keys (where-is-internal command nil t)) + (string (if str str (symbol-name command)))) + (if keys + (format (if width (format "%%-%ds%%s" (+ width 2)) "%s (%s)") + string (make-explicit-string keys)) + string))) + + (defun menu-items (commands proportional) + (let* ((width (if proportional nil 0)) + (names (mapcar + (function (lambda (cmd) + (if cmd + (let* ((name (if (symbolp cmd) + (symbol-name cmd) + (car cmd))) + (len (length name))) + (if (and (not proportional) (> len width)) + (setq width len)) + name)))) + commands))) + (mapcar + (function (lambda (cmd) + (let ((name (car names))) + (setq names (cdr names)) + (if cmd + (let ((command (if (symbolp cmd) cmd (cadr cmd)))) + (list (make-command-name command name width) + (list 'call-interactively (list 'quote command)) + (caddr cmd))))))) + commands))) + + (defun convert-menu-buffer (proportional) + "Convert the current buffer into a loadable menu file for emacs.\n\ + If PROPORTIONAL is true (or if a prefix arg is given), assume menu is in a \n\ + proportional font & present it differently." + (interactive "P") + (save-buffer) + (widen) + (goto-char 1) + (let ((menu-spec (reverse (read (current-buffer)))) + menu-code) + (while menu-spec + (let ((menu-item (car menu-spec))) + (setq menu-code + (cons (list (car menu-item) + (menu-items (cdr menu-item) proportional)) + menu-code)) + (setq menu-spec (cdr menu-spec)))) + (let ((new-buf + (find-file (concat + (substring (buffer-file-name) 0 + (string-match "\\.menu$" (buffer-file-name))) + ".el")))) + (erase-buffer) + (prin1 (list 'amiga-menus-set (list 'quote menu-code)) (current-buffer)) + (beginning-of-buffer)))) + + (defvar menu-mode-syntax-table nil + "Syntax table used while in menu mode.") + + (defvar menu-mode-abbrev-table nil + "Abbrev table used while in menu mode.") + (define-abbrev-table 'menu-mode-abbrev-table ()) + + (if menu-mode-syntax-table + () + (setq menu-mode-syntax-table (make-syntax-table)) + (modify-syntax-entry ?' "w " menu-mode-syntax-table)) + + (defvar menu-mode-map ()) + (if menu-mode-map + () + (setq menu-mode-map (make-sparse-keymap)) + (define-key menu-mode-map "\t" 'indent-relative) + (define-key menu-mode-map "\C-c\C-c" 'convert-menu-buffer)) + + (defun menu-mode () + "Major mode for editing menus intended for humans to read. + Indentation works like in indented-text-mode. This could be improved.\\{menu-mode-map} + Turning on menu-mode calls the value of the variable menu-mode-hook, + if that value is non-nil." + (interactive) + (kill-all-local-variables) + (use-local-map menu-mode-map) + (define-abbrev-table 'menu-mode-abbrev-table ()) + (setq local-abbrev-table menu-mode-abbrev-table) + (set-syntax-table menu-mode-syntax-table) + (make-local-variable 'indent-line-function) + (setq indent-line-function 'indent-relative-maybe) + (use-local-map menu-mode-map) + (setq mode-name "Menu") + (setq major-mode 'menu-mode) + (run-hooks 'menu-mode-hook)) + + (setq auto-mode-alist (cons '("\\.menu$" . menu-mode) auto-mode-alist)) Binary files emacs-18.59-fsf/lisp/amiga-menu.elc and emacs-18.59-amiga/lisp/amiga-menu.elc differ diff -rcP emacs-18.59-fsf/lisp/amiga-mouse.el emacs-18.59-amiga/lisp/amiga-mouse.el *** emacs-18.59-fsf/lisp/amiga-mouse.el Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/lisp/amiga-mouse.el Sat Nov 21 16:13:20 1992 *************** *** 0 **** --- 1,276 ---- + ;; Mouse support for Amiga Intuition window system. + ;; Copyright (C) 1985, 1987 Free Software Foundation, Inc. + + ;; This file is part of GNU Emacs. + + ;; GNU Emacs is distributed in the hope that it will be useful, + ;; but WITHOUT ANY WARRANTY. No author or distributor + ;; accepts responsibility to anyone for the consequences of using it + ;; or for whether it serves any particular purpose or works at all, + ;; unless he says so in writing. Refer to the GNU Emacs General Public + ;; License for full details. + + ;; Everyone is granted permission to copy, modify and redistribute + ;; GNU Emacs, but only under the conditions described in the + ;; GNU Emacs General Public License. A copy of this license is + ;; supposed to have been given to you along with GNU Emacs so you + ;; can know your rights and responsibilities. It should be in a + ;; file named COPYING. Among other things, the copyright notice + ;; and this notice must be preserved on all copies. + + (provide 'amiga-mouse) + + (defconst amiga-button-right (char-to-string 0)) + (defconst amiga-button-middle (char-to-string 1)) + (defconst amiga-button-left (char-to-string 2)) + + (defconst amiga-button-right-up (char-to-string 4)) + (defconst amiga-button-middle-up (char-to-string 5)) + (defconst amiga-button-left-up (char-to-string 6)) + + (defconst amiga-button-s-right (char-to-string 16)) + (defconst amiga-button-s-middle (char-to-string 17)) + (defconst amiga-button-s-left (char-to-string 18)) + + (defconst amiga-button-s-right-up (char-to-string 20)) + (defconst amiga-button-s-middle-up (char-to-string 21)) + (defconst amiga-button-s-left-up (char-to-string 22)) + + (defconst amiga-button-m-right (char-to-string 32)) + (defconst amiga-button-m-middle (char-to-string 33)) + (defconst amiga-button-m-left (char-to-string 34)) + + (defconst amiga-button-m-right-up (char-to-string 36)) + (defconst amiga-button-m-middle-up (char-to-string 37)) + (defconst amiga-button-m-left-up (char-to-string 38)) + + (defconst amiga-button-c-right (char-to-string 64)) + (defconst amiga-button-c-middle (char-to-string 65)) + (defconst amiga-button-c-left (char-to-string 66)) + + (defconst amiga-button-c-right-up (char-to-string 68)) + (defconst amiga-button-c-middle-up (char-to-string 69)) + (defconst amiga-button-c-left-up (char-to-string 70)) + + (defconst amiga-button-m-s-right (char-to-string 48)) + (defconst amiga-button-m-s-middle (char-to-string 49)) + (defconst amiga-button-m-s-left (char-to-string 50)) + + (defconst amiga-button-m-s-right-up (char-to-string 52)) + (defconst amiga-button-m-s-middle-up (char-to-string 53)) + (defconst amiga-button-m-s-left-up (char-to-string 54)) + + (defconst amiga-button-c-s-right (char-to-string 80)) + (defconst amiga-button-c-s-middle (char-to-string 81)) + (defconst amiga-button-c-s-left (char-to-string 82)) + + (defconst amiga-button-c-s-right-up (char-to-string 84)) + (defconst amiga-button-c-s-middle-up (char-to-string 85)) + (defconst amiga-button-c-s-left-up (char-to-string 86)) + + (defconst amiga-button-c-m-right (char-to-string 96)) + (defconst amiga-button-c-m-middle (char-to-string 97)) + (defconst amiga-button-c-m-left (char-to-string 98)) + + (defconst amiga-button-c-m-right-up (char-to-string 100)) + (defconst amiga-button-c-m-middle-up (char-to-string 101)) + (defconst amiga-button-c-m-left-up (char-to-string 102)) + + (defconst amiga-button-c-m-s-right (char-to-string 112)) + (defconst amiga-button-c-m-s-middle (char-to-string 113)) + (defconst amiga-button-c-m-s-left (char-to-string 114)) + + (defconst amiga-button-c-m-s-right-up (char-to-string 116)) + (defconst amiga-button-c-m-s-middle-up (char-to-string 117)) + (defconst amiga-button-c-m-s-left-up (char-to-string 118)) + + (defmacro cadr (x) (list 'car (list 'cdr x))) + (defmacro caddr (x) (list 'car (list 'cdr (list 'cdr x)))) + (defmacro cadddr (x) (list 'car (list 'cdr (list 'cdr (list 'cdr x))))) + + (defun coordinates-in-window-p (arg w) + (let ((x (car arg)) + (y (cadr arg)) + (edges (window-edges w))) + (and (>= x (car edges)) (< x (caddr edges)) + (>= y (cadr edges)) (< y (cadddr edges)) + (list (- x (car edges)) (- y (cadr edges)))))) + + (defvar amiga-process-mouse-hook nil + "Hook to run after each mouse event is processed. Should take two + arguments; the first being a list (XPOS YPOS) corresponding to character + offset from top left of screen and the second being a specifier for the + buttons/keys. + + This will normally be set on a per-buffer basis.") + + (defun amiga-flush-mouse-queue () + "Process all queued mouse events." + ;; A mouse event causes a special character sequence to be given + ;; as keyboard input. That runs this function, which process all + ;; queued mouse events and returns. + (interactive) + (while (> (amiga-mouse-events) 0) + (amiga-proc-mouse-event) + (and (boundp 'amiga-process-mouse-hook) + (symbol-value 'amiga-process-mouse-hook) + (funcall amiga-process-mouse-hook amiga-mouse-pos amiga-mouse-item)))) + + (defun amiga-mouse-select (arg) + "Select Emacs window the mouse is on." + (let ((start-w (selected-window)) + (done nil) + (w (selected-window)) + (rel-coordinate nil)) + (if (eq start-w (minibuffer-window)) + (setq rel-coordinate (coordinates-in-window-p arg w)) + (while (and (not done) + (null (setq rel-coordinate + (coordinates-in-window-p arg w)))) + (setq w (next-window w)) + (if (eq w start-w) + (setq done t)))) + (select-window w) + rel-coordinate)) + + (defun amiga-mouse-keep-one-window (arg) + "Select Emacs window mouse is on, then kill all other Emacs windows." + (if (amiga-mouse-select arg) + (delete-other-windows))) + + (defun amiga-mouse-select-and-split (arg) + "Select Emacs window mouse is on, then split it vertically in half." + (if (amiga-mouse-select arg) + (split-window-vertically nil))) + + + (defun amiga-mouse-set-point (arg) + "Select Emacs window mouse is on, and move point to mouse position." + (let* ((relative-coordinate (amiga-mouse-select arg)) + margin-column + (rel-x (car relative-coordinate)) + (rel-y (car (cdr relative-coordinate)))) + (if relative-coordinate + (let ((prompt-width (if (eq (selected-window) (minibuffer-window)) + minibuffer-prompt-width 0))) + (move-to-window-line rel-y) + (setq margin-column + (if (or truncate-lines (> (window-hscroll) 0)) + (current-column) + ;; If we are using line continuation, + ;; compensate if first character on a continuation line + ;; does not start precisely at the margin. + (- (current-column) + (% (current-column) (1- (window-width)))))) + (move-to-column (+ rel-x (1- (max 1 (window-hscroll))) + (if (= (point) 1) + (- prompt-width) 0) + margin-column)))))) + + (defun amiga-mouse-set-mark (arg) + "Select Emacs window mouse is on, and set mark at mouse position. + Display cursor at that position for a second." + (if (amiga-mouse-select arg) + (let ((point-save (point))) + (unwind-protect + (progn (amiga-mouse-set-point arg) + (push-mark nil t) + (sit-for 1)) + (goto-char point-save))))) + + (defun amiga-mouse-cut (arg) + "Select Emacs window mouse is on, and set mark at mouse position. + Display cursor at that position for a second. Then cut." + (if (amiga-mouse-select arg) + (let ((point-save (point))) + (unwind-protect + (progn (amiga-mouse-set-point arg) + (push-mark nil t) + (kill-region point-save (point)) + (sit-for 1)) + (goto-char point-save))))) + + (defun amiga-mouse-copy (arg) + "Select Emacs window mouse is on, and set mark at mouse position. + Display cursor at that position for a second. Then copy." + (if (amiga-mouse-select arg) + (let ((point-save (point))) + (unwind-protect + (progn (amiga-mouse-set-point arg) + (push-mark nil t) + (copy-region-as-kill point-save (point)) + (sit-for 1)) + (goto-char point-save))))) + + (defun amiga-mouse-paste (arg) + "Move point to mouse position (and select window), then paste." + (if (amiga-mouse-select arg) + (progn + (amiga-mouse-set-point arg) + (yank)))) + + (defun amiga-mouse-iconify (arg) (amiga-iconify)) + + (defun amiga-mouse-ignore (arg) + "Don't do anything.") + + ; Prevent beeps. on button-up. If the button isn't bound to anything, it + (define-key mouse-map amiga-button-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-s-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-m-s-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-s-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-left-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-right 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-middle 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-left 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-right-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-middle-up 'amiga-mouse-ignore) + (define-key mouse-map amiga-button-c-m-s-left-up 'amiga-mouse-ignore) + + ; Define a few events + (define-key mouse-map amiga-button-left 'amiga-mouse-set-point) + (define-key mouse-map amiga-button-s-left 'amiga-mouse-set-mark) + (define-key mouse-map amiga-button-c-left 'amiga-mouse-cut) + (define-key mouse-map amiga-button-m-left 'amiga-mouse-copy) + (define-key mouse-map amiga-button-middle 'amiga-mouse-paste) + (define-key mouse-map amiga-button-s-middle 'amiga-mouse-iconify) + + (define-key amiga-map "M" 'amiga-flush-mouse-queue) + (setq amiga-mouse-initialized t) ;; Mouse commands can now be processed. Binary files emacs-18.59-fsf/lisp/amiga-mouse.elc and emacs-18.59-amiga/lisp/amiga-mouse.elc differ diff -rcP emacs-18.59-fsf/lisp/compile.el emacs-18.59-amiga/lisp/compile.el *** emacs-18.59-fsf/lisp/compile.el Fri Aug 14 22:53:00 1992 --- emacs-18.59-amiga/lisp/compile.el Thu Dec 24 17:06:50 1992 *************** *** 43,49 **** ;; The filename excludes colons to avoid confusion when error message ;; starts with digits. (defvar compilation-error-regexp ! "\\([^ :\n]+\\(: *\\|, line \\|(\\)[0-9]+\\)\\|\\([0-9]+ *of *[^ \n]+\\)" "Regular expression for filename/linenumber in error in compilation log.") (defun compile (command) --- 43,49 ---- ;; The filename excludes colons to avoid confusion when error message ;; starts with digits. (defvar compilation-error-regexp ! "^\\([^ :\e]+\\([ :] *\\|, line \\|(\\)[0-9]+\\)\\|\\([0-9]+ *of *[^ \n]+\\)" "Regular expression for filename/linenumber in error in compilation log.") (defun compile (command) *************** *** 61,67 **** While grep runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to." (interactive "sRun grep (with args): ") ! (compile1 (concat "grep -n " command " /dev/null") "No more grep hits" "grep")) (defun compile1 (command error-message &optional name-of-mode) --- 61,68 ---- While grep runs asynchronously, you can use the \\[next-error] command to find the text that grep hits refer to." (interactive "sRun grep (with args): ") ! (compile1 (concat "grep -n " command (if (eq system-type 'amigados) " nil:" ! " /dev/null")) "No more grep hits" "grep")) (defun compile1 (command error-message &optional name-of-mode) *************** *** 195,201 **** (let* ((pop-up-windows t) (w (display-buffer (marker-buffer (car next-error))))) (set-window-point w (car next-error)) ! (set-window-start w (car next-error))) (set-marker (car next-error) nil))) ;; Set compilation-error-list to nil, and --- 196,208 ---- (let* ((pop-up-windows t) (w (display-buffer (marker-buffer (car next-error))))) (set-window-point w (car next-error)) ! (if compilation-parse-sasc ! (let ((thiswin (selected-window))) ! (select-window w) ! (vertical-motion -1) ! (set-window-start w (point)) ! (select-window thiswin)) ! (set-window-start w (car next-error)))) (set-marker (car next-error) nil))) ;; Set compilation-error-list to nil, and *************** *** 222,227 **** --- 229,236 ---- and visits its location." (setq compilation-error-list nil) (message "Parsing error messages...") + (goto-char (point-min)) + (setq compilation-parse-sasc (search-forward "SAS/C" nil t)) (let (text-buffer last-filename last-linenum) ;; Don't reparse messages already seen at last parse. Binary files emacs-18.59-fsf/lisp/compile.elc and emacs-18.59-amiga/lisp/compile.elc differ diff -rcP emacs-18.59-fsf/lisp/files.el emacs-18.59-amiga/lisp/files.el *** emacs-18.59-fsf/lisp/files.el Sun Oct 11 22:27:38 1992 --- emacs-18.59-amiga/lisp/files.el Sat Nov 21 16:14:10 1992 *************** *** 141,146 **** --- 141,156 ---- after you find a file. If you explicitly request such a scan with \\[normal-mode], there is no query, regardless of this variable.") + (defconst backup-char (if (eq system-type 'amigados) "!" "~") + "Character to add to file names to make backup names.") + + (defconst autosave-char (if (eq system-type 'amigados) "@" "#") + "Character to add to file names to make autosave names.") + + (defconst bufferfile-char (if (eq system-type 'amigados) "^" "%") + "Character to add to buffer names to make file names.") + + ;; Avoid losing in versions where CLASH_DETECTION is disabled. (or (fboundp 'lock-buffer) (fset 'lock-buffer 'ignore)) *************** *** 380,386 **** (funcall (intern (concat (downcase mode) "-mode"))) (let ((alist auto-mode-alist) (name buffer-file-name)) ! (let ((case-fold-search (eq system-type 'vax-vms))) ;; Remove backup-suffixes from file name. (setq name (file-name-sans-versions name)) ;; Find first matching alist entry. --- 390,397 ---- (funcall (intern (concat (downcase mode) "-mode"))) (let ((alist auto-mode-alist) (name buffer-file-name)) ! (let ((case-fold-search (or (eq system-type 'amigados) ! (eq system-type 'vax-vms)))) ;; Remove backup-suffixes from file name. (setq name (file-name-sans-versions name)) ;; Find first matching alist entry. *************** *** 559,566 **** (setq setmodes (file-modes backupname))) (file-error ;; If trouble writing the backup, write it in ~. ! (setq backupname (expand-file-name "~/%backup%~")) ! (message "Cannot write backup file; backing up in ~/%%backup%%~") (sleep-for 1) (condition-case () (delete-file backupname) --- 570,580 ---- (setq setmodes (file-modes backupname))) (file-error ;; If trouble writing the backup, write it in ~. ! (setq backupname ! (expand-file-name (concat "~/" bufferfile-char "backup" ! bufferfile-char backup-char))) ! (message "Cannot write backup file; backing up in ~/%sbackup%s%s" ! bufferfile-char bufferfile-char backup-char) (sleep-for 1) (condition-case () (delete-file backupname) *************** *** 588,605 **** (or (string-match ";[0-9]*\\'" name) (and (string-match "\\." name (string-match "[]>]" name)) (string-match "\\.[0-9]*\\'" name (match-end 0)))) ! (string-match "\\(\\.~[0-9]+\\)?~\\'" name)))) (defun make-backup-file-name (file) "Create the non-numeric backup file name for FILE. This is a separate function so you can redefine it for customization." ! (concat file "~")) (defun backup-file-name-p (file) "Return non-nil if FILE is a backup file name (numeric or not). This is a separate function so you can redefine it for customization. You may need to redefine file-name-sans-versions as well." ! (string-match "~$" file)) ;; I believe there is no need to alter this behavior for VMS; ;; since backup files are not made on VMS, it should not get called. --- 602,620 ---- (or (string-match ";[0-9]*\\'" name) (and (string-match "\\." name (string-match "[]>]" name)) (string-match "\\.[0-9]*\\'" name (match-end 0)))) ! (string-match (concat "\\(\\." backup-char "[0-9]+\\)?" ! backup-char "\\'") name)))) (defun make-backup-file-name (file) "Create the non-numeric backup file name for FILE. This is a separate function so you can redefine it for customization." ! (concat file backup-char)) (defun backup-file-name-p (file) "Return non-nil if FILE is a backup file name (numeric or not). This is a separate function so you can redefine it for customization. You may need to redefine file-name-sans-versions as well." ! (string-match (concat backup-char "$") file)) ;; I believe there is no need to alter this behavior for VMS; ;; since backup files are not made on VMS, it should not get called. *************** *** 609,615 **** and whose cdr is a list of old versions to consider deleting now." (if (eq version-control 'never) (list (make-backup-file-name fn)) ! (let* ((base-versions (concat (file-name-nondirectory fn) ".~")) (bv-length (length base-versions)) (possibilities (file-name-all-completions base-versions --- 624,630 ---- and whose cdr is a list of old versions to consider deleting now." (if (eq version-control 'never) (list (make-backup-file-name fn)) ! (let* ((base-versions (concat (file-name-nondirectory fn) "." backup-char)) (bv-length (length base-versions)) (possibilities (file-name-all-completions base-versions *************** *** 626,645 **** kept-old-versions kept-new-versions -1))) (if (not deserve-versions-p) (list (make-backup-file-name fn)) ! (cons (concat fn ".~" (int-to-string (1+ high-water-mark)) "~") (if (and (> number-to-delete 0) ;; Delete nothing if there is overflow ;; in the number of versions to keep. (>= (+ kept-new-versions kept-old-versions -1) 0)) (mapcar (function (lambda (n) ! (concat fn ".~" ! (int-to-string n) "~"))) (let ((v (nthcdr kept-old-versions versions))) (rplacd (nthcdr (1- number-to-delete) v) ()) v)))))))) (defun backup-extract-version (fn) ! (if (and (string-match "[0-9]+~$" fn bv-length) (= (match-beginning 0) bv-length)) (string-to-int (substring fn bv-length -1)) 0)) --- 641,661 ---- kept-old-versions kept-new-versions -1))) (if (not deserve-versions-p) (list (make-backup-file-name fn)) ! (cons (concat fn "." backup-char (int-to-string (1+ high-water-mark)) ! backup-char) (if (and (> number-to-delete 0) ;; Delete nothing if there is overflow ;; in the number of versions to keep. (>= (+ kept-new-versions kept-old-versions -1) 0)) (mapcar (function (lambda (n) ! (concat fn "." backup-char ! (int-to-string n) backup-char))) (let ((v (nthcdr kept-old-versions versions))) (rplacd (nthcdr (1- number-to-delete) v) ()) v)))))))) (defun backup-extract-version (fn) ! (if (and (string-match (concat "[0-9]+" backup-char "$") fn bv-length) (= (match-beginning 0) bv-length)) (string-to-int (substring fn bv-length -1)) 0)) *************** *** 741,747 **** ;; If file is precious, rename it away before ;; overwriting it. (let ((rename t) nodelete ! (file (concat buffer-file-name "#"))) (condition-case () (progn (rename-file buffer-file-name file t) (setq setmodes (file-modes file))) --- 757,763 ---- ;; If file is precious, rename it away before ;; overwriting it. (let ((rename t) nodelete ! (file (concat buffer-file-name autosave-char))) (condition-case () (progn (rename-file buffer-file-name file t) (setq setmodes (file-modes file))) *************** *** 774,779 **** --- 790,798 ---- ;; Change the mode back, after writing. (setq setmodes (file-modes buffer-file-name)) (set-file-modes buffer-file-name 511))) + (if (eq system-type 'amigados) + (if amiga-create-icons + (amiga-put-icon buffer-file-name nil))) (write-region (point-min) (point-max) buffer-file-name nil t))))) (if setmodes *************** *** 983,998 **** See also auto-save-file-name-p." (if buffer-file-name (concat (file-name-directory buffer-file-name) ! "#" (file-name-nondirectory buffer-file-name) ! "#") ! (expand-file-name (concat "#%" (buffer-name) "#")))) (defun auto-save-file-name-p (filename) "Return non-nil if FILENAME can be yielded by make-auto-save-file-name. FILENAME should lack slashes. You can redefine this for customization." ! (string-match "^#.*#$" filename)) (defconst list-directory-brief-switches "-CF" "*Switches for list-directory to pass to `ls' for brief listing,") --- 1002,1018 ---- See also auto-save-file-name-p." (if buffer-file-name (concat (file-name-directory buffer-file-name) ! autosave-char (file-name-nondirectory buffer-file-name) ! autosave-char) ! (expand-file-name (concat autosave-char bufferfile-char (buffer-name) ! autosave-char)))) (defun auto-save-file-name-p (filename) "Return non-nil if FILENAME can be yielded by make-auto-save-file-name. FILENAME should lack slashes. You can redefine this for customization." ! (string-match (concat "^" autosave-char ".*" autosave-char "$") filename)) (defconst list-directory-brief-switches "-CF" "*Switches for list-directory to pass to `ls' for brief listing,") Binary files emacs-18.59-fsf/lisp/files.elc and emacs-18.59-amiga/lisp/files.elc differ diff -rcP emacs-18.59-fsf/lisp/loadup.el emacs-18.59-amiga/lisp/loadup.el *** emacs-18.59-fsf/lisp/loadup.el Wed May 13 19:42:48 1992 --- emacs-18.59-amiga/lisp/loadup.el Sat Nov 21 16:14:52 1992 *************** *** 28,34 **** (load "simple") (garbage-collect) (load "help") - (garbage-collect) (load "files") (garbage-collect) (load "indent") --- 28,33 ---- *************** *** 64,69 **** --- 63,72 ---- (progn (garbage-collect) (load "vms-patch"))) + (if (eq system-type 'amigados) + (progn + (garbage-collect) + (load "amiga-init"))) ;If you want additional libraries to be preloaded and their ;doc strings kept in the DOC file rather than in core, diff -rcP emacs-18.59-fsf/lisp/simple.el emacs-18.59-amiga/lisp/simple.el *** emacs-18.59-fsf/lisp/simple.el Wed Apr 15 08:13:32 1992 --- emacs-18.59-amiga/lisp/simple.el Sat Nov 21 16:16:00 1992 *************** *** 539,549 **** (defvar kill-ring-yank-pointer nil "The tail of the kill ring whose car is the last thing yanked.") (defun kill-append (string before-p) (setcar kill-ring (if before-p (concat string (car kill-ring)) ! (concat (car kill-ring) string)))) (defun kill-region (beg end) "Kill between point and mark. --- 539,585 ---- (defvar kill-ring-yank-pointer nil "The tail of the kill ring whose car is the last thing yanked.") + (if (eq system-type 'amigados) + (progn + (defun safe-amiga-paste () + "Paste from the amiga clipboard, trapping any errors." + (condition-case nil + (amiga-paste) + (error nil))) + + (defun check-clipboard () + "If there is anything new in the clipboard, add it to the emacs kill ring. + Returns t if there was something added, nil otherwise." + (let (added) + (if amiga-new-clip + (let ((str (safe-amiga-paste))) + (setq amiga-new-clip nil) + (if str + (progn + (kill-add str) + (setq added t) + (setq kill-ring-yank-pointer kill-ring))))) + added)) + (defun update-clipboard (str) + (amiga-cut str) + (setq amiga-new-clip nil))) + (progn ; These could be defined for X-Windows. + (defun check-clipboard () nil) + (defun update-clipboard () nil))) + (defun kill-append (string before-p) (setcar kill-ring (if before-p (concat string (car kill-ring)) ! (concat (car kill-ring) string))) ! (update-clipboard (car kill-ring))) ! ! (defun kill-add (string) ! (check-clipboard) ! (setq kill-ring (cons string kill-ring)) ! (update-clipboard string) ! (if (> (length kill-ring) kill-ring-max) ! (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) (defun kill-region (beg end) "Kill between point and mark. *************** *** 571,579 **** (delete-region beg end) ;; Take the same string recorded for undo ;; and put it in the kill-ring. ! (setq kill-ring (cons (car (car buffer-undo-list)) kill-ring)) ! (if (> (length kill-ring) kill-ring-max) ! (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)) (setq this-command 'kill-region) (setq kill-ring-yank-pointer kill-ring)) (copy-region-as-kill beg end) --- 607,613 ---- (delete-region beg end) ;; Take the same string recorded for undo ;; and put it in the kill-ring. ! (kill-add (car (car buffer-undo-list))) (setq this-command 'kill-region) (setq kill-ring-yank-pointer kill-ring)) (copy-region-as-kill beg end) *************** *** 584,594 **** (defun copy-region-as-kill (beg end) "Save the region as if killed, but don't kill it." (interactive "r") ! (if (eq last-command 'kill-region) (kill-append (buffer-substring beg end) (< end beg)) ! (setq kill-ring (cons (buffer-substring beg end) kill-ring)) ! (if (> (length kill-ring) kill-ring-max) ! (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))) (setq this-command 'kill-region) (setq kill-ring-yank-pointer kill-ring)) --- 618,626 ---- (defun copy-region-as-kill (beg end) "Save the region as if killed, but don't kill it." (interactive "r") ! (if (and (eq last-command 'kill-region) (not (check-clipboard))) (kill-append (buffer-substring beg end) (< end beg)) ! (kill-add (buffer-substring beg end))) (setq this-command 'kill-region) (setq kill-ring-yank-pointer kill-ring)) *************** *** 643,648 **** --- 675,681 ---- text. See also the command \\[yank-pop]." (interactive "*P") + (check-clipboard) (rotate-yank-pointer (if (listp arg) 0 (if (eq arg '-) -1 (1- arg)))) Binary files emacs-18.59-fsf/lisp/simple.elc and emacs-18.59-amiga/lisp/simple.elc differ diff -rcP emacs-18.59-fsf/lisp/startup.el emacs-18.59-amiga/lisp/startup.el *** emacs-18.59-fsf/lisp/startup.el Sun Apr 19 05:20:08 1992 --- emacs-18.59-amiga/lisp/startup.el Sat Nov 21 16:16:08 1992 *************** *** 113,121 **** ;; Load user's init file, or load default one. (condition-case error (if init ! (progn (load (if (eq system-type 'vax-vms) ! "sys$login:.emacs" ! (concat "~" init "/.emacs")) t t t) (or inhibit-default-init (let ((inhibit-startup-message nil)) --- 113,121 ---- ;; Load user's init file, or load default one. (condition-case error (if init ! (progn (load (cond ((eq system-type 'vax-vms) "sys$login:.emacs") ! ((eq system-type 'amigados) "s:.emacs") ! (t (concat "~" init "/.emacs"))) t t t) (or inhibit-default-init (let ((inhibit-startup-message nil)) *************** *** 129,134 **** --- 129,138 ---- (save-excursion (set-buffer "*scratch*") (funcall initial-major-mode))) + ;; On Amiga, initialise clipboard + (if (eq system-type 'amigados) + (let ((clip (safe-amiga-paste))) + (if clip (kill-add clip)))) ;; Load library for our terminal type. ;; User init file can set term-file-prefix to nil to prevent this. (and term-file-prefix (not noninteractive) Binary files emacs-18.59-fsf/lisp/startup.elc and emacs-18.59-amiga/lisp/startup.elc differ diff -rcP emacs-18.59-fsf/lisp/term/intuition-win.el emacs-18.59-amiga/lisp/term/intuition-win.el *** emacs-18.59-fsf/lisp/term/intuition-win.el Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/lisp/term/intuition-win.el Sat Nov 21 16:08:08 1992 *************** *** 0 **** --- 1,47 ---- + (load "s:.emacs-menu" t t) + (setq command-switch-alist (append '(("-fn" . amiga-handle-set-font) + ("-fg" . amiga-handle-set-foreground) + ("-bg" . amiga-handle-set-background) + ("-geometry" . amiga-handle-set-geometry) + ("-screen" . amiga-handle-set-screen)) + command-switch-alist)) + + (defun amiga-handle-set-font (switch) + (condition-case err + (let ((wfont (car command-line-args-left)) + (height (car (read-from-string (car (cdr command-line-args-left)))))) + (setq command-line-args-left (cdr (cdr command-line-args-left))) + (amiga-set-font wfont height)) + (error (message "Failed to load font")))) + + (defun amiga-handle-set-foreground (switch) + (condition-case err + (let ((pen (car (read-from-string (car command-line-args-left))))) + (setq command-line-args-left (cdr command-line-args-left)) + (amiga-set-foreground-color pen)) + (error (message "Failed to set foreground colour")))) + + (defun amiga-handle-set-background (switch) + (condition-case err + (let ((pen (car (read-from-string (car command-line-args-left))))) + (setq command-line-args-left (cdr command-line-args-left)) + (amiga-set-background-color pen)) + (error (message "Failed to set background colour")))) + + (defun amiga-handle-set-screen (switch) + (condition-case err + (let ((name (car command-line-args-left))) + (setq command-line-args-left (cdr command-line-args-left)) + (amiga-set-geometry nil nil nil nil name)) + (error (message "Couldn't open on public screen")))) + + (defun amiga-handle-set-geometry (switch) + (condition-case err + (let ((x (car (read-from-string (car command-line-args-left)))) + (y (car (read-from-string (car (cdr command-line-args-left))))) + (w (car (read-from-string (car (cdr (cdr command-line-args-left)))))) + (h (car (read-from-string (car (cdr (cdr (cdr command-line-args-left))))))) + ) + (setq command-line-args-left (cdr (cdr (cdr (cdr command-line-args-left))))) + (amiga-set-geometry x y w h nil)) + (error (message "Couldn't set window size")))) diff -rcP emacs-18.59-fsf/lisp/term/intuition-win.elc emacs-18.59-amiga/lisp/term/intuition-win.elc *** emacs-18.59-fsf/lisp/term/intuition-win.elc Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/lisp/term/intuition-win.elc Sun May 16 10:57:14 1993 *************** *** 0 **** --- 1,16 ---- + + (load "s:.emacs-menu" t t) + + (setq command-switch-alist (append (quote (("-fn" . amiga-handle-set-font) ("-fg" . amiga-handle-set-foreground) ("-bg" . amiga-handle-set-background) ("-geometry" . amiga-handle-set-geometry) ("-screen" . amiga-handle-set-screen))) command-switch-alist)) + + (defun amiga-handle-set-font (switch) (byte-code "ÀÁ‡" [err (byte-code " @à A@!@ AA‰ˆÄ + \"*‡" [wfont command-line-args-left height read-from-string amiga-set-font] 4) ((error (byte-code "ÀÁ!‡" [message "Failed to load font"] 2)))] 3)) + + (defun amiga-handle-set-foreground (switch) (byte-code "ÀÁ‡" [err (byte-code " @!@ A‰ˆÃ!)‡" [pen command-line-args-left read-from-string amiga-set-foreground-color] 3) ((error (byte-code "ÀÁ!‡" [message "Failed to set foreground colour"] 2)))] 3)) + + (defun amiga-handle-set-background (switch) (byte-code "ÀÁ‡" [err (byte-code " @!@ A‰ˆÃ!)‡" [pen command-line-args-left read-from-string amiga-set-background-color] 3) ((error (byte-code "ÀÁ!‡" [message "Failed to set background colour"] 2)))] 3)) + + (defun amiga-handle-set-screen (switch) (byte-code "ÀÁ‡" [err (byte-code " @ A‰ˆÃÂÂÂÂ%)‡" [name command-line-args-left nil amiga-set-geometry] 6) ((error (byte-code "ÀÁ!‡" [message "Couldn't open on public screen"] 2)))] 3)) + + (defun amiga-handle-set-geometry (switch) (byte-code "ÀÁ‡" [err (byte-code "Æ @!@Æ A@!@Æ AA@!@Æ AAA@!@ AAAA‰ˆÇ + Å%,‡" [x command-line-args-left y w h nil read-from-string amiga-set-geometry] 10) ((error (byte-code "ÀÁ!‡" [message "Couldn't set window size"] 2)))] 3)) diff -rcP emacs-18.59-fsf/lisp/texinfmt.el emacs-18.59-amiga/lisp/texinfmt.el *** emacs-18.59-fsf/lisp/texinfmt.el Sun Dec 8 05:28:09 1991 --- emacs-18.59-amiga/lisp/texinfmt.el Sat Nov 21 16:16:32 1992 *************** *** 874,880 **** (insert "\n* Menu:\n\n") (setq opoint (point)) (texinfo-print-index nil indexelts) ! (if (eq system-type 'vax-vms) (texinfo-sort-region opoint (point)) (shell-command-on-region opoint (point) "sort -fd" 1)))) --- 874,880 ---- (insert "\n* Menu:\n\n") (setq opoint (point)) (texinfo-print-index nil indexelts) ! (if (or (eq system-type 'amigados) (eq system-type 'vax-vms)) (texinfo-sort-region opoint (point)) (shell-command-on-region opoint (point) "sort -fd" 1)))) Binary files emacs-18.59-fsf/lisp/texinfmt.elc and emacs-18.59-amiga/lisp/texinfmt.elc differ diff -rcP emacs-18.59-fsf/src/SCOPTIONS emacs-18.59-amiga/src/SCOPTIONS *** emacs-18.59-fsf/src/SCOPTIONS Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/SCOPTIONS Sat Oct 2 15:31:56 1993 *************** *** 0 **** --- 1,15 ---- + STRINGMERGE + STRUCTUREEQUIVALENCE + NOWARNVOIDRETURN + NOVERSION + MEMORYSIZE=HUGE + INCLUDEDIR=//unix/include + IGNORE=147 + IGNORE=62 + IGNORE=132 + IGNORE=154 + IGNORE=104 + IGNORE=100 + IGNORE=161 + IGNORE=84 + IGNORE=93 diff -rcP emacs-18.59-fsf/src/alloc.c emacs-18.59-amiga/src/alloc.c *** emacs-18.59-fsf/src/alloc.c Mon Sep 21 05:45:30 1992 --- emacs-18.59-amiga/src/alloc.c Sun Dec 6 12:42:02 1992 *************** *** 76,81 **** --- 76,86 ---- Preallocated since perhaps we can't allocate it when memory is full. */ Lisp_Object memory_exhausted_message; + #ifdef AMIGA_DUMP + int *pure; /* pure array is allocated at run-time */ + int puresize = DEF_PURESIZE; /* and has a variable size */ + #define PUREBEG (char *) pure + #else /* not AMIGA_DUMP */ #ifndef HAVE_SHM #ifdef VMS int pure[PURESIZE / sizeof (int)]; /*no need to initialize - wasted space*/ *************** *** 87,92 **** --- 92,98 ---- #define pure PURE_SEG_BITS /* Use shared memory segment */ #define PUREBEG (char *)PURE_SEG_BITS #endif /* not HAVE_SHM */ + #endif /* not AMIGA_DUMP */ /* Index in pure at which next pure object will be allocated. */ int pureptr; *************** *** 608,614 **** XSET (val, Lisp_String, (struct Lisp_String *) current_string_block->chars); } ! XSTRING (val)->size = length; XSTRING (val)->data[length] = 0; --- 614,620 ---- XSET (val, Lisp_String, (struct Lisp_String *) current_string_block->chars); } ! XSTRING (val)->size = length; XSTRING (val)->data[length] = 0; *************** *** 727,735 **** --- 733,745 ---- #ifdef __GNUC__ Lisp_Object *staticvec[NSTATICS] = {0}; #else + #ifdef AMIGA_DUMP + Lisp_Object *staticvec[NSTATICS]; /* Doesn't need to be pure */ + #else char staticvec1[NSTATICS * sizeof (Lisp_Object *)] = {0}; #define staticvec ((Lisp_Object **) staticvec1) #endif + #endif /* Put an entry in staticvec, pointing at the variable whose address is given */ *************** *** 859,870 **** { mark_object (&catch->tag); mark_object (&catch->val); ! } for (handler = handlerlist; handler; handler = handler->next) { mark_object (&handler->handler); mark_object (&handler->var); ! } for (backlist = backtrace_list; backlist; backlist = backlist->next) { if (!XMARKBIT (*backlist->function)) --- 869,880 ---- { mark_object (&catch->tag); mark_object (&catch->val); ! } for (handler = handlerlist; handler; handler = handler->next) { mark_object (&handler->handler); mark_object (&handler->var); ! } for (backlist = backtrace_list; backlist; backlist = backlist->next) { if (!XMARKBIT (*backlist->function)) *************** *** 882,888 **** mark_object (&backlist->args[i]); XMARK (backlist->args[i]); } ! } gc_sweep (); --- 892,898 ---- mark_object (&backlist->args[i]); XMARK (backlist->args[i]); } ! } gc_sweep (); *************** *** 900,906 **** i = backlist->nargs - 1; for (; i >= 0; i--) XUNMARK (backlist->args[i]); ! } XUNMARK (buffer_defaults.name); XUNMARK (buffer_local_symbols.name); --- 910,916 ---- i = backlist->nargs - 1; for (; i >= 0; i--) XUNMARK (backlist->args[i]); ! } XUNMARK (buffer_defaults.name); XUNMARK (buffer_local_symbols.name); *************** *** 936,942 **** { register struct cons_block *cblk; register int lim = cons_block_index; ! for (cblk = cons_block; cblk; cblk = cblk->next) { register int i; --- 946,952 ---- { register struct cons_block *cblk; register int lim = cons_block_index; ! for (cblk = cons_block; cblk; cblk = cblk->next) { register int i; *************** *** 949,955 **** { register struct symbol_block *sblk; register int lim = symbol_block_index; ! for (sblk = symbol_block; sblk; sblk = sblk->next) { register int i; --- 959,965 ---- { register struct symbol_block *sblk; register int lim = symbol_block_index; ! for (sblk = symbol_block; sblk; sblk = sblk->next) { register int i; *************** *** 964,970 **** { register struct marker_block *sblk; register int lim = marker_block_index; ! for (sblk = marker_block; sblk; sblk = sblk->next) { register int i; --- 974,980 ---- { register struct marker_block *sblk; register int lim = marker_block_index; ! for (sblk = marker_block; sblk; sblk = sblk->next) { register int i; *************** *** 1197,1203 **** register int num_free = 0, num_used = 0; cons_free_list = 0; ! for (cblk = cons_block; cblk; cblk = cblk->next) { register int i; --- 1207,1213 ---- register int num_free = 0, num_used = 0; cons_free_list = 0; ! for (cblk = cons_block; cblk; cblk = cblk->next) { register int i; *************** *** 1226,1232 **** register int num_free = 0, num_used = 0; symbol_free_list = 0; ! for (sblk = symbol_block; sblk; sblk = sblk->next) { register int i; --- 1236,1242 ---- register int num_free = 0, num_used = 0; symbol_free_list = 0; ! for (sblk = symbol_block; sblk; sblk = sblk->next) { register int i; *************** *** 1260,1266 **** register int num_free = 0, num_used = 0; marker_free_list = 0; ! for (mblk = marker_block; mblk; mblk = mblk->next) { register int i; --- 1270,1276 ---- register int num_free = 0, num_used = 0; marker_free_list = 0; ! for (mblk = marker_block; mblk; mblk = mblk->next) { register int i; *************** *** 1400,1406 **** while ((unsigned) size > STRING_BLOCK_SIZE) { if (size & 1) size ^= MARKBIT | 1; ! size = *(int *)size & ~MARKBIT; } total_string_size += size; --- 1410,1417 ---- while ((unsigned) size > STRING_BLOCK_SIZE) { if (size & 1) size ^= MARKBIT | 1; ! size = *(int *)size; ! size &= ~MARKBIT; } total_string_size += size; *************** *** 1438,1444 **** if (size & 1) size ^= MARKBIT | 1; objptr = (Lisp_Object *)size; ! size = XFASTINT (*objptr) & ~MARKBIT; if (XMARKBIT (*objptr)) { XSET (*objptr, Lisp_String, newaddr); --- 1449,1456 ---- if (size & 1) size ^= MARKBIT | 1; objptr = (Lisp_Object *)size; ! size = XFASTINT (*objptr); ! size &= ~MARKBIT; if (XMARKBIT (*objptr)) { XSET (*objptr, Lisp_String, newaddr); *************** *** 1498,1504 **** Qt tends to return NULL, which effectively turns undo back on. So don't call truncate_undo_list if undo_list is Qt. */ if (! EQ (nextb->undo_list, Qt)) ! nextb->undo_list = truncate_undo_list (nextb->undo_list, undo_threshold, undo_high_threshold); nextb = nextb->next; --- 1510,1516 ---- Qt tends to return NULL, which effectively turns undo back on. So don't call truncate_undo_list if undo_list is Qt. */ if (! EQ (nextb->undo_list, Qt)) ! nextb->undo_list = truncate_undo_list (nextb->undo_list, undo_threshold, undo_high_threshold); nextb = nextb->next; diff -rcP emacs-18.59-fsf/src/alloca.c emacs-18.59-amiga/src/alloca.c *** emacs-18.59-fsf/src/alloca.c Sat Jul 25 21:40:32 1992 --- emacs-18.59-amiga/src/alloca.c Sun Nov 22 10:12:50 1992 *************** *** 72,78 **** #define STACK_DIRECTION 0 /* direction unknown */ #endif ! #if STACK_DIRECTION != 0 #define STACK_DIR STACK_DIRECTION /* known at compile-time */ --- 72,78 ---- #define STACK_DIRECTION 0 /* direction unknown */ #endif ! #if (STACK_DIRECTION) != 0 #define STACK_DIR STACK_DIRECTION /* known at compile-time */ *************** *** 137,142 **** --- 137,144 ---- static header *last_alloca_header = NULL; /* -> last alloca header */ + int alloca_calling; + pointer alloca (size) /* returns pointer to storage */ unsigned size; /* # bytes to allocate */ *************** *** 176,185 **** --- 178,189 ---- /* Allocate combined header + user data storage. */ + alloca_calling = 1; { register pointer new = xmalloc (sizeof (header) + size); /* address of header */ + alloca_calling = 0; ((header *)new)->h.next = last_alloca_header; ((header *)new)->h.deep = depth; diff -rcP emacs-18.59-fsf/src/amiga.h emacs-18.59-amiga/src/amiga.h *** emacs-18.59-fsf/src/amiga.h Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga.h Sat Dec 5 18:07:10 1992 *************** *** 0 **** --- 1,145 ---- + + /* Prototypes for functions defined in amiga_clipboard.c */ + void syms_of_amiga_clipboard(void); + void early_clipboard(void); + void init_clipboard(void); + void cleanup_clipboard(void); + + /* Prototypes for functions defined in amiga_dump.c */ + void map_out_data(char *fn); + void map_in_data(int load); + extern void *far first_fn, *far last_fn; + + /* Prototypes for functions defined in amiga_menu.c */ + void suspend_menus(void); + int resume_menus(void); + void syms_of_amiga_menu(void); + void init_amiga_menu(void); + void cleanup_amiga_menu(void); + + /* Prototypes for functions defined in amiga_processes.c */ + /* Simulation of unix processes & signals */ + int wait_for_termination(int pid); + int wait_without_blocking(void); + char *amiga_path(void); + void init_amiga_processes(void); + void cleanup_amiga_processes(void); + + /* Prototypes for functions defined in amiga_rexx.c */ + int check_arexx(int force, int kbd); + void init_amiga_rexx(void); + void cleanup_amiga_rexx(void); + void syms_of_amiga_rexx(void); + + /* Prototypes for functions defined in amiga_screen.c */ + extern struct Window *emacs_win; + void get_window_size(int *widthp, int *heightp); + void reset_window(void); + void force_window(void); + void add_wbevent(struct WBArg *wbarg); + void check_window(int force); + void setup_intchar(char intchar); + + void start_count(int n); + void stop_count(int n); + void suspend_count(int n); + void resume_count(int n); + int disp_counts(void); + + void screen_puts(char *str, unsigned int len); + void syms_of_amiga_screen(void); + void init_amiga_screen(void); + void cleanup_amiga_screen(void); + + /* Prototypes for functions defined in amiga_serial.c */ + void init_amiga_serial(void); + void cleanup_amiga_serial(void); + void check_serial(int force); + void serial_puts(char *str, int len); + unsigned long serial_baud_rate(void); + + /* Prototypes for functions defined in amiga_sysdep.c */ + extern int selecting; + + int set_exclusive_use(int fd); + int sys_suspend(void); + char *get_system_name(void); + char *expand_path(char *path, char *buf, int len); + int syms_of_amiga(void); + void cleanup_amiga(void); + void amiga_undump_reinit(void); + void *early_xmalloc(long size); + void *early_xrealloc(void *old, long size); + + /* Failure stuff */ + void wbmessage(char *msg); + void fail(char *cause); + void fail_nomem(void); + void _fail_internal(char *file, int line); + #define fail_internal() _fail_internal(__FILE__, __LINE__); + enum exit_method { use_exit, use_xcexit, use_safe }; + extern enum exit_method amiga_fail_exit; + + #define MALLOC_HUNK_SIZE 92000 /* Default malloc hunk size */ + extern long malloc_hunk_size; /* Amount of memory malloc'ed by a to-be-dumped emacs */ + extern long malloc_bytes_used; /* Amount of this hunk actually used */ + extern long far pre_alloc; /* amount of memory to reserve for emacs */ + extern int puresize; /* Size of pure hunk */ + + /* Various special values used to find the beginning & end of the text, data, + bss and malloc segments. */ + extern int first_data, last_data, first_bss, last_bss; + extern void first_function(), last_function(); + extern char *malloc_hunk; + extern int amiga_initialized; /* True once Emacs has been undumped or initialised */ + struct mem_header /* sizeof() must be multiple of 4 ! */ + { + struct mem_header *next, *prev; + long size; + /* Data follows */ + }; + extern struct mem_header *free_list; + + + /* Prototypes for functions defined in amiga_term.c */ + int amiga_term_init(void); + + /* Prototypes for functions defined in amiga_tty.c */ + extern struct timeinfo *far odd_timer; + extern unsigned long odd_sig; + int setpgrp_of_tty(int pid); + int init_sigio(void); + int reset_sigio(void); + int request_sigio(void); + int unrequest_sigio(void); + int tabs_safe_p(void); + int get_screen_size(int *widthp, int *heightp); + int init_baud_rate(void); + void check_intuition(void); + #define AMIGASEQ 256 /* When passed to enque, insert the Amiga sequence introducer + C-x C-^ */ + void enque(unsigned int c, int meta); + int init_sys_modes(void); + int reset_sys_modes(void); + void amiga_consume_input(void); + int discard_tty_input(void); + int emacs_fflush(struct __iobuf *f); + void emacs_putchar(int c); + void emacs_output(char *str, int size); + void emacs_fwrite(char *str, unsigned int nblocks, unsigned int len, FILE *f); + void syms_of_amiga_tty(void); + void init_amiga_tty(void); + void cleanup_amiga_tty(void); + void early_amiga_tty(void); + void amiga_term_open(void); + /* Signal mask used to detect available keyboard input. + Must be set by amiga_serial or amiga_screen */ + extern unsigned long inputsig; + + /* Prototypes for functions defined in amiga_unix.c */ + void MemCleanup(void); + char *malloc(int size); + int free(void *p); + char *calloc(long n, long size); + char *realloc(char *p, long size); + void emacs_malloc_init(void); diff -rcP emacs-18.59-fsf/src/amiga_clipboard.c emacs-18.59-amiga/src/amiga_clipboard.c *** emacs-18.59-fsf/src/amiga_clipboard.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_clipboard.c Tue Mar 23 09:41:50 1993 *************** *** 0 **** --- 1,225 ---- + #include "config.h" + #undef NULL + #include "lisp.h" + #include "termchar.h" + #include "amiga.h" + + #include + #include + + #undef LONGBITS + + #include + #include + #include + #include + #include + + #include + #include + + #define ID_FTXT MAKE_ID('F','T','X','T') + #define ID_CHRS MAKE_ID('C','H','R','S') + + /* + * Text error messages for possible IFFERR_#? returns from various + * IFF routines. To get the index into this array, take your IFFERR code, + * negate it, and subtract one. + * idx = -error - 1; + */ + static char *far ifferrormsgs[] = { + "End of file (not an error).", + "End of context (not an error).", + "No lexical scope.", + "Insufficient memory.", + "Stream read error.", + "Stream write error.", + "Stream seek error.", + "File is corrupt.", + "IFF syntax error.", + "Not an IFF file.", + "Required call-back hook missing.", + "Return to client. You should never see this." + }; + + Lisp_Object amiga_new_clip; + static struct IFFHandle *far iff; + struct Library *IFFParseBase; + + static struct IOClipReq *far ClipRequest; + static struct Hook cliphook; + + /* added __interrupt flag this disables stack checking for this function + * so we can compile with stack checking on. -ch3/19/93. */ + static ULONG __saveds __asm __interrupt + clip_change( register __a0 struct Hook *hook, + register __a2 VOID *object, + register __a1 ULONG *message ) + { + amiga_new_clip = 1; + return 0; + } + + static Lisp_Object clip_unwind(Lisp_Object dummy) + { + CloseIFF (iff); + CloseClipboard ((struct ClipboardHandle *) iff->iff_Stream); + + return Qnil; + } + + static int clip_protect(void) + { + int count = specpdl_ptr - specpdl; + + record_unwind_protect(clip_unwind, Qnil); + + return count; + } + + static long clip_check(long err) + { + if(err) error ("Clipboard IO failed, error %ld: %s\n", + err, ifferrormsgs[-err - 1]); + return err; + } + + + static void cut(char *str, int size) + { + int count; + + if (!(iff->iff_Stream = (ULONG) OpenClipboard (0))) + error ("Clipboard open failed."); + + count = clip_protect(); + + /* Open clipbaord */ + InitIFFasClip (iff); + clip_check(OpenIFF (iff, IFFF_WRITE)); + + /* Write data */ + clip_check(PushChunk(iff, ID_FTXT, ID_FORM, IFFSIZE_UNKNOWN)); + clip_check(PushChunk(iff, 0, ID_CHRS, IFFSIZE_UNKNOWN)); + if (WriteChunkBytes(iff, str, size) != size) clip_check(IFFERR_WRITE); + clip_check(PopChunk(iff)); + clip_check(PopChunk(iff)); + + /* & close */ + unbind_to (count); + } + + DEFUN ("amiga-cut", Famiga_cut, Samiga_cut, + 1, 1, 0, + "Copy string into Amiga clipboard.") + (arg) + Lisp_Object arg; + { + struct Lisp_String *p; + + CHECK_STRING (arg, 0); + + p = XSTRING (arg); + cut(p->data, p->size); + + return Qnil; + } + + DEFUN ("amiga-paste", Famiga_paste, Samiga_paste, + 0, 0, 0, + "Returns text currently in the Amiga clipboard, or NIL if there is none.") + () + { + long err = 0; + Lisp_Object result = Qnil; + struct ContextNode *cn; + int count; + + if (!(iff->iff_Stream = (ULONG) OpenClipboard (0))) + error ("Clipboard open failed."); + + count = clip_protect(); + + /* Open clipbaord */ + InitIFFasClip (iff); + clip_check(OpenIFF (iff, IFFF_READ)); + clip_check(StopChunk(iff, ID_FTXT, ID_CHRS)); + + /* Find the first FTXT CHRS chunks */ + while (result == Qnil) + { + long err = ParseIFF(iff, IFFPARSE_SCAN); + + if (err == IFFERR_EOC) continue; /* enter next context */ + else if (err == IFFERR_EOF) break; + else clip_check(err); + + /* We only asked to stop at FTXT CHRS chunks + * If no error we've hit a stop chunk + * Read the CHRS chunk data + */ + cn = CurrentChunk(iff); + + if ((cn) && (cn->cn_Type == ID_FTXT) && (cn->cn_ID == ID_CHRS)) + { + int size = cn->cn_Size, rlen; + + result = make_string("", size); + + if ((rlen = ReadChunkBytes(iff, XSTRING (result)->data, size)) != size) + if (rlen < 0) clip_check(rlen); + else clip_check(IFFERR_EOC); + } + } + unbind_to (count); + + return result; + } + + void syms_of_amiga_clipboard(void) + { + DEFVAR_BOOL ("amiga-new-clip", &amiga_new_clip, + "Set to t every time a new clip is put in the Amiga clipboard"); + amiga_new_clip = 0; + + defsubr (&Samiga_cut); + defsubr (&Samiga_paste); + } + + void early_clipboard(void) + { + IFFParseBase = 0; + } + + void init_clipboard(void) + { + /* Initialise IFF for clipboard */ + if (!(IFFParseBase = OpenLibrary("iffparse.library", 0))) + _fail("iffparse.library is required"); + if (!(iff = AllocIFF())) no_memory(); + + ClipRequest = (struct IOClipReq *) + _device_open("clipboard.device", 0L, 0L, 0L, 0, sizeof(struct IOClipReq)); + if (!ClipRequest) _fail("clipboard.device missing !?"); + + cliphook.h_Entry = (ULONG (*)())clip_change; + ClipRequest->io_Command = CBD_CHANGEHOOK; + ClipRequest->io_Length = 1; /* install */ + ClipRequest->io_Data = (APTR)&cliphook; + DoIO((struct IORequest *)ClipRequest); + } + + void cleanup_clipboard(void) + { + if (ClipRequest) + { + cliphook.h_Entry = (ULONG (*)())clip_change; + ClipRequest->io_Command = CBD_CHANGEHOOK; + ClipRequest->io_Length = 0; /* remove */ + ClipRequest->io_Data = (APTR)&cliphook; + DoIO((struct IORequest *)ClipRequest); + } + if (iff) FreeIFF(iff); + if (IFFParseBase) CloseLibrary(IFFParseBase); + _device_close((struct IORequest *)ClipRequest); + } diff -rcP emacs-18.59-fsf/src/amiga_data.c emacs-18.59-amiga/src/amiga_data.c *** emacs-18.59-fsf/src/amiga_data.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_data.c Sun Nov 22 10:12:54 1992 *************** *** 0 **** --- 1 ---- + /* Declarations of data that should not be squashed by the dump routine */ diff -rcP emacs-18.59-fsf/src/amiga_dump.c emacs-18.59-amiga/src/amiga_dump.c *** emacs-18.59-fsf/src/amiga_dump.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_dump.c Sun Nov 22 10:13:00 1992 *************** *** 0 **** --- 1,721 ---- + #include + #include + #include + #include + #include + #include + #include "config.h" + #include "lisp.h" + #include "buffer.h" + #include "regex.h" + #include "amiga.h" + #include "dispextern.h" + #include "termchar.h" + + #define RANGE(ptr, s, e) ((char *)ptr >= (char *)s && (char *)ptr < (char *)e) + #define HUNK_POS (VALBITS - 3) + #define HUNK_MASK (7 << HUNK_POS) + #define HUNK_CODE (0 << HUNK_POS) + #define HUNK_DATA (1 << HUNK_POS) + #define HUNK_BSS (2 << HUNK_POS) + #define HUNK_MALLOC (3 << HUNK_POS) + #define HUNK_PURE (4 << HUNK_POS) + #define ARRAY_MARK_FLAG ((MARKBIT >> 1) & ~MARKBIT) + + void *far first_fn = first_function, *far last_fn = last_function; + + extern int *pure, puresize; + extern struct gcpro *gcprolist; + + extern Lisp_Object *staticvec[]; + extern int staticidx; + extern struct cons_block *cons_block; + extern struct Lisp_Cons *cons_free_list; + extern struct Lisp_Vector *all_vectors; + extern struct symbol_block *symbol_block; + extern struct Lisp_Symbol *symbol_free_list; + extern struct marker_block *marker_block; + extern struct Lisp_Marker *marker_free_list; + + struct string_block_head + { + struct string_block_head *next, *prev; + int pos; + }; + extern struct string_block_head *current_string_block; + extern struct string_block_head *first_string_block; + extern struct string_block_head *large_string_blocks; + extern char *kbd_macro_buffer, *read_buffer, *chars_wasted, *copybuf; + extern struct minibuf_save_data *minibuf_save_vector; + extern struct re_pattern_buffer searchbuf; + extern int *ILcost, *DLcost, *ILncost, *DLncost; + extern Lisp_Object MouseMap, global_map, Vglobal_map, Vesc_map, Vctl_x_map; + extern Lisp_Object Qvariable_documentation, selected_window; + + extern char *callint_argfuns[]; + + static void *dump_malloc(int size) + { + void *new = malloc(size); + + if (!new) no_memory(); + + return new; + } + + static void bailout(char *fn) + { + if (fn) _message("%s isn't a dump file for this version of Emacs, aborting", fn); + else _message("Dump file isn't for this version of Emacs, aborting"); + + /* We are in deep trouble, as all our variables are potentially corrupt */ + /* Therefore, no cleanup is possible */ + /* Remove cleanup routines */ + onexit(0); + /* However, the library & the memory allocation should be ok, so + we can exit reasonably */ + _fail("Some system resources may have been lost"); + } + + static void *hunk_pointer(void *ptr) + { + if (!ptr) return ptr; + + if (RANGE(ptr, first_fn, last_fn)) + return (void *)(HUNK_CODE | (char *)ptr - (char *)first_fn); + else if (RANGE(ptr, &first_data, &last_data)) + return (void *)(HUNK_DATA | (char *)ptr - (char *)&first_data); + else if (RANGE(ptr, &first_bss, &last_bss)) + return (void *)(HUNK_BSS | (char *)ptr - (char *)&first_bss); + else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size)) + return (void *)(HUNK_MALLOC | (char *)ptr - malloc_hunk); + else if (RANGE(ptr, pure, (char *)pure + puresize)) + return (void *)(HUNK_PURE | (char *)ptr - (char *)pure); + else bailout(0); + } + + static Lisp_Object hunk_lispptr(Lisp_Object *objptr, Lisp_Object val) + { + int type = val & ~VALMASK; + void *ptr = (void *)XPNTR(val); + + if (RANGE(ptr, first_fn, last_fn)) + return type | HUNK_CODE | (char *)ptr - (char *)first_fn; + else if (RANGE(ptr, &first_data, &last_data)) + return type | HUNK_DATA | (char *)ptr - (char *)&first_data; + else if (RANGE(ptr, &first_bss, &last_bss)) + return type | HUNK_BSS | (char *)ptr - (char *)&first_bss; + else if (RANGE(ptr, pure, (char *)pure + puresize)) + return type | HUNK_PURE | (char *)ptr - (char *)pure; + else if (RANGE(ptr, malloc_hunk, malloc_hunk + malloc_hunk_size)) + return type | HUNK_MALLOC | (char *)ptr - malloc_hunk; + else bailout(0); + } + + static void patch_pointers (); + + static void patch_buffer (buf) + Lisp_Object buf; + { + Lisp_Object tem; + register struct buffer *buffer = XBUFFER (buf); + register Lisp_Object *ptr; + + buffer->text.beg = hunk_pointer (buffer->text.beg); + patch_pointers (&buffer->markers); + + /* This is the buffer's markbit */ + patch_pointers (&buffer->name); + XMARK (buffer->name); + + for (ptr = &buffer->name + 1; + (char *)ptr < (char *)buffer + sizeof (struct buffer); + ptr++) + patch_pointers (ptr); + } + + static void patch_pointers (objptr) + Lisp_Object *objptr; + { + register Lisp_Object obj; + + obj = *objptr; + XUNMARK (obj); + + + loop: + + switch (XGCTYPE (obj)) + { + case Lisp_String: + *objptr = hunk_lispptr(objptr, *objptr); + break; + + case Lisp_Vector: + case Lisp_Window: + case Lisp_Process: + case Lisp_Window_Configuration: + *objptr = hunk_lispptr(objptr, *objptr); + { + register struct Lisp_Vector *ptr = XVECTOR (obj); + register int size = ptr->size; + register int i; + + if (size & ARRAY_MARK_FLAG) break; /* Already marked */ + ptr->size |= ARRAY_MARK_FLAG; /* Else mark it */ + for (i = 0; i < size; i++) /* and then mark its elements */ + patch_pointers (&ptr->contents[i]); + } + break; + + case Lisp_Symbol: + *objptr = hunk_lispptr(objptr, *objptr); + { + register struct Lisp_Symbol *ptr = XSYMBOL (obj); + struct Lisp_Symbol *ptrx; + + if (XMARKBIT (ptr->plist)) break; + XMARK (ptr->plist); + XSETTYPE (*(Lisp_Object *) &ptr->name, Lisp_String); + patch_pointers (&ptr->name); + patch_pointers ((Lisp_Object *) &ptr->value); + patch_pointers (&ptr->function); + patch_pointers (&ptr->plist); + objptr = (Lisp_Object *)&ptr->next; + ptr = ptr->next; + if (ptr) + { + ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */ + XSETSYMBOL (obj, ptrx); + goto loop; + } + } + break; + + case Lisp_Marker: { + struct Lisp_Marker *ptr = XMARKER (obj); + + *objptr = hunk_lispptr(objptr, *objptr); + if (XMARKBIT (ptr->chain)) break; + XMARK (ptr->chain); + ptr->buffer = hunk_pointer (ptr->buffer); + patch_pointers (&ptr->chain); + break; + } + + case Lisp_Cons: + case Lisp_Buffer_Local_Value: + case Lisp_Some_Buffer_Local_Value: + *objptr = hunk_lispptr(objptr, *objptr); + { + register struct Lisp_Cons *ptr = XCONS (obj); + if (XMARKBIT (ptr->car)) break; + XMARK (ptr->car); + patch_pointers (&ptr->car); + objptr = &ptr->cdr; + obj = ptr->cdr; + goto loop; + } + + case Lisp_Buffer: + *objptr = hunk_lispptr(objptr, *objptr); + if (!XMARKBIT (XBUFFER (obj)->name)) + patch_buffer (obj); + break; + + case Lisp_Subr: { + struct Lisp_Subr *subr = XSUBR(obj); + + *objptr = hunk_lispptr(objptr, *objptr); + if (subr->min_args & 0x8000) break; + subr->min_args |= 0x8000; + subr->function = hunk_pointer(subr->function); + subr->symbol_name = hunk_pointer(subr->symbol_name); + subr->prompt = hunk_pointer(subr->prompt); + if ((long)subr->doc >= 0) /* Make sure that not a doc offset */ + subr->doc = hunk_pointer(subr->doc); + break; + } + + case Lisp_Int: + case Lisp_Void: + case Lisp_Buffer_Objfwd: break; + + case Lisp_Intfwd: + case Lisp_Boolfwd: + case Lisp_Objfwd: + case Lisp_Internal_Stream: + *objptr = hunk_lispptr(objptr, *objptr); + /* Don't bother with Lisp_Buffer_Objfwd, + since all markable slots in current buffer marked anyway. */ + /* Don't need to do Lisp_Objfwd, since the places they point + are protected with staticpro. */ + break; + + default: + abort (); + } + } + + static void patch_chain(void **ptr, int offset) + { + while (*ptr) + { + void **next = (void **)((char *)*ptr + offset); + + *ptr = hunk_pointer(*ptr); + ptr = next; + } + } + + static void patch(void) + { + int i; + struct string_block_head *sptr; + struct buffer *bptr; + struct mem_header *mem; + + for (i = 0; i < staticidx; i++) + { + if (!XMARKBIT(*staticvec[i])) + { + patch_pointers(staticvec[i]); + XMARK(*staticvec[i]); + } + staticvec[i] = hunk_pointer(staticvec[i]); + } + + /* Patch all the pointers normally used before a dump ! */ + patch_chain((void **)&cons_block, 0); + patch_chain((void **)&cons_free_list, 0); + + patch_chain((void **)&all_vectors, 4); + + patch_chain((void **)&symbol_block, 0); + patch_chain((void **)&symbol_free_list, 4); + + patch_chain((void **)&marker_block, 0); + patch_chain((void **)&marker_free_list, 4); + + /* Strings are lots of fun */ + patch_chain((void **)&large_string_blocks, 0); + sptr = first_string_block; + while (sptr) + { + struct string_block *next = sptr->next; + + if (sptr->next) sptr->next = hunk_pointer(sptr->next); + if (sptr->prev) sptr->prev = hunk_pointer(sptr->prev); + sptr = next; + } + first_string_block = hunk_pointer(first_string_block); + current_string_block = hunk_pointer(current_string_block); + + /* More fun with buffers */ + bptr = all_buffers; + if (bptr) + { + while (bptr->next) + { + struct buffer *next = bptr->next; + + bptr->next = hunk_pointer(bptr->next); + bptr = next; + } + } + all_buffers = hunk_pointer(all_buffers); + current_buffer = hunk_pointer(current_buffer); + + kbd_macro_buffer = hunk_pointer(kbd_macro_buffer); + minibuf_save_vector = hunk_pointer(minibuf_save_vector); + searchbuf.buffer = hunk_pointer(searchbuf.buffer); + searchbuf.fastmap = hunk_pointer(searchbuf.fastmap); + specpdl = hunk_pointer(specpdl); + read_buffer = hunk_pointer(read_buffer); + + MouseMap = hunk_lispptr(&MouseMap, MouseMap); + global_map = hunk_lispptr(&global_map, global_map); + Vglobal_map = hunk_lispptr(&Vglobal_map, Vglobal_map); + Vesc_map = hunk_lispptr(&Vesc_map, Vesc_map); + Vctl_x_map = hunk_lispptr(&Vctl_x_map, Vctl_x_map); + + Qvariable_documentation = hunk_lispptr(&Qvariable_documentation, Qvariable_documentation); + selected_window = hunk_lispptr(&selected_window, selected_window); + + mem = free_list; + free_list = hunk_pointer(free_list); + while (mem) + { + struct mem_header *next = mem->next; + + mem->prev = hunk_pointer(mem->prev); + mem->next = hunk_pointer(mem->next); + mem = next; + } + + for (i = 0; i <= 4; i++) + callint_argfuns[i] = hunk_pointer(callint_argfuns[i]); + } + + static dump(char *fn) + { + BPTR fd; + long size; + + fd = Open(fn, MODE_NEWFILE); + if (!fd) + { + static void unpatch(); + + unpatch(); + _fail("emacs hasn't been dumped (%s missing)", fn); + } + + Write(fd, (char *)&puresize, sizeof puresize); + Write(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size); + Write(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data); + Write(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss); + Write(fd, (char *)pure, puresize); + Write(fd, (char *)malloc_hunk, malloc_hunk_size); + Write(fd, (char *)&staticidx, sizeof staticidx); + Write(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *)); + size = (char *)last_fn - (char *)first_fn; + Write(fd, (char *)&size, sizeof size); + + Close(fd); + } + + static void *make_pointer(void *ptr) + { + int hunk = (long)ptr & HUNK_MASK; + int offset = (long)ptr & (VALMASK & ~HUNK_MASK); + + if (!ptr) return 0; + + if (hunk == HUNK_CODE) return (char *)first_fn + offset; + if (hunk == HUNK_DATA) return (char *)&first_data + offset; + if (hunk == HUNK_BSS) return (char *)&first_bss + offset; + if (hunk == HUNK_PURE) return (char *)pure + offset; + if (hunk == HUNK_MALLOC) return malloc_hunk + offset; + assert(0); + } + + static Lisp_Object make_lispptr(Lisp_Object *objptr, Lisp_Object obj) + { + long val = XUINT(obj); + int hunk = val & HUNK_MASK; + int offset = val & ~HUNK_MASK; + char *ptr; + + if (hunk == HUNK_CODE) ptr = (char *)first_fn + offset; + else if (hunk == HUNK_DATA) ptr = (char *)&first_data + offset; + else if (hunk == HUNK_BSS) ptr = (char *)&first_bss + offset; + else if (hunk == HUNK_PURE) ptr = (char *)pure + offset; + else if (hunk == HUNK_MALLOC) ptr = malloc_hunk + offset; + else assert(0); + + XSETPNTR(obj, (long)ptr); + return obj; + } + + static void unpatch_pointers (); + + static void unpatch_buffer (buf) + Lisp_Object buf; + { + Lisp_Object tem; + register struct buffer *buffer = XBUFFER (buf); + register Lisp_Object *ptr; + + buffer->text.beg = make_pointer (buffer->text.beg); + unpatch_pointers (&buffer->markers); + + /* This is the buffer's markbit */ + XUNMARK (buffer->name); + unpatch_pointers (&buffer->name); + + for (ptr = &buffer->name + 1; + (char *)ptr < (char *)buffer + sizeof (struct buffer); + ptr++) + unpatch_pointers (ptr); + } + + static void unpatch_pointers (objptr) + Lisp_Object *objptr; + { + register Lisp_Object obj; + + obj = *objptr; + XUNMARK (obj); + + + loop: + + switch (XGCTYPE (obj)) + { + case Lisp_String: + *objptr = make_lispptr(objptr, *objptr); + break; + + case Lisp_Vector: + case Lisp_Window: + case Lisp_Process: + case Lisp_Window_Configuration: + obj = *objptr = make_lispptr(objptr, *objptr); + { + register struct Lisp_Vector *ptr = XVECTOR (obj); + register int size; + register int i; + + if (!(ptr->size & ARRAY_MARK_FLAG)) break; /* Already unmarked */ + size = ptr->size &= ~ARRAY_MARK_FLAG; /* Else unmark it */ + for (i = 0; i < size; i++) /* and then unmark its elements */ + unpatch_pointers (&ptr->contents[i]); + } + break; + + case Lisp_Symbol: + obj = *objptr = make_lispptr(objptr, *objptr); + { + register struct Lisp_Symbol *ptr = XSYMBOL (obj); + struct Lisp_Symbol *ptrx; + + if (!XMARKBIT (ptr->plist)) break; + XUNMARK (ptr->plist); + unpatch_pointers (&ptr->name); + ptr->name = XSTRING (*(Lisp_Object *)&ptr->name); + unpatch_pointers ((Lisp_Object *) &ptr->value); + unpatch_pointers (&ptr->function); + unpatch_pointers (&ptr->plist); + objptr = (Lisp_Object *)&ptr->next; + ptr = ptr->next; + if (ptr) + { + ptrx = ptr; /* Use pf ptrx avoids compiler bug on Sun */ + XSET (obj, Lisp_Symbol, ptrx); + goto loop; + } + } + break; + + case Lisp_Marker: { + struct Lisp_Marker *ptr; + + obj = *objptr = make_lispptr(objptr, *objptr); + ptr = XMARKER (obj); + if (!XMARKBIT (ptr->chain)) break; + XUNMARK (ptr->chain); + ptr->buffer = make_pointer (ptr->buffer); + unpatch_pointers (&ptr->chain); + break; + } + + case Lisp_Cons: + case Lisp_Buffer_Local_Value: + case Lisp_Some_Buffer_Local_Value: + obj = *objptr = make_lispptr(objptr, *objptr); + { + register struct Lisp_Cons *ptr = XCONS (obj); + if (!XMARKBIT (ptr->car)) break; + XUNMARK (ptr->car); + unpatch_pointers (&ptr->car); + objptr = &ptr->cdr; + obj = ptr->cdr; + goto loop; + } + + case Lisp_Buffer: + obj = *objptr = make_lispptr(objptr, *objptr); + if (XMARKBIT (XBUFFER (obj)->name)) + unpatch_buffer (obj); + break; + + case Lisp_Subr: { + struct Lisp_Subr *subr; + + obj = *objptr = make_lispptr(objptr, *objptr); + subr = XSUBR(obj); + if (!(subr->min_args & 0x8000)) break; + subr->min_args &= ~0x8000; + subr->function = make_pointer(subr->function); + subr->symbol_name = make_pointer(subr->symbol_name); + subr->prompt = make_pointer(subr->prompt); + if ((long)subr->doc >= 0) /* Make sure that not a doc offset */ + subr->doc = make_pointer(subr->doc); + break; + } + + case Lisp_Int: + case Lisp_Void: + case Lisp_Buffer_Objfwd: break; + + case Lisp_Intfwd: + case Lisp_Boolfwd: + case Lisp_Objfwd: + case Lisp_Internal_Stream: + *objptr = make_lispptr(objptr, *objptr); + /* Don't bother with Lisp_Buffer_Objfwd, + since all markable slots in current buffer marked anyway. */ + /* Don't need to do Lisp_Objfwd, since the places they point + are protected with staticpro. */ + break; + + default: + abort (); + } + } + + static void unpatch_chain(void **ptr, int offset) + { + while (*ptr) + { + *ptr = make_pointer(*ptr); + ptr = (void **)((char *)*ptr + offset); + } + } + + /* Reconstructs the addresses that were patched */ + static void unpatch(void) + { + int fd, i; + struct string_block_head *sptr; + struct buffer *bptr; + struct mem_header *mem; + + for (i = 0; i < staticidx; i++) + { + staticvec[i] = make_pointer(staticvec[i]); + if (XMARKBIT(*staticvec[i])) + { + XUNMARK(*staticvec[i]); + unpatch_pointers(staticvec[i]); + } + } + + /* Unpatch all the pointers normally used before a dump ! */ + unpatch_chain((void **)&cons_block, 0); + unpatch_chain((void **)&cons_free_list, 0); + + unpatch_chain((void **)&all_vectors, 4); + + unpatch_chain((void **)&symbol_block, 0); + unpatch_chain((void **)&symbol_free_list, 4); + + unpatch_chain((void **)&marker_block, 0); + unpatch_chain((void **)&marker_free_list, 4); + + /* Strings are lots of fun */ + unpatch_chain((void **)&large_string_blocks, 0); + sptr = first_string_block = make_pointer(first_string_block); + current_string_block = make_pointer(current_string_block); + while (sptr) + { + if (sptr->next) sptr->next = make_pointer(sptr->next); + if (sptr->prev) sptr->prev = make_pointer(sptr->prev); + sptr = sptr->next; + } + + /* More fun with buffers */ + bptr = all_buffers = make_pointer(all_buffers); + if (bptr) + { + while (bptr->next) + { + bptr->next = make_pointer(bptr->next); + bptr = bptr->next; + } + } + current_buffer = make_pointer(current_buffer); + + kbd_macro_buffer = make_pointer(kbd_macro_buffer); + minibuf_save_vector = make_pointer(minibuf_save_vector); + searchbuf.buffer = make_pointer(searchbuf.buffer); + searchbuf.fastmap = make_pointer(searchbuf.fastmap); + specpdl = make_pointer(specpdl); + read_buffer = make_pointer(read_buffer); + + MouseMap = make_lispptr(&MouseMap, MouseMap); + global_map = make_lispptr(&global_map, global_map); + Vglobal_map = make_lispptr(&Vglobal_map, Vglobal_map); + Vesc_map = make_lispptr(&Vesc_map, Vesc_map); + Vctl_x_map = make_lispptr(&Vctl_x_map, Vctl_x_map); + + Qvariable_documentation = make_lispptr(&Qvariable_documentation, Qvariable_documentation); + selected_window = make_lispptr(&selected_window, selected_window); + + free_list = make_pointer(free_list); + mem = free_list; + while (mem) + { + mem->prev = make_pointer(mem->prev); + mem->next = make_pointer(mem->next); + mem = mem->next; + } + + for (i = 0; i <= 4; i++) + callint_argfuns[i] = make_pointer(callint_argfuns[i]); + } + + static undump(char *fn) + { + BPTR fd; + long code_size; + char *_malloc_hunk; + int *_pure; + /*extern struct Library *FifoBase; + struct Library *_FifoBase = FifoBase;*/ + + fd = Open(fn, MODE_OLDFILE); + if (!fd) return 0; + + Read(fd, (char *)&puresize, sizeof puresize); + Read(fd, (char *)&malloc_hunk_size, sizeof malloc_hunk_size); + _pure = dump_malloc(puresize); + _malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc); + Read(fd, (char *)&first_data, (char *)&last_data - (char *)&first_data); + Read(fd, (char *)&first_bss, (char *)&last_bss - (char *)&first_bss); + Read(fd, (char *)_pure, puresize); + Read(fd, (char *)_malloc_hunk, malloc_hunk_size); + Read(fd, (char *)&staticidx, sizeof staticidx); + Read(fd, (char *)staticvec, staticidx * sizeof(Lisp_Object *)); + /*FifoBase = _FifoBase;*/ + if (Read(fd, (char *)&code_size, sizeof code_size) != sizeof code_size || + code_size != (char *)last_fn - (char *)first_fn) + bailout(fn); + + Close(fd); + malloc_hunk = _malloc_hunk; + pure = _pure; + return 1; + } + + void map_out_data(char *fn) + { + if (amiga_initialized) error("You can only dump once !"); + Fgarbage_collect(); + + patch(); + dump(fn); + unpatch(); + amiga_initialized = 1; + } + + void map_in_data(int load) + { + if (load && undump("GNUEmacs:etc/EMACS-DATA")) + { + unpatch(); + current_screen = new_screen = temp_screen = 0; + message_buf = 0; + chars_wasted = copybuf = 0; + DC_ICcost = 0; + ILcost = DLcost = ILncost = DLncost = 0; + initialized = amiga_initialized = 1; + } + else + { + malloc_hunk = dump_malloc(malloc_hunk_size + pre_alloc); + pure = dump_malloc(puresize); + } + amiga_undump_reinit(); + } diff -rcP emacs-18.59-fsf/src/amiga_malloc.c emacs-18.59-amiga/src/amiga_malloc.c *** emacs-18.59-fsf/src/amiga_malloc.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_malloc.c Sat Dec 5 16:36:46 1992 *************** *** 0 **** --- 1,321 ---- + /* Emulation of some unix functions for emacs. + Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Emacs General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + GNU Emacs, but only under the conditions described in the + GNU Emacs General Public License. A copy of this license is + supposed to have been given to you along with GNU Emacs so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. */ + + #include + #include + #include + + #undef LONGBITS + #undef NULL + #include "config.h" + #include "lisp.h" + #include "amiga.h" + + /* Memory stuff */ + long far DataSegBits; + static int DataSegFound; + static struct mem_header *far current; + struct mem_header *free_list; + extern int alloca_calling; + extern int *pure; + long far pre_alloc; /* amount of memory to reserve for emacs */ + char *malloc_hunk; + long malloc_hunk_size = MALLOC_HUNK_SIZE; /* Amount of memory malloc'ed by a + to-be-dumped emacs */ + long malloc_bytes_used; /* Amount of this hunk actually used */ + static int early_malloc = TRUE; /* Before we undump, we want system allocations */ + + #define ADDR_OK(x) (((long)x & ~VALMASK) == DataSegBits) + + /* Memory allocation code */ + /* ---------------------- */ + + static void *alloc_sys(long memsize) + /* Effect: Allocate from AmigaOS (via AllocMem). */ + { + /* Allocation rounded up to multiple of 4 */ + long size = ((memsize + 3) & ~3) + sizeof(struct mem_header); + struct mem_header *mem; + + if (!DataSegFound) + { + /* Find page containing Pure data. All data used by emacs must be + on the same page (As a page is 2^26 bytes, this shouldn't be too + unlikely). */ + DataSegBits = (long)&first_data & ~VALMASK; + if (!(ADDR_OK(first_fn) && ADDR_OK(last_fn) && + ADDR_OK(&first_data) && ADDR_OK(&last_data) && + ADDR_OK(&first_bss) && ADDR_OK(&last_bss))) + _fail("I can't handle your memory configuration"); + DataSegFound = TRUE; + } + + mem = AllocMem(size, 0); + if (!mem) return 0; + /* All memory *must* be allocated on the same page ! */ + if (!ADDR_OK(mem)) + { + FreeMem(mem, size); + return 0; + } + if (current) current->prev = mem; + mem->next = current; + mem->prev = 0; + current = mem; + mem->size = size; + + return mem + 1; + } + + static void free_sys(char *p) + { + struct mem_header *old = (struct mem_header *)p - 1; + + if (old == current) + { + current = current->next; + if (current) current->prev = 0; + } + else + { + old->prev->next = old->next; + if (old->next) old->next->prev = old->prev; + } + FreeMem(old, old->size); + } + + void _MemCleanup(void) + { + struct mem_header *next; + + while (current) + { + next = current->next; + FreeMem(current, current->size); + current = next; + } + } + + static void *alloc_hunk(long memsize) + /* Effect: Allocates from the malloc hunk (which is dumped to disk). + */ + { + /* Allocation rounded up to multiple of 4 */ + long size = ((memsize + 3) & ~3) + sizeof(struct mem_header); + /* Find a free block in the memory list */ + struct mem_header *scan = free_list->next; + + while (scan->size > 0) + { + if (size < scan->size) /* Found ! */ + { + long end; + + /* Split block if big enough */ + if (size + sizeof(struct mem_header) + 8 > scan->size) + { + /* Remove block from list */ + scan->prev->next = scan->next; + scan->next->prev = scan->prev; + } + else + { + /* Split block */ + struct mem_header *new = (struct mem_header *)((char *)scan + size); + + new->prev = scan->prev; + new->next = scan->next; + scan->prev->next = new; + scan->next->prev = new; + new->size = scan->size - size; + scan->size = size; + } + if (!amiga_initialized) + { + end = (char *)scan - (char *)free_list + scan->size + + sizeof(long) + sizeof(struct mem_header); + if (end > malloc_bytes_used) malloc_bytes_used = end; + } + return scan + 1; + } + scan = scan->next; + } + return 0; + } + + static void free_hunk(char *p) + { + struct mem_header *old = (struct mem_header *)p - 1, *scan = free_list; + + do scan = scan->next; while (scan < old); + + /* Check for merges (potentially with both sides) */ + if ((char *)scan->prev + scan->prev->size == (char *)old) + if ((char *)old + old->size == (char *)scan) + { + /* Merge all 3 blocks together */ + scan->prev->size += old->size + scan->size; + scan->next->prev = scan->prev; + scan->prev->next = scan->next; + } + else /* Merge with previous block */ + scan->prev->size += old->size; + else if ((char *)old + old->size == (char *)scan) + { + /* Merge with next block */ + old->size += scan->size; + scan->prev->next = old; + scan->next->prev = old; + old->prev = scan->prev; + old->next = scan->next; + } + else /* Add a new block */ + { + old->next = scan; + old->prev = scan->prev; + scan->prev->next = old; + scan->prev = old; + } + } + + char *__halloc(long size) + { + if (early_malloc) return alloc_sys(size); + + if (!amiga_initialized) + if (alloca_calling) + { + alloca_calling = 0; + return alloc_sys(size); + } + else + { + void *mem = alloc_hunk(size); + + if (!mem) + _fail("Emacs dump: ran out of memory for malloc. \n" + "See the -malloc option for more information.\n"); + return mem; + } + else + { + alloca_calling = 0; + if (pre_alloc) + { + void *mem; + + if (mem = alloc_hunk(size)) return mem; + } + return alloc_sys(size); + } + } + + char *malloc(int size) + { + return __halloc(size); + } + + free(void *p) + { + struct mem_header *old = (struct mem_header *)p - 1; + + if ((char *)p >= malloc_hunk && + (char *)p <= malloc_hunk + malloc_hunk_size + pre_alloc) + { + if (!amiga_initialized || pre_alloc) free_hunk(p); + } + else free_sys(p); + } + + char *calloc(long n, long size) + { + char *t; + long rsize = n * size; + + t = malloc(rsize); + if (t) memset (t, 0, rsize); + + return t; + } + + char *realloc(char *p, long size) + { + char *new = malloc(size); + struct mem_header *old = (struct mem_header *)p - 1; + + if (new) + { + long minsize; + long oldsize = old->size - sizeof(struct mem_header); + + if (size < oldsize) minsize = size; + else minsize = oldsize; + + memcpy(new, p, minsize); + } + free(p); + return new; + } + + void emacs_malloc_init(void) + { + struct mem_header *end_sentinel, *new_end, *new_block; + + early_malloc = FALSE; /* We now have a malloc hunk */ + + /* Set up the memory allocation in the malloc hunk */ + free_list = (struct mem_header *)malloc_hunk; + end_sentinel = (struct mem_header *)((char *)free_list + malloc_hunk_size + - sizeof(struct mem_header)); + if (!amiga_initialized) + { + /* Before dumping */ + free_list->next = free_list + 1; + free_list->prev = 0; + free_list->size = 0; /* Prevents merges with this pseudo-block */ + free_list[1].prev = free_list; + free_list[1].next = end_sentinel; + free_list[1].size = + malloc_hunk_size - 2 * sizeof(struct mem_header) - sizeof(long); + /* The - sizeof(long) prevents any merges with end_sentinel */ + + end_sentinel->size = 0; + end_sentinel->prev = free_list + 1; + end_sentinel->next = 0; + + malloc_bytes_used = 0; + } + else if (pre_alloc) + { + /* After having undumped extend malloc block */ + /* Move end_sentinel: */ + new_end = (struct mem_header *)((char *)free_list + malloc_hunk_size + + pre_alloc - sizeof(struct mem_header)); + new_end->size = 0; + new_end->next = 0; + new_end->prev = end_sentinel->prev; + end_sentinel->prev->next = new_end; + + /* Add extra memory (pre_alloc bytes) */ + new_block = (struct mem_header *)((char *)end_sentinel - sizeof(long)); + new_block->size = pre_alloc; + free_hunk((char *)(new_block + 1)); + } + } diff -rcP emacs-18.59-fsf/src/amiga_menu.c emacs-18.59-amiga/src/amiga_menu.c *** emacs-18.59-fsf/src/amiga_menu.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_menu.c Thu Sep 30 21:27:42 1993 *************** *** 0 **** --- 1,309 ---- + #include + #include + #include + #include + #include + #include + #include + #include "config.h" + #undef NULL + #include "lisp.h" + #include "amiga.h" + + #ifndef GTMN_NewLookMenus + #define GTMN_NewLookMenus GT_TagBase+67 + #endif + + static struct Menu *emacs_menu; + static char *emacs_menu_strings; + static APTR win_vi; + struct Library *GadToolsBase; + + void suspend_menus(void) + { + if (emacs_win) + { + ClearMenuStrip(emacs_win); + if (win_vi) + { + FreeVisualInfo(win_vi); + win_vi = 0; + } + } + } + + int resume_menus(void) + { + if (emacs_win && emacs_menu) + { + win_vi = GetVisualInfo(emacs_win->WScreen, TAG_END); + + if (!win_vi || !LayoutMenus(emacs_menu, win_vi, + GTMN_NewLookMenus, 1L, + TAG_END)) + { + if (win_vi) FreeVisualInfo(win_vi); + Famiga_delete_menus(); + + return FALSE; + } + SetMenuStrip(emacs_win, emacs_menu); + } + return TRUE; + } + + DEFUN ("amiga-menus", Famiga_menus, Samiga_menus, 1, 1, 0, + "Define menus for emacs. The argument is a list structured as follows:\n\ + ((menu1-name ((item1-name item1-expr item1-key item1-disabled) ...)\n\ + menu1-disabled) ...)\n\ + menu-name is the name of the menu item header.\n\ + The menu is disabled if menu-disabled is not nil [optional].\n\ + item-name is the name of an item.\n\ + The item-expr fields are ignored.\n\ + If item-key is nil, no shortcut is allowed.\n\ + If item-disabled is not nil, the item is disabled.\n\ + If the item information list is nil, a line is drawn in the menu.\n\ + item-key & item-disabled are optional.") + (menus) + Lisp_Object menus; + { + Lisp_Object s_menus, s_items; + int citems, slen; + char *strdata; + struct NewMenu *menudata, *mkm; + struct Lisp_String *name; + + /* int i; + extern int total[], nb[]; + + for (i = 0; i < 16; i++) + { + printf("%d(%d) ", total[i], nb[i]); + total[i] = nb[i] = 0; + } + printf("\n"); + start_count(15); + for (i = 0; i < 100; i++) { suspend_count(15); resume_count(15); } + stop_count(15); + for (i = 0; i < 100; i++) { start_count(14); stop_count(14); } + printf("100 s/r: %d, 100 s/s: %d\n", total[15], total[14]); + + return Qnil; + */ + check_intuition(); + + /* Check structure of parameter & count # items & menus */ + s_menus = menus; + citems = slen = 0; + + while (!NULL(s_menus)) + { + struct Lisp_Cons *menu, *menu_cell; + + CHECK_CONS(s_menus, 0); + menu_cell = XCONS(s_menus); + citems++; + CHECK_CONS(menu_cell->car, 0); /* Each menu is a list */ + menu = XCONS(menu_cell->car); + + CHECK_STRING(menu->car, 0); /* Check name */ + name = XSTRING(menu->car); + slen += name->size + 1; + CHECK_CONS(menu->cdr, 0); + + menu = XCONS(menu->cdr); /* Check items */ + + s_items = menu->car; + while (!NULL(s_items)) + { + struct Lisp_Cons *item, *item_cell; + + CHECK_CONS(s_items, 0); + item_cell = XCONS(s_items); + citems++; + if (!NULL(item_cell->car)) + { + CHECK_CONS(item_cell->car, 0); /* Each item is a list */ + item = XCONS(item_cell->car); + + CHECK_STRING(item->car, 0); + name = XSTRING(item->car); + slen += name->size + 1; + + if (!NULL(item->cdr)) /* Only name is necessary */ + { + CHECK_CONS(item->cdr, 0); + item = XCONS(item->cdr); + + /* Expr is arbitrary */ + if (!NULL(item->cdr)) + { + CHECK_CONS(item->cdr, 0); + item = XCONS(item->cdr); + + /* Check shortcut */ + if (!NULL(item->car)) + { + CHECK_NUMBER(item->car, 0); + slen += 2; + } + + if (!NULL(item->cdr)) + { + CHECK_CONS(item->cdr, 0); + item = XCONS(item->cdr); + + /* Check that end of list */ + if (!NULL(item->cdr)) error("Badly formed item"); + } + } + } + } + s_items = item_cell->cdr; + } + if (!NULL(menu->cdr)) + { + CHECK_CONS(menu->cdr, 0); + menu = XCONS(menu->cdr); + if (!NULL(menu->cdr)) error("Badly formed menu"); + } + s_menus = menu_cell->cdr; + } + + suspend_menus(); + if (emacs_menu) Famiga_delete_menus(); + + /* Now create menu structure */ + menudata = (struct NewMenu *)alloca(sizeof(struct NewMenu) * (citems + 1)); + emacs_menu_strings = strdata = (char *)xmalloc(slen); + mkm = menudata; + s_menus = menus; + while (!NULL(s_menus)) + { + struct Lisp_Cons *menu, *menu_cell; + struct NewMenu *menu1; + + menu_cell = XCONS(s_menus); + mkm->nm_Type = NM_TITLE; + menu = XCONS(menu_cell->car); + name = XSTRING(menu->car); + strcpy(strdata, name->data); + mkm->nm_Label = strdata; + strdata += name->size + 1; + mkm->nm_CommKey = 0; + mkm->nm_Flags = 0; + mkm->nm_MutualExclude = 0; + menu1 = mkm++; + + menu = XCONS(menu->cdr); /* Check items */ + + s_items = menu->car; + while (!NULL(s_items)) + { + struct Lisp_Cons *item, *item_cell; + + item_cell = XCONS(s_items); + mkm->nm_Type = NM_ITEM; + mkm->nm_CommKey = 0; + mkm->nm_Flags = 0; + mkm->nm_MutualExclude = 0; + if (NULL(item_cell->car)) + { + mkm->nm_Type = IM_ITEM; + mkm->nm_Label = NM_BARLABEL; + } + else + { + + item = XCONS(item_cell->car); + name = XSTRING(item->car); + strcpy(strdata, name->data); + mkm->nm_Label = strdata; + strdata += name->size + 1; + + if (!NULL(item->cdr)) /* Only name is necessary */ + { + item = XCONS(item->cdr); + + /* Expr is ignored */ + + if (!NULL(item->cdr)) + { + item = XCONS(item->cdr); + + /* Check shortcut */ + if (!NULL(item->car)) + { + mkm->nm_CommKey = strdata; + strdata[0] = XFASTINT(item->car); + strdata[1] = '\0'; + strdata += 2; + } + if (!NULL(item->cdr)) + { + item = XCONS(item->cdr); + if (!NULL(item->car)) + mkm->nm_Flags |= NM_ITEMDISABLED; + } + } + } + } + mkm++; + s_items = item_cell->cdr; + } + if (!NULL(menu->cdr)) + { + menu = XCONS(menu->cdr); + if (!NULL(menu->car)) menu1->nm_Flags |= NM_MENUDISABLED; + } + s_menus = menu_cell->cdr; + } + mkm->nm_Type = NM_END; + mkm->nm_Label = 0; + mkm->nm_CommKey = 0; + mkm->nm_Flags = 0; + mkm->nm_MutualExclude = 0; + if (!(emacs_menu = CreateMenus(menudata, TAG_END))) + { + free(emacs_menu_strings); + emacs_menu_strings = 0; + error("Menu couldn't be created"); + } + if (!resume_menus()) error("Menu couldn't be layed out"); + + return Qt; + } + + DEFUN ("amiga-delete-menus", Famiga_delete_menus, Samiga_delete_menus, 0, 0, 0, + "Remove & free menu strip") + () + { + check_intuition(); + + suspend_menus(); + if (emacs_menu) FreeMenus(emacs_menu); + emacs_menu = 0; + if (emacs_menu_strings) free(emacs_menu_strings); + emacs_menu_strings = 0; + + return Qt; + } + + void syms_of_amiga_menu(void) + { + defsubr(&Samiga_delete_menus); + defsubr(&Samiga_menus); + } + + void init_amiga_menu(void) + { + GadToolsBase = OpenLibrary("gadtools.library", 0); + if (!GadToolsBase) _fail("gadtools.library required"); + } + + void cleanup_amiga_menu(void) + { + suspend_menus(); + if (emacs_menu) Famiga_delete_menus(); + if (GadToolsBase) CloseLibrary(GadToolsBase); + } diff -rcP emacs-18.59-fsf/src/amiga_processes.c emacs-18.59-amiga/src/amiga_processes.c *** emacs-18.59-fsf/src/amiga_processes.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_processes.c Sun Nov 22 10:13:02 1992 *************** *** 0 **** --- 1,94 ---- + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #undef signal + #include + #include + #include + #include + #include + + #include "config.h" + #include "lisp.h" + #include "amiga.h" + #include "emacssignal.h" + + extern struct ExecBase *SysBase; + + int amiga_process_stack_size; + + /* A few emacs support functions */ + /* ----------------------------- */ + + wait_for_termination (pid) + int pid; + { + while (1) + { + sigsetmask (sigmask (SIGCHLD)); + if (0 > kill (pid, 0)) + { + sigsetmask (SIGEMPTYMASK); + break; + } + sigpause (SIGEMPTYMASK); + } + } + + char *amiga_path(void) + { + char *path, *pp, name[128]; + int pathsize; + struct CommandLineInterface *cli; + BPTR lock; + long l, *lp, nlen; + + pathsize = 128; + path = (char *)xmalloc(pathsize); + + strcpy(path, "."); + pp = path + 1; + + if (!(cli = (struct CommandLineInterface *)((long)_us->pr_CLI << 2))) + return path; + + l = (long)cli->cli_CommandDir; + while (l) { + *pp++ = ','; + l <<= 2; + lp = (long *)l; + lock = (BPTR)*(lp + 1); + NameFromLock(lock, name, 128); + nlen = strlen(name); + if (pp + nlen + 5 >= path + pathsize) + { + char *newpath; + + pathsize = 2 * pathsize + nlen; + newpath = (char *)xrealloc(path); + pp = newpath + (pp - path); + path = newpath; + } + memcpy(pp, name, nlen); + pp += nlen; + l = *lp; + } + /* Use of +5 above guarantees that there is enough space for c: */ + strcpy(pp, ",c:"); + + return path; + } + + void syms_of_amiga_processes(void) + { + amiga_process_stack_size = 0; + DEFVAR_INT("amiga-process-stack-size", &amiga_process_stack_size, + "Size of stack for called processes. 0 means same size as emacs stack."); + } diff -rcP emacs-18.59-fsf/src/amiga_rexx.c emacs-18.59-amiga/src/amiga_rexx.c *** emacs-18.59-fsf/src/amiga_rexx.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_rexx.c Sat Jun 5 13:21:16 1993 *************** *** 0 **** --- 1,460 ---- + /* low level ARexx code for use in amiga version of Emacs. + Copyright (C) 1993 Christian E. Hopps. + + This file is part of GNU Emacs. + + GNU Emacs is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Emacs; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + #include "SimpleRexx.h" + #include + #undef NULL + #include "config.h" + #include "lisp.h" + + #include "amiga.h" + + #define XLRXMSG(x) ((struct LispRexxMsg *) XPNTR((x))) + #define XSETLRXMSG(x,v) (XSET((x), Lisp_Int, v)) + + static AREXXCONTEXT far handle; + static int amiga_arexx_initialized; + + /* This structure should be allocated with emacs_malloc() its pointer will be */ + /* used as an msgid. (emacs XUINT())*/ + struct LispRexxMsg { + struct MinNode lrm_Node; /* A node for tracking messages. */ + struct RexxMsg *lrm_Msg; /* The actual Rexx Msg. */ + ULONG lrm_Flags; + }; + /* Flags for LispRexxMessage indicating what to do with it. */ + #define LRMF_SENTCMD (1L << 0) /* this msg originated here. */ + #define LRMF_DOERRORS (1L << 1) /* handle error replies */ + #define LRMF_DORESULTS (1L << 2) /* handle result strings */ + + struct LispRexxList { + struct MinList lrl_List; + int lrl_Count; + }; + + struct LispRexxList pending; /* The list of pending */ + /* (outgoing) Rexx Messages. */ + struct LispRexxList returned; /* The list of pending */ + /* (outgoing) Rexx Messages */ + /* that have been received. */ + struct LispRexxList incoming; /* The message that are */ + /* incoming to Emacs (sent */ + /* from some other rexx host. */ + + /* allocate a rexx message properly */ + Lisp_Object alloc_rexx_msg(ULONG flags) + { + Lisp_Object rm = Qnil; + struct LispRexxMsg *lrm = (struct LispRexxMsg *)malloc(sizeof(*lrm)); + if(lrm) { + lrm->lrm_Flags = flags; + XSETLRXMSG(rm,lrm); + return(rm); + } + return(Qnil); + } + + /* free an arexx message allocated with alloc_arexx_msg() */ + void free_rexx_msg (Lisp_Object rm) + { + if(!NULL(rm)) { + void *mem = XLRXMSG(rm); + free(mem); + } + } + + /* The next 2 functions imlement FIFO lists. */ + + /* add LispRexxMsg to a LispRexxLisp Tail. */ + void add_rexx_msg_to_tail(struct LispRexxList *rl, Lisp_Object rm) + { + AddTail((struct List *)rl,(struct Node *)XPNTR(rm)); + rl->lrl_Count++; + } + + /* remove LispRexxMsg from head of a LispRexxLisp. */ + Lisp_Object remove_rexx_msg_from_head(struct LispRexxList *rl) + { + Lisp_Object rm = (Lisp_Object)RemHead((struct List *)rl); + if(rm != 0) { + rl->lrl_Count--; + return(rm); + } else { + return Qnil; + } + } + + void remove_rexx_msg(struct LispRexxList *rl, Lisp_Object rm) + { + Remove((struct Node *)XPNTR(rm)); + rl->lrl_Count--; + } + + + /* find a rexx message on a list given an msgid (ptr) */ + int is_rexx_msgid_on_list(struct LispRexxList *rl, + Lisp_Object id) + { + struct MinNode *mn = rl->lrl_List.mlh_Head; + for(mn; mn->mln_Succ; mn = mn->mln_Succ) { + Lisp_Object cmpid = Qnil; + XSETLRXMSG(cmpid,mn); + if( EQ(cmpid,id)) { + return(1); + } + } + return(0); + } + + Lisp_Object find_rexx_msg_on_list(struct LispRexxList *rl, + struct RexxMsg *msg) + { + Lisp_Object pnt = Qnil; + struct MinNode *mn = rl->lrl_List.mlh_Head; + for(mn; mn->mln_Succ; mn = mn->mln_Succ) { + if( ((struct LispRexxMsg *)mn)->lrm_Msg == msg) { + XSETLRXMSG(pnt,mn); + } + } + return(pnt); + } + + /* This function is given a RexxMsg and it goes and find (or doesn't) the */ + /* corisponding pending message, removes it from the list and sets up the lisp */ + /* list for return values. if it is not found nil is returned. (it deals with */ + /* the errors for incoming messages properly. Some thought is needed on how to */ + /* handle errors from replied sent commands that were not asking for results. */ + Lisp_Object handle_rexx_msg_replied(struct RexxMsg *msg) + { + Lisp_Object rm = find_rexx_msg_on_list(&pending, msg); + if(!NULL(rm)) { + /* Process the command. If it was requesting results strings handle */ + /* them otherwise just delete. */ + struct LispRexxMsg *lrm = XLRXMSG(rm); + remove_rexx_msg(&pending, rm); + + if(msg->rm_Result1 == 0) { + if(lrm->lrm_Flags & LRMF_DORESULTS) { + /* add to returned so that result can be fetched. */ + add_rexx_msg_to_tail(&returned,rm); + } else { + /* simply delete rexx message. */ + DeleteARexxMsg(handle,msg); + free_rexx_msg(rm); + } + } else { + /* an error occured with our message. */ + if(lrm->lrm_Flags & LRMF_DOERRORS) { + /* add to returned so that error can be fetched. */ + add_rexx_msg_to_tail(&returned,rm); + } else { + /* simply delete rexx message. */ + DeleteARexxMsg(handle,msg); + free_rexx_msg(rm); + } + } + } else { + /* This should never happen we received a rexx message reply */ + /* that we never sent out. */ + DeleteARexxMsg(handle,msg); + } + } + + /* This function takes incoming messages and place them on the incoming msg */ + /* list. */ + Lisp_Object handle_rexx_msg_received(struct RexxMsg *msg) + { + Lisp_Object rm = alloc_rexx_msg(LRMF_DORESULTS|LRMF_DOERRORS); + if(!NULL(rm)) { + /* Add message to incoming list. */ + struct LispRexxMsg *lrm = XLRXMSG(rm); + lrm->lrm_Msg = msg; /* set msg pointer. */ + add_rexx_msg_to_tail(&incoming,rm); + } else { + /* This should never happen we received a rexx message but ran out of */ + /* memory. Set last error msg. and reply with fail. */ + SetARexxLastError(handle, msg, "Out of emacs memory."); + ReplyARexxMsg(handle, msg, 0, 20); + } + } + + /* Almost the same as old one, but we now call handle_pending_arexx_reply() for */ + /* replied messages that we sent, so that we can setup result strings and such. */ + int check_arexx(int force, int kbd) + { + struct RexxMsg *msg; + int msg_received = FALSE; + while (msg = GetARexxMsg(handle)) { + msg_received = TRUE; + if(msg->rm_Node.mn_Node.ln_Type == NT_REPLYMSG) { + /* This is a reply to a rexx command we send out. */ + handle_rexx_msg_replied(msg); + } else { + handle_rexx_msg_received(msg); + } + } + if ((kbd && amiga_arexx_initialized)) { + /* if we got a message or we have some out, or we have some waiting to */ + /* be processes then enque the Key sequence that will call the rexx */ + /* message handler. We obviously don't do this for returned commands :^) */ + if ((msg_received || force && incoming.lrl_Count > 0) && + get_ttycount() == 0) { + enque(AMIGASEQ, FALSE); enque('X', FALSE); + } + } + return msg_received; + } + + DEFUN ("amiga-arexx-wait", Famiga_arexx_wait, Samiga_arexx_wait, 0, 0, 0, + "Wait for an ARexx event (command or reply) before proceeding.") + () + { + while (!check_arexx(FALSE, FALSE)) Wait(ARexxSignal(handle)); + } + + DEFUN ("amiga-arexx-check-command", + Famiga_arexx_check_command, Samiga_arexx_check_command, 1, 1, 0, + "Return t if command ID has finished, nil otherwise.") + (id) + Lisp_Object id; + { + CHECK_NUMBER(id,0); + + if(is_rexx_msgid_on_list(&pending,id)) { + /* still on pending return false. */ + return Qnil; + } else if(is_rexx_msgid_on_list(&returned,id)) { + /* is waiting to be processed return true. */ + return Qt; + } + + /* is nowhere to be found. error. */ + error("id not found."); + return Qnil; + } + + DEFUN ("amiga-arexx-get-next-msg", Famiga_arexx_get_next_msg, + Samiga_get_next_msg, 0, 0, 0, + "Returns the oldest arexx msg sent to emacs rexx port.\n\ + When you are through with this message call (amiga-arexx-reply).\n\ + if the msg is not replied this function will continue to\n\ + return that msg until it has been replied to.") + () + { + struct RexxMsg *rmsg; + + check_arexx(FALSE, FALSE); + if (incoming.lrl_Count) { + struct RexxMsg *msg = ((struct LispRexxMsg *) + incoming.lrl_List.mlh_Head)->lrm_Msg; + return build_string(ARG0(msg)); + } + /* nothing to be gotten. */ + return Qnil; + } + + DEFUN("amiga-arexx-get-msg-results", Famiga_arexx_get_msg_results, + Samiga_arexx_get_msg_results, 1,1,0, + "Returns the results from MSGID. will be a list of the form:\n\ + (msgid resultcode secondary)\n\n\ + If resultcode is 0 then secondary will be a string or nil.\n\ + else resulcode will be greater than 0 and secondary will be\n\ + an error-code (int).\n\n\ + If MSGID has not yet completed nil is returned.\n\ + if MSGID has been dealt with or is invalid and error will occur.") + (msgid) + Lisp_Object msgid; + { + CHECK_NUMBER(msgid,0); + + if(is_rexx_msgid_on_list(&returned,msgid)) { + /* msgid has completed build list and delete LispRexxMsg. */ + struct LispRexxMsg *lrm = XLRXMSG(msgid); + Lisp_Object rc, error_or_string, ret; + struct RexxMsg *msg = lrm->lrm_Msg; + + remove_rexx_msg(&returned,msgid); + + rc = make_number(msg->rm_Result1); + if(msg->rm_Result1 == 0) { + error_or_string = msg->rm_Result2 ? build_string(msg->rm_Result2) : 0; + } else { + /* error occurred */ + error_or_string = make_number(msg->rm_Result2); /* save error code. */ + } + free_rexx_msg(msgid); /* free our rexx msg. */ + DeleteARexxMsg(handle,msg); /* free ARexx msg proper */ + + /* build lisp list. */ + ret = Fcons( msgid, Fcons( rc, Fcons(error_or_string, Qnil))); + if(NULL(ret)) { + error("Couldn't get memory."); + } + return(ret); + } else if(is_rexx_msgid_on_list(&pending,msgid)) { + return Qnil; /* this msgid has not yet completed. */ + } else { + error("Unknown MSGID."); + return Qnil; + } + } + + DEFUN ("amiga-arexx-reply", Famiga_arexx_reply, Samiga_arexx_reply, + 2, 2, 0, + "Replies to the first arexx message (the one got via amiga-arexx-get-event)\n\ + with RC as return code.\n\ + If RC=0, TEXT is the result, otherwise it is the error text. It can be nil.") + (rc, text) + Lisp_Object rc, text; + { + int retcode, ok = TRUE; + char *result; + struct RexxMsg *rmsg; + Lisp_Object rm = remove_rexx_msg_from_head(&incoming); + struct LispRexxMsg *lrm = XLRXMSG(rm); + + if (NULL(rm)) + error("No ARexx message to reply to."); + + rmsg = lrm->lrm_Msg; + + CHECK_NUMBER(rc, 0); + retcode = XINT(rc); + + if (!NULL (text)) { + CHECK_STRING(text, 0); + result = XSTRING (text)->data; + } else { + result = 0; + } + if (retcode && result) + ok = SetARexxLastError(handle, rmsg, result); + ReplyARexxMsg(handle, rmsg, result, retcode); + + if (!ok) + error("Failed to set ARexx error message."); + + return Qnil; + } + + Lisp_Object send_rexx_command(Lisp_Object str, Lisp_Object as_file, + ULONG flags) + { + struct RexxMsg *rmsg; + int i; + Lisp_Object id, rm; + struct LispRexxMsg *lrm; + + rm = alloc_rexx_msg(flags); + if(NULL(rm)) { + error("Failed to send command to ARexx."); + return Qnil; + } + + CHECK_STRING (str, 0); + if (!(rmsg = SendARexxMsg(handle, XSTRING (str)->data,!NULL (as_file), + (flags & LRMF_DORESULTS ? 1 : 0)))) { + free_rexx_msg(rm); + error("Failed to send command to ARexx."); + return Qnil; + } + lrm = XLRXMSG(rm); + lrm->lrm_Msg = rmsg; /* set rexx message pointer. */ + add_rexx_msg_to_tail(&pending,rm); /* add to pending list. */ + + return(rm); + } + + DEFUN ("amiga-arexx-send-command", Famiga_arexx_send_command, + Samiga_arexx_send_command, 1, 2, 0, + "Sends a command to ARexx for execution.\n\ + If the second arg is non-nil, the command is directly interpreted.\n\ + Returns an integer that uniquely identifies this message. This must\n\ + then be used to get the results from the command.\n\ + NOTE: this is very different from old way things worked.\n\ + earlier versions of emacs discarded successful results\n\ + and errors always got replied to becuase they caused failures\n\ + Neither of these are true now.\ + This function is also no longer interactive.\n\ + Use (amiga-arexx-do-command)\n") + (str, as_file) + Lisp_Object str, as_file; + { + return(send_rexx_command(str,as_file, + LRMF_DORESULTS| + LRMF_DOERRORS| + LRMF_SENTCMD)); + } + + void init_amiga_rexx(void) + { + extern ULONG inputsig; + int i; + + handle = InitARexx("Emacs", "elx"); + inputsig |= ARexxSignal(handle); + + /* init exec lists. */ + NewList((struct List *)&incoming.lrl_List); + incoming.lrl_Count = 0; + + NewList((struct List *)&pending.lrl_List); + pending.lrl_Count = 0; + + NewList((struct List *)&returned.lrl_List); + returned.lrl_Count = 0; + } + + void cleanup_amiga_rexx(void) + { + /* Delete and reply all rexx messages we have gotten. */ + Lisp_Object rm = remove_rexx_msg_from_head(&returned); + while(!NULL(rm)) { + struct LispRexxMsg *lrm = XLRXMSG(rm); + DeleteARexxMsg(handle,lrm->lrm_Msg); + free_rexx_msg(rm); + rm = remove_rexx_msg_from_head(&returned); + } + + rm = remove_rexx_msg_from_head(&incoming); + while(!NULL(rm)) { + struct LispRexxMsg *lrm = XLRXMSG(rm); + ReplyARexxMsg(handle, lrm->lrm_Msg, 0, 20); + free_rexx_msg(rm); + rm = remove_rexx_msg_from_head(&incoming); + } + + /* Free the rest of rexx, will wait for pending msgs to return */ + FreeARexx(handle); + } + + void syms_of_amiga_rexx(void) + { + DEFVAR_BOOL ("amiga-arexx-initialized", &amiga_arexx_initialized, + "Set this to t when Emacs is ready to respond to ARexx messages.\n" + "(ie C-\ X causes all pending ARexx messages to be answered)"); + amiga_arexx_initialized = 0; + + defsubr(&Samiga_arexx_send_command); + defsubr(&Samiga_arexx_reply); + defsubr(&Samiga_get_next_msg); + defsubr(&Samiga_arexx_get_msg_results); + defsubr(&Samiga_arexx_check_command); + defsubr(&Samiga_arexx_wait); + } diff -rcP emacs-18.59-fsf/src/amiga_screen.c emacs-18.59-amiga/src/amiga_screen.c *** emacs-18.59-fsf/src/amiga_screen.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_screen.c Tue Aug 31 18:16:14 1993 *************** *** 0 **** --- 1,1396 ---- + #include "config.h" + #undef NULL + #include "lisp.h" + #include "termchar.h" + #include "dispextern.h" + + #include + #include + #include + #include + #include + + #define min(x,y) ((x) > (y) ? (y) : (x)) + #define max(x,y) ((x) < (y) ? (y) : (x)) + + #undef LONGBITS + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + /* this is defined for those unlucky enough + * not to have the 3.0 headers -ch3/16/93. */ + #ifndef WA_NewLookMenus + #define WA_NewLookMenus (WA_Dummy + 0x30) + #endif + + #include "amiga.h" + + #define SHIFT_MASK (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT) + #define CONTROL_MASK IEQUALIFIER_CONTROL + #define META_MASK IEQUALIFIER_LALT + + struct GfxBase *GfxBase; + struct IntuitionBase *IntuitionBase; + struct Library *DiskfontBase, *KeymapBase, *WorkbenchBase; + + static char intkey_code, intkey_qualifier; + static struct IOStdReq *input_req; + static struct Interrupt int_handler_hook; + static int hooked; + + static struct MsgPort *wbport; + static struct AppWindow *emacs_app_win; + static struct AppIcon *emacs_icon; + + struct Library *ConsoleDevice; + static struct TextFont *font; + static int font_opened; + /* The reset string resets the console, turns off scrolling and sets up + the foreground & background colors. */ + #define CONSOLE_RESET "\x1b""c\x9b>1l\x9b""3%d;4%d;>%dm" + static char reset_string[20]; /* Must be big enough for + printf(CONSOLE_RESET, foreground, background, background); + (0 <= foreground, background <= 7) */ + + /* These are the pen numbers for emacs window's base colors */ + int foreground = 1, background = 0; + + /* Current window, and its main characteristics */ + struct Window *emacs_win; + WORD emacs_x = 0, emacs_y = 0, emacs_w = 640, emacs_h = 200; + char *emacs_screen_name; + char emacs_screen_name_storage[MAXPUBSCREENNAME+1]; + int emacs_backdrop = 0; /* Use backdrop window ? */ + + /* Current window size: */ + #define EMACS_X() (emacs_win ? emacs_win->LeftEdge : emacs_x) + #define EMACS_Y() (emacs_win ? emacs_win->TopEdge : emacs_y) + #define EMACS_W() (emacs_win ? emacs_win->Width : emacs_w) + #define EMACS_H() (emacs_win ? emacs_win->Height : emacs_h) + + /* used for setting the color of standout text -ch3/16/93. */ + int inverse_fill_pen = 8, inverse_text_pen = 8; + + /* IO request for all console io. */ + static struct IOStdReq *emacs_console; + + /* a storage area for the name of the screen last opened on */ + + #define emacs_icon_width 57 + #define emacs_icon_height 55 + #define emacs_icon_num_planes 1 + #define emacs_icon_words_per_plane 220 + + UWORD chip emacs_icon_data[1][55][4] = { + { + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0fe0,0x6000, + 0x0000,0x0000,0x0060,0x6000,0x0000,0x0000,0x0fff,0xe000, + 0x0000,0x0000,0x1800,0x2000,0x0000,0x0000,0x13ff,0xa000, + 0x0000,0x0000,0x1400,0xa000,0x0000,0x0000,0x3600,0xa000, + 0x0000,0x0000,0x0000,0xa000,0x0000,0x0000,0x0c00,0xa000, + 0x0000,0x0000,0x1e00,0xa000,0x0000,0x0000,0x0c00,0xa000, + 0x0000,0x0000,0x0000,0xa000,0x0000,0x0000,0x2100,0xa000, + 0x0000,0x0000,0x3300,0xa000,0x0000,0x0000,0x0c00,0xa000, + 0x003f,0xffff,0xffff,0xb000,0x001f,0xffff,0xffff,0x8000, + 0x004e,0x0000,0x0001,0xf000,0x00c6,0x00f0,0x0001,0x8000, + 0x00c6,0x0100,0x0001,0x8000,0x0006,0x0103,0x9201,0x8000, + 0x0006,0x013a,0x5201,0x8000,0x00c6,0x010a,0x5201,0x8000, + 0x00c6,0x010a,0x5601,0x8000,0x0086,0x00f2,0x4a01,0x8000, + 0x0006,0x0000,0x0001,0x8000,0x0046,0x0000,0x0001,0x8000, + 0x00c6,0x7c00,0x0001,0x8000,0x00c6,0x4000,0x0001,0x8000, + 0x0006,0x41d8,0xc319,0x8000,0x0006,0x7925,0x24a1,0x8000, + 0x00c6,0x4125,0x2419,0x8000,0x01c6,0x4125,0x2485,0x8000, + 0x0086,0x7d24,0xd319,0x8000,0x0007,0x0000,0x0003,0x8000, + 0x0003,0xffe3,0xffff,0x0000,0x0081,0xfff7,0xfffe,0x0000, + 0x01c0,0x0036,0x0000,0x0000,0x0180,0x0014,0x0f80,0x0000, + 0x0000,0x0014,0x1040,0x0000,0x0000,0x0014,0x2720,0x0000, + 0x0000,0x0012,0x28a0,0x0000,0x0080,0x000a,0x48a0,0x0000, + 0x01c0,0x0009,0x90a0,0x0000,0x0180,0x0004,0x20a0,0x0000, + 0x0000,0x0003,0xc0a0,0x0000,0x0000,0x0000,0x00a0,0x0000, + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000, + 0x0000,0x0000,0x0000,0x0000 + }, + }; + + struct Image far emacs_icon_image = { + 0, 0, + emacs_icon_width, emacs_icon_height, emacs_icon_num_planes, + (UWORD *)emacs_icon_data, + 3, 0, + 0 + }; + + static struct DiskObject far emacs_icon_object = { + 0, 0, + { 0, 0, 0, emacs_icon_width, emacs_icon_height, 0, 0, 0, (APTR)&emacs_icon_image }, + 0, 0, 0, + NO_ICON_POSITION, NO_ICON_POSITION + }; + + static struct Hook background_hook; + + #define EVENTSIZE 32 + + static struct event { + ULONG class; + UWORD code, qual; + WORD x, y; + } events[EVENTSIZE]; + static int event_num, event_in, event_out; + + static struct wbevent { + struct wbevent *next; + char file[1]; + } *wbevents; + + Lisp_Object Vamiga_mouse_pos; + Lisp_Object Vamiga_mouse_item; + extern Lisp_Object MouseMap; + int amiga_remap_bsdel; + int amiga_remap_numeric_keypad; + int amiga_mouse_initialized; + int amiga_wb_initialized; + int emacs_iconified; + + static int amiga_pos_x(int x) + { + return (x - emacs_win->BorderLeft) / emacs_win->RPort->Font->tf_XSize; + } + + static int amiga_pos_y(int y) + { + return (y - emacs_win->BorderTop) / emacs_win->RPort->Font->tf_YSize; + } + + static void amiga_change_size(void) + { + int new_height = amiga_pos_y(emacs_win->Height - emacs_win->BorderBottom); + int new_width = amiga_pos_x(emacs_win->Width - emacs_win->BorderRight); + + /* Hack to force redisplay */ + if (screen_height == new_height) screen_height--; + /* I consider that refreshes are possible during a select, which is + true for the current state of emacs */ + change_screen_size(new_height, new_width, 0, !selecting && !waiting_for_input, 1); + } + + /* Get terminal size from system. + Store number of lines into *heightp and width into *widthp. + If zero or a negative number is stored, the value is not valid. */ + + void get_window_size (widthp, heightp) + int *widthp, *heightp; + { + if (emacs_win) + { + *heightp = amiga_pos_y(emacs_win->Height - emacs_win->BorderBottom); + *widthp = amiga_pos_x(emacs_win->Width - emacs_win->BorderRight); + } + else + { + *heightp = 0; + *widthp = 0; + } + } + + static int set_min_size(struct Window *win, struct TextFont *font, + WORD *minw, WORD *minh) + { + *minw = 11 * font->tf_XSize + win->BorderLeft + win->BorderRight; + *minh = 4 * font->tf_YSize + win->BorderTop + win->BorderBottom; + + return (int)WindowLimits(win, *minw, *minh, 0, 0); + } + + struct fill + { + struct Layer *layer; + struct Rectangle bounds; + WORD offsetx, offsety; + }; + + /* __interrupt disables stack checking. -ch3/19/93. */ + static ULONG __asm __saveds __interrupt + fill_background(register __a2 struct RastPort *obj, + register __a1 struct fill *msg) + { + struct Layer *l; + + SetAPen(obj, background); + SetDrMd(obj, JAM1); + SetAfPt(obj, 0, 0); + SetWrMsk(obj, 0xff); + /* Gross hack starts here */ + l = obj->Layer; + obj->Layer = 0; + /* Stops */ + RectFill(obj, msg->bounds.MinX, msg->bounds.MinY, + msg->bounds.MaxX, msg->bounds.MaxY); + /* Starts again */ + obj->Layer = l; + /* And finally dies */ + + return 0; + } + + static void clear_window(void) + { + SetAPen(emacs_win->RPort, background); + RectFill(emacs_win->RPort, emacs_win->BorderLeft, emacs_win->BorderTop, + emacs_win->Width - emacs_win->BorderRight - 1, + emacs_win->Height - emacs_win->BorderBottom - 1); + } + + static int make_reset_string(void) + { + sprintf(reset_string, CONSOLE_RESET, foreground, background, background); + } + + void reset_window(void) + { + make_reset_string(); + if (emacs_win) + { + screen_puts (reset_string, strlen(reset_string)); + clear_window(); + amiga_change_size (); + } + } + + static void close_app_win(void) + { + if (emacs_app_win) + { + struct AppMessage *msg; + + RemoveAppWindow(emacs_app_win); /* What can I do if it fails ?! */ + while (msg = (struct AppMessage *)GetMsg(wbport)) ReplyMsg(msg); + } + } + + static int close_emacs_window(void) + { + close_app_win(); + inputsig &= ~(1L << emacs_win->UserPort->mp_SigBit); + _device_close(emacs_console); + if(emacs_win) + { + /* put title back the way it should be -ch3/19/93. */ + ShowTitle(emacs_win->WScreen, !emacs_backdrop); + } + CloseWindow(emacs_win); + emacs_console = 0; + emacs_win = 0; + ConsoleDevice = 0; + } + + /* We need this function becuase we do not always have the string + * for the screen we opened on. for example LockPubScreen(NULL); + * This function will get the name by looping through all public + * screens looking for the one that matches ours. -ch3/20/93 */ + + char *get_screen_name(struct Screen *this, char *namebuf) + { + struct PubScreenNode *pubscreens = + (struct PubScreenNode *)LockPubScreenList()->lh_Head; + + while (pubscreens->psn_Node.ln_Succ) + { + if (pubscreens->psn_Screen == this) + { + strcpy(namebuf, pubscreens->psn_Node.ln_Name); + UnlockPubScreenList(); + return namebuf; + } + pubscreens = (struct PubScreenNode *)pubscreens->psn_Node.ln_Succ; + } + /* Failed to find screen */ + namebuf[0] = '\0'; + UnlockPubScreenList(); + + return 0; + } + + /* added two parameters to eliminate the need for the global + * which was causing some unwanted effect (bugs). -ch3/19/93 */ + + static enum { ok, no_screen, no_window } + open_emacs_window(UWORD x, UWORD y, UWORD w, UWORD h, int backdrop, + char *pubscreen_name) + /* Open or reopen emacs window */ + { + WORD minw, minh; + struct Screen *new_screen; + struct Window *new_win; + struct IOStdReq *new_console; + int no_backdrop = !backdrop; + + new_screen = LockPubScreen(pubscreen_name); + + if (!new_screen) + return no_screen; + + /* removed newwindow structure, and added as tag + * items so that we can change them easier. -ch3/16/93. */ + + new_win = OpenWindowTags(0, WA_Left, x, WA_Top, y, + WA_Width, w, WA_Height, h, /* Static items */ + WA_AutoAdjust, 1, WA_NewLookMenus, 1, + WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY | + IDCMP_MOUSEBUTTONS| IDCMP_NEWSIZE | + IDCMP_MENUPICK | IDCMP_MENUHELP, + WA_PubScreen, new_screen, + WA_BackFill, &background_hook, + WA_MenuHelp, 1, WA_Activate, 1, + WA_SimpleRefresh, 1, + WA_MaxWidth, -1, WA_MaxHeight, -1, + WA_Backdrop, backdrop, /* changing items */ + WA_Borderless, backdrop, + WA_CloseGadget, no_backdrop, + WA_SizeGadget, no_backdrop, + WA_DragBar, no_backdrop, + WA_DepthGadget, no_backdrop, + WA_Title, no_backdrop ? + "GNU Emacs 18.59, Amiga port "VERS : 0, + TAG_END); + + UnlockPubScreen(0L, new_screen); + + if (new_win) + { + /* if emacs_backdrop then the screen title will show BEHIND the window + -ch3/16/93. */ + ShowTitle(new_screen, !emacs_backdrop); + SetFont(new_win->RPort, font); + + if (set_min_size(new_win, font, &minw, &minh) && + (new_console = (struct IOStdReq *) + _device_open("console.device", CONU_CHARMAP, CONFLAG_NODRAW_ON_NEWSIZE, + (APTR)new_win, sizeof(*new_win), + sizeof(struct IOStdReq)))) + { + inputsig |= 1L << new_win->UserPort->mp_SigBit; + ConsoleDevice = (struct Library *)new_console->io_Device; + emacs_app_win = AddAppWindowA(0, 0, new_win, wbport, 0); + + /* Copy the info into permanent storage */ + emacs_win = new_win; + emacs_console = new_console; + + /* fetch the name of the current screen -ch3/19/93 */ + emacs_screen_name = get_screen_name(emacs_win->WScreen, + emacs_screen_name_storage); + + emacs_backdrop = backdrop; + + reset_window(); + + return ok; + } + CloseWindow(new_win); + } + return no_window; + } + + void force_window(void) + { + if (!emacs_win && !emacs_iconified) + { + if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop, + emacs_screen_name) != ok) + { + /* Try to return to defaults (Workbench, etc) */ + if (open_emacs_window(0, 0, 640, 200, 0, 0) != ok) + _fail("I've lost my window ! Exiting."); + } + resume_menus(); + } + } + + /* returns: + * -2 if msg is not class RAWKEY + * same as RawKeyConvert otherwise: + * buffer length if <= kbsize + * -1 else + */ + static DeadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer, int kbsize, + struct KeyMap *kmap) + { + static struct InputEvent ievent = {0, IECLASS_RAWKEY, 0, 0, 0}; + int extra = 0, res; + + if (msg->Class != RAWKEY) return (-2); + + /* Do some keymapping ourselves to make emacs users happy */ + + /* Ctrl-space becomes Ctrl-@ */ + if (msg->Code == 0x40 && msg->Qualifier & CONTROL_MASK) + { + *kbuffer = 0; + return 1; + } + /* Backspace becomes DEL */ + if (msg->Code == 0x41 && amiga_remap_bsdel) + { + *kbuffer = 0177; + return 1; + } + /* And DEL becomes CTRL-D */ + if (msg->Code == 0x46 && amiga_remap_bsdel) + { + *kbuffer = 04; + return 1; + } + /* Stick numeric pad prefix in front of numeric keypad chars */ + if (msg->Qualifier & IEQUALIFIER_NUMERICPAD && amiga_remap_numeric_keypad) + { + *kbuffer++ = 'x' & 037; + *kbuffer++ = '^' & 037; + *kbuffer++ = 'K'; + kbsize -= 3; + extra = 3; + } + + /* pack input event */ + ievent.ie_Code = msg->Code; + + /* Ignore meta in decoding keys */ + ievent.ie_Qualifier = msg->Qualifier & ~META_MASK; + + /* get previous codes from location pointed to by IAddress + * this pointer is valid until IntuiMessage is replied. + */ + ievent.ie_position.ie_addr = *((APTR *)msg->IAddress); + ievent.ie_position.ie_dead.ie_prev1DownQual &= ~META_MASK; + ievent.ie_position.ie_dead.ie_prev2DownQual &= ~META_MASK; + + res = RawKeyConvert(&ievent, kbuffer, kbsize, kmap); + return res ? res + extra : 0; + } + + void add_wbevent(struct WBArg *wbarg) + { + char filename[256]; + + if (wbarg->wa_Lock && NameFromLock(wbarg->wa_Lock, filename, 256)) + { + struct wbevent *event; + + if (wbarg->wa_Name) AddPart(filename, wbarg->wa_Name, 256); + if (event = (struct wbevent *)malloc(offsetof(struct wbevent, file) + + strlen(filename) + 1)) + { + event->next = wbevents; + strcpy(event->file, filename); + wbevents = event; + } + } + } + + void check_window(int force) + { + ULONG class; + USHORT code, qualifier; + UWORD mx, my; + unsigned char buf[32]; + int buflen, deiconify, i; + struct IntuiMessage *msg; + int mouse_event = FALSE, wb_event = FALSE; + struct AppMessage *amsg; + + force_window(); + + if (emacs_win) + while (msg = (struct IntuiMessage *)GetMsg(emacs_win->UserPort)) + { + class = msg->Class; + code = msg->Code; + qualifier = msg->Qualifier; + mx = msg->MouseX; my = msg->MouseY; + buflen = DeadKeyConvert(msg, buf, 32, 0); + ReplyMsg(msg); + + switch (class) + { + case IDCMP_CLOSEWINDOW: { + enque(030, FALSE); enque(03, FALSE); /* ^X^C */ + break; + } + case IDCMP_RAWKEY: { + if (buflen > 0) + { + unsigned char *sbuf = buf; + int meta = qualifier & META_MASK; + + /* Don't set META on CSI */ + do enque(*sbuf++, meta); while (--buflen); + } + break; + } + case IDCMP_NEWSIZE: amiga_change_size(); break; + case IDCMP_MENUPICK: case IDCMP_MENUHELP: + if (code == MENUNULL) break; /* else fall through */ + case IDCMP_MOUSEBUTTONS: { + mouse_event = TRUE; + if (event_num == EVENTSIZE) break; + + events[event_in].class = class; + events[event_in].code = code; + events[event_in].qual = qualifier; + events[event_in].x = mx; + events[event_in].y = my; + event_num++; + event_in = (event_in + 1) % EVENTSIZE; + + break; + } + } + } + /* Handle App requests */ + while (amsg = (struct AppMessage *)GetMsg(wbport)) + switch (amsg->am_Type) + { + case MTYPE_APPICON: case MTYPE_APPWINDOW: + /* Add an event for all these files */ + for (i = 0; i < amsg->am_NumArgs; i++) add_wbevent(amsg->am_ArgList + i); + wb_event = TRUE; + /* Reply to the message, and deiconify if was icon */ + deiconify = amsg->am_Type == MTYPE_APPICON; + ReplyMsg(amsg); + if (deiconify && emacs_icon) + /* Reopen window */ + if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop, + emacs_screen_name) == ok) + { + resume_menus(); + RemoveAppIcon(emacs_icon); + emacs_icon = 0; + emacs_iconified = 0; + } + break; + default: ReplyMsg(amsg); break; + } + + if (amiga_mouse_initialized && (force && event_num > 0 || mouse_event)) + { + enque(AMIGASEQ, FALSE); enque('M', FALSE); + } + if (amiga_wb_initialized && (force && wbevents || wb_event)) + { + enque(AMIGASEQ, FALSE); enque('W', FALSE); + } + } + + void setup_intchar(char intchar) + { + char cqbuf[2]; + + if (MapANSI(&intchar, 1, cqbuf, 1, 0) == 1) + { + intkey_code = cqbuf[0]; + intkey_qualifier = cqbuf[1]; + } + else + { + /* Default is CTRL-G in usa0 keymap */ + intkey_code = 0x24; + intkey_qualifier = IEQUALIFIER_CONTROL; + } + } + + /* Hack to detect interrupt char as soon as it is pressed */ + /* __interrupt disables stack checking. -ch3/19/93.*/ + static long __saveds __interrupt __asm + int_handler(register __a0 struct InputEvent *ev) + { + struct InputEvent *ep, *laste; + static struct InputEvent retkey; + ULONG lock = LockIBase(0); + + if (emacs_win && IntuitionBase->ActiveWindow == emacs_win) + { + laste = 0; + + /* run down the list of events to see if they pressed the magic key */ + for (ep = ev; ep; laste = ep, ep = ep->ie_NextEvent) + if (ep->ie_Class == IECLASS_RAWKEY && + (ep->ie_Qualifier & 0xff) == intkey_qualifier && + ep->ie_Code == intkey_code) + { + /* Remove this key from input sequence */ + if (laste) laste->ie_NextEvent = ep->ie_NextEvent; + else ev = ep->ie_NextEvent; + + Vquit_flag = Qt; + Signal(_us, SIGBREAKF_CTRL_C); + } + } + UnlockIBase(lock); + + /* pass on the pointer to the event */ + return (long)ev; + } + + DEFUN ("amiga-mouse-events", Famiga_mouse_events, Samiga_mouse_events, 0, 0, 0, + "Return number of pending mouse events from Intuition.") + () + { + register Lisp_Object tem; + + check_intuition (); + + XSET (tem, Lisp_Int, event_num); + + return tem; + } + + DEFUN ("amiga-proc-mouse-event", Famiga_proc_mouse_event, Samiga_proc_mouse_event, + 0, 0, 0, + "Pulls a mouse event out of the mouse event buffer and dispatches\n\ + the appropriate function to act upon this event.") + () + { + register Lisp_Object mouse_cmd; + register char com_letter; + register char key_mask; + register Lisp_Object tempx; + register Lisp_Object tempy; + extern Lisp_Object get_keyelt (); + extern int meta_prefix_char; + struct event *ev; + int posx, posy; + + check_intuition (); + + if (event_num) { + ev = &events[event_out]; + event_out = (event_out + 1) % EVENTSIZE; + event_num--; + if (ev->class == MOUSEBUTTONS) + { + switch (ev->code) + { + case SELECTDOWN: com_letter = 2; break; + case SELECTUP: com_letter = 6; break; + case MIDDLEDOWN: com_letter = 1; break; + case MIDDLEUP: com_letter = 5; break; + case MENUDOWN: com_letter = 0; break; + case MENUUP: com_letter = 4; break; + default: com_letter = 3; break; + } + posx = amiga_pos_x(ev->x); + posy = amiga_pos_y(ev->y); + XSET (tempx, Lisp_Int, min (screen_width-1, max (0, posx))); + XSET (tempy, Lisp_Int, min (screen_height-1, max (0, posy))); + } + else + { + /* Must be Menu Pick or Help */ + com_letter = ev->class == IDCMP_MENUPICK ? 3 : 7; + + /* The parameters passed describe the selected item */ + XSET (tempx, Lisp_Int, MENUNUM(ev->code)); + XSET (tempy, Lisp_Int, ITEMNUM(ev->code)); + } + if (ev->qual & META_MASK) com_letter |= 0x20; + if (ev->qual & SHIFT_MASK) com_letter |= 0x10; + if (ev->qual & CONTROL_MASK) com_letter |= 0x40; + + Vamiga_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil)); + Vamiga_mouse_item = make_number (com_letter); + mouse_cmd = get_keyelt (access_keymap (MouseMap, com_letter)); + if (NULL (mouse_cmd)) { + bell (); + Vamiga_mouse_pos = Qnil; + } + else return call1 (mouse_cmd, Vamiga_mouse_pos); + } + return Qnil; + } + + DEFUN ("amiga-get-mouse-event", Famiga_get_mouse_event, Samiga_get_mouse_event, + 1, 1, 0, + "Get next mouse event out of mouse event buffer (com-letter (x y)).\n\ + ARG non-nil means return nil immediately if no pending event;\n\ + otherwise, wait for an event.") + (arg) + Lisp_Object arg; + { + register char com_letter; + register char key_mask; + + register Lisp_Object tempx; + register Lisp_Object tempy; + struct event *ev; + int posx, posy; + + check_intuition (); + + if (NULL (arg)) + { + amiga_consume_input(); + while (!event_num) + { + int rfds = 1; + + select(1, &rfds, 0, 0, 0); + amiga_consume_input(); + } + } + /*** ??? Surely you don't mean to busy wait??? */ + + if (event_num) { + ev = &events[event_out]; + event_out = (event_out + 1) % EVENTSIZE; + event_num--; + switch (ev->code) + { + case SELECTDOWN: com_letter = 2; break; + case SELECTUP: com_letter = 6; break; + case MIDDLEDOWN: com_letter = 1; break; + case MIDDLEUP: com_letter = 5; break; + case MENUDOWN: com_letter = 0; break; + case MENUUP: com_letter = 4; break; + default: com_letter = 3; break; + } + if (ev->qual & META_MASK) com_letter |= 0x20; + if (ev->qual & SHIFT_MASK) com_letter |= 0x10; + if (ev->qual & CONTROL_MASK) com_letter |= 0x40; + + posx = amiga_pos_x(ev->x); + posy = amiga_pos_y(ev->y); + XSET (tempx, Lisp_Int, min (screen_width-1, max (0, posx))); + XSET (tempy, Lisp_Int, min (screen_height-1, max (0, posy))); + + Vamiga_mouse_pos = Fcons (tempx, Fcons (tempy, Qnil)); + Vamiga_mouse_item = make_number (com_letter); + return Fcons (com_letter, Fcons (Vamiga_mouse_pos, Qnil)); + } + return Qnil; + } + + DEFUN ("amiga-get-wb-event", Famiga_get_wb_event, Samiga_get_wb_event, + 1, 1, 0, + "Get next Workbench event out of workbench event buffer (a file name).\n\ + ARG non-nil means return nil immediately if no pending event;\n\ + otherwise, wait for an event.") + (arg) + Lisp_Object arg; + { + Lisp_Object file; + struct wbevent *ev; + + check_intuition (); + + if (NULL (arg)) + { + amiga_consume_input(); + while (!wbevents) + { + int rfds = 1; + + select(1, &rfds, 0, 0, 0); + amiga_consume_input(); + } + } + /*** ??? Surely you don't mean to busy wait??? */ + + if (wbevents) { + file = build_string(wbevents->file); + ev = wbevents; + wbevents = wbevents->next; + free(ev); + return file; + } + return Qnil; + } + + DEFUN("amiga-set-foreground-color", Famiga_set_foreground_color, + Samiga_set_foreground_color, 1, 1, "nPen number: ", + "Use PEN as foreground color") + (pen) + { + int fg; + + check_intuition(); + CHECK_NUMBER(pen, 0); + + fg = XUINT (pen); + if (pen > 7) error("Pen colors must be between 0 & 7"); + foreground = fg; + reset_window(); + return Qnil; + } + + DEFUN("amiga-set-background-color", Famiga_set_background_color, + Samiga_set_background_color, 1, 1, "nPen number: ", + "Use PEN as background color") + (pen) + { + int bg; + + check_intuition(); + CHECK_NUMBER(pen, 0); + + bg = XUINT (pen); + if (pen > 7) error("Pen colors must be between 0 & 7"); + background = bg; + reset_window(); + return Qnil; + } + + DEFUN("amiga-set-inverse-fill-pen", Famiga_set_inverse_fill_pen, + Samiga_set_inverse_fill_pen, 1, 1, "nPen number: ", + "Use PEN's color for inverse fills (0-7 or 8 for reverse)") + (pen) + { + int ifp = 8; + + check_intuition(); + CHECK_NUMBER(pen, 0); + + ifp = XUINT (pen); + if (pen > 8) + error("choices are from 0 to 8"); + inverse_fill_pen = ifp; + reset_window(); + return Qnil; + } + + DEFUN("amiga-set-inverse-text-pen", Famiga_set_inverse_text_pen, + Samiga_set_inverse_text_pen, 1, 1, "nPen number: ", + "Use PEN's color for inverse fills (0-7 or 8 for reverse)") + (pen) + { + int itp = 8; + + check_intuition(); + CHECK_NUMBER(pen, 0); + + itp = XUINT (pen); + if (pen > 8) + error("choices are from 0 to 8"); + inverse_text_pen = itp; + reset_window(); + return Qnil; + } + + DEFUN("amiga-set-font", Famiga_set_font, Samiga_set_font, 2, 2, + "sFont: \n\ + nSize: ", + "Set font used for window to FONT with given HEIGHT.\n\ + The font used must be non-proportional.") + (wfont, height) + { + struct TextAttr attr; + struct TextFont *newfont; + char *fname; + struct Lisp_String *fstr; + WORD minw, minh, oldmw, oldmh; + + CHECK_STRING (wfont, 0); + CHECK_NUMBER (height, 0); + + check_intuition(); + + fstr = XSTRING (wfont); + fname = (char *)alloca (fstr->size + 6); + strcpy (fname, fstr->data); + strcat (fname, ".font"); + attr.ta_Name = fname; + attr.ta_YSize = XFASTINT (height); + attr.ta_Style = 0; + attr.ta_Flags = 0; + newfont = OpenDiskFont (&attr); + + if (!newfont) + error ("Font %s %d not found", fstr->data, XFASTINT (height)); + if (newfont->tf_Flags & FPF_PROPORTIONAL) + { + CloseFont(newfont); + error ("Font %s %d is proportional", fstr->data, XFASTINT (height)); + } + + if (emacs_win) + { + if (!set_min_size(emacs_win, newfont, &minw, &minh)) + { + CloseFont(newfont); + if (!set_min_size(emacs_win, font, &oldmw, &oldmh)) + _fail("Failed to restore old font, exiting."); + error("Window is too small for this font, need at least %d(w) by %d(h)", + minw, minh); + } + SetFont(emacs_win->RPort, newfont); + } + if (font_opened) CloseFont(font); + font_opened = TRUE; + font = newfont; + reset_window(); + return Qnil; + } + + DEFUN("amiga-set-geometry", Famiga_set_geometry, Samiga_set_geometry, 4, MANY, 0, + "Set Emacs window geometry and screen.\n\ + First 4 parameters are the (X,Y) position of the top-left corner of the window\n\ + and its WIDTH and HEIGHT. These must be big enough for an 11x4 characters window.\n\ + If nil is given for any of these, that means to keep the same value as before.\n\ + The optional argument SCREEN specifies which screen to use, nil stands for the\n\ + same screen as the window is on, t stands for the default public screen (normally\n\ + the Workbench), a string specifies a given public screen.\n\ + If optional argument BACKDROP is t, a backdrop window is used.") + (nargs, args) + int nargs; + Lisp_Object *args; + { + Lisp_Object x, y, w, h, scr = Qnil, backdrop = Qnil; + int opened; + WORD tempx, tempy, tempw, temph; + char *screen_name; + int use_backdrop; + + if (nargs > 6) error("Too many arguments to amiga-set-geometry"); + x = args[0]; y = args[1]; w = args[2]; h = args[3]; + if (nargs > 4) + { + scr = args[4]; + if (nargs > 5) backdrop = args[5]; + } + + check_intuition(); + + if (!NULL (x)) + { + CHECK_NUMBER(x, 0); + tempx = XUINT(x); + } + else tempx = EMACS_X(); + if (!NULL (y)) + { + CHECK_NUMBER(y, 0); + tempy = XUINT(y); + } + else tempy = EMACS_Y(); + if (!NULL (w)) + { + CHECK_NUMBER(w, 0); + tempw = XUINT(w); + } + else tempw = EMACS_W(); + if (!NULL (h)) + { + CHECK_NUMBER(h, 0); + temph = XUINT(h); + } + else temph = EMACS_H(); + + use_backdrop = !NULL(backdrop); + + if (scr == Qt) screen_name = 0; /* set to zero for def. */ + else if (!NULL (scr)) + { + CHECK_STRING (scr, 0); + screen_name = XSTRING (scr)->data; + } + else screen_name = emacs_screen_name; + + if (emacs_win) + { + struct Window *old_win = emacs_win; + struct IOStdReq *old_console = emacs_console; + + suspend_menus(); + opened = open_emacs_window(tempx, tempy, tempw, temph, use_backdrop, + screen_name); + if (opened != ok) + { + resume_menus(); + + if (opened == no_window) error("Failed to open desired window"); + else if (screen_name) + error("Unknown public screen %s", screen_name); + else error("The default screen wasn't found !?"); + } + + _device_close(old_console); + CloseWindow(old_win); + if (!resume_menus()) error("Failed to recover menus (No memory?)"); + } + else /* No window, set defaults */ + { + emacs_screen_name = screen_name; + if (screen_name) + { + emacs_screen_name_storage[MAXPUBSCREENNAME] = '\0'; + strncpy(emacs_screen_name_storage, screen_name, MAXPUBSCREENNAME); + } + emacs_x = tempx; + emacs_y = tempy; + emacs_w = tempw; + emacs_h = temph; + emacs_backdrop = use_backdrop; + } + return Qnil; + } + + + /* The next 2 functions are very usefull for writing + * arexx/lisp functions that interact with other programs + * that will be sharing the same screen. -ch3/19/93. */ + + DEFUN("amiga-get-window-geometry", + Famiga_get_window_geometry, Samiga_get_window_geometry, 0, 0, 0, + "Get Emacs window geometry.\n\ + a list returned is of the form: (iconified x y width height backdrop)\n\ + where x, y, width, height are integers, backdrop is t or nil and iconified\n\ + is t if the window is iconified and nil otherwise") + () + { + Lisp_Object x, y, w, h, b, i; + + XSET(x, Lisp_Int, EMACS_X()); + XSET(y, Lisp_Int, EMACS_Y()); + XSET(w, Lisp_Int, EMACS_W()); + XSET(h, Lisp_Int, EMACS_H()); + b = emacs_backdrop ? Qt : Qnil; + i = emacs_iconified ? Qt : Qnil; + + return Fcons(i, Fcons(x, Fcons(y, Fcons(w, Fcons(h, Fcons(b, Qnil)))))); + } + + DEFUN("amiga-get-screen-geometry", + Famiga_get_screen_geometry, Samiga_get_screen_geometry, 0, 0, 0, + "Get geometry of the screen emacs window resides on.\n\ + a list returned is of the form: (name x y width height)\n\ + where name is a string, x, y, width, height are integers.\n\ + Only the public screen name is returned if the window is not currently open.\n\ + In this last case, the name may be nil if the window will be opened on the\n\ + default public screen.") + () + { + Lisp_Object name; + + if (emacs_screen_name) name = Qnil; + else name = build_string(emacs_screen_name); + + if(emacs_win) + { + struct Screen *s = emacs_win->WScreen; + Lisp_Object x, y, w, h; + + XSET(x, Lisp_Int, s->LeftEdge); + XSET(y, Lisp_Int, s->TopEdge); + XSET(w, Lisp_Int, s->Width); + XSET(h, Lisp_Int, s->Height); + + return Fcons(name, Fcons(x, Fcons(y, Fcons(w, Fcons(h, Qnil))))); + } + return Fcons(name, Qnil); + } + + DEFUN("amiga-iconify", Famiga_iconify, Samiga_iconify, 0, 0, "", + "Toggle the emacs iconification state.") + () + { + check_intuition(); + + if (emacs_iconified) + { + /* Deiconify */ + + /* Reopen window */ + if (open_emacs_window(emacs_x, emacs_y, emacs_w, emacs_h, emacs_backdrop, + emacs_screen_name) != ok) + error("Failed to deiconify (No memory?)"); + resume_menus(); + + RemoveAppIcon(emacs_icon); + emacs_icon = 0; + emacs_iconified = 0; + } + else + if (emacs_icon = AddAppIconA(0, 0, "Emacs", wbport, 0, &emacs_icon_object, 0)) + { + if (emacs_win) + { + /* Close window */ + emacs_x = EMACS_X(); emacs_y = EMACS_Y(); + emacs_w = EMACS_W(); emacs_h = EMACS_H(); + suspend_menus(); + close_emacs_window(); + } + emacs_iconified = 1; + } + else error("Iconify attempt failed\n"); + + return Qnil; + } + + DEFUN("amiga-set-icon-pos", Famiga_set_icon_pos, Samiga_set_icon_pos, 2, 2, + "nX position: \n\ + nY position: ", + "Set the X Y position of the icon for emacs when iconified.") + (Lisp_Object x, Lisp_Object y) + { + long xpos, ypos; + + if (NULL (x)) emacs_icon_object.do_CurrentX = NO_ICON_POSITION; + else + { + CHECK_NUMBER (x, 0); + emacs_icon_object.do_CurrentX = XINT(x); + } + if (NULL (y)) emacs_icon_object.do_CurrentY = NO_ICON_POSITION; + else + { + CHECK_NUMBER (y, 0); + emacs_icon_object.do_CurrentY = XINT(y); + } + + return Qnil; + } + + struct EClockVal scount[16], ecount[16]; + long total[16], counting[16], nb[16], susp[16]; + + void start_count(int n) + { + nb[n]++; + if (counting[n]) printf("Restarted %d\n", n); + counting[n] = 1; + /*ReadEClock(&scount[n]);*/ + } + + void stop_count(int n) + { + if (counting[n]) + { + /*ReadEClock(&ecount[n]);*/ + counting[n] = 0; + + total[n] += ecount[n].ev_lo - scount[n].ev_lo; + } + } + + void suspend_count(int n) + { + if (counting[n] && susp[n]++ == 0) + { + /*ReadEClock(&ecount[n]);*/ + total[n] += ecount[n].ev_lo - scount[n].ev_lo; + } + } + + void resume_count(int n) + { + if (counting[n] && --susp[n] == 0) /*ReadEClock(&scount[n])*/; + } + + disp_counts(void) + { + int i; + + for (i = 0; i < 16; i++) + { + printf("%d(%d) ", total[i], nb[i]); + total[i] = nb[i] = 0; + } + printf("\n"); + } + + void screen_puts(char *str, unsigned int len) + { + if (emacs_win) + { + int i; + + emacs_console->io_Command = CMD_WRITE; + emacs_console->io_Data = (APTR)str; + emacs_console->io_Length = len; + + /* start_count(0); + for (i = 1; i <= 6; i++) suspend_count(i);*/ + DoIO(emacs_console); + /* for (i = 1; i <= 6; i++) resume_count(i); + stop_count(0);*/ + } + } + + DEFUN ("amiga-activate-window", Famiga_activate_window, Samiga_activate_window, 0, 0, 0, + "Makes emacs window the currently active one.") + () + { + if(emacs_win) { + ActivateWindow(emacs_win); + return Qnil; + } + error("No window to make active."); + return Qnil; + } + + DEFUN ("amiga-window-to-front", Famiga_window_to_front, Samiga_window_to_front, 0, 0, 0, + "Pulls the emacs window to the front (including screen)") + () + { + if(emacs_win) { + WindowToFront(emacs_win); + ScreenToFront(emacs_win->WScreen); + return Qnil; + } + error("No window to pull to the front."); + return Qnil; + } + + DEFUN ("amiga-window-to-back", Famiga_window_to_back, Samiga_window_to_back, 0, 0, 0, + "Pushes the emacs window to the back (including screen)") + () + { + if(emacs_win) { + WindowToBack(emacs_win); + ScreenToBack(emacs_win->WScreen); + return Qnil; + } + error("No window to push back."); + return Qnil; + } + + + void syms_of_amiga_screen(void) + { + DEFVAR_LISP ("amiga-mouse-item", &Vamiga_mouse_item, + "Encoded representation of last mouse click, corresponding to\n\ + numerical entries in amiga-mouse-map."); + Vamiga_mouse_item = Qnil; + DEFVAR_LISP ("amiga-mouse-pos", &Vamiga_mouse_pos, + "Current x-y position of mouse by row, column as specified by font."); + Vamiga_mouse_pos = Qnil; + + DEFVAR_BOOL ("amiga-remap-bsdel", &amiga_remap_bsdel, + "*If true, map DEL to Ctrl-D and Backspace to DEL. \n\ + This is the most convenient (and default) setting. If nil, don't remap."); + amiga_remap_bsdel = 1; + + DEFVAR_BOOL ("amiga-remap-numeric-keypad", &amiga_remap_numeric_keypad, + "*If true, numeric keypad keys are prefixed with C-x C-^ K.\n\ + This enables you to remap them, but causes problems with functions like\n\ + isearch-forward-regexp on some keyboards. Default to true."); + amiga_remap_numeric_keypad = 1; + + DEFVAR_BOOL ("amiga-mouse-initialized", &amiga_mouse_initialized, + "Set to true once lisp has been setup to process mouse commands.\n\ + No mouse processing request (C-X C-^ M) will be queued while this is nil."); + amiga_mouse_initialized = 0; + + DEFVAR_BOOL ("amiga-wb-initialized", &amiga_wb_initialized, + "Set to true once lisp has been setup to process workbench commands.\n\ + No workbench processing request (C-X C-^ W) will be queued while this is nil."); + amiga_mouse_initialized = 0; + + defsubr (&Samiga_mouse_events); + defsubr (&Samiga_proc_mouse_event); + defsubr (&Samiga_get_mouse_event); + defsubr (&Samiga_get_wb_event); + defsubr (&Samiga_set_font); + defsubr (&Samiga_set_geometry); + defsubr (&Samiga_set_background_color); + defsubr (&Samiga_set_foreground_color); + defsubr (&Samiga_iconify); + defsubr (&Samiga_set_icon_pos); + + /* New functions -ch3/19/93. */ + defsubr (&Samiga_set_inverse_text_pen); + defsubr (&Samiga_set_inverse_fill_pen); + defsubr (&Samiga_window_to_front); + defsubr (&Samiga_window_to_back); + defsubr (&Samiga_activate_window); + defsubr (&Samiga_get_window_geometry); + defsubr (&Samiga_get_screen_geometry); + + } + + void init_amiga_screen(void) + { + event_num = event_in = event_out = 0; + + if (!((IntuitionBase = (struct IntuitionBase *) + OpenLibrary("intuition.library", 37L)) && + (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L)) && + (DiskfontBase = OpenLibrary("diskfont.library", 0L)) && + (WorkbenchBase = OpenLibrary("workbench.library", 37)) && + (KeymapBase = OpenLibrary("keymap.library", 36)) && + (input_req = (struct IOStdReq *)_device_open("input.device", 0, 0, 0, 0, + sizeof(struct IOStdReq))))) + _fail("Need version 2.04 and diskfont.library!"); + + if (!(wbport = CreateMsgPort())) no_memory(); + + /* Add Ctrl-G detector */ + int_handler_hook.is_Data = 0; + int_handler_hook.is_Code = (void *)int_handler; + int_handler_hook.is_Node.ln_Pri = 100; /* 100 not 127 is the standard value + * for input stream handlers. -ch3/19/93. */ + /* it is standard for interrupts to have names -ch3/19/93.*/ + int_handler_hook.is_Node.ln_Name = "GNU Emacs CTRL-G handler"; + input_req->io_Command = IND_ADDHANDLER; + input_req->io_Data = (APTR)&int_handler_hook; + + /* wasn't checking for error. -ch3/19/93. */ + if(0 == DoIO(input_req)) + hooked = TRUE; + else + { + hooked = FALSE; + _fail("couldn't get input handler hook for CTRL-G"); + } + + inputsig |= 1L << wbport->mp_SigBit; + + background_hook.h_Entry = (ULONG (*)()) fill_background; /* added cast. */ + font = GfxBase->DefaultFont; + + init_amiga_menu(); + } + + void cleanup_amiga_screen(void) + { + if (hooked) + { + input_req->io_Command = IND_REMHANDLER; + input_req->io_Data = (APTR)&int_handler_hook; + DoIO(input_req); + } + close_app_win(); + if (wbport) DeleteMsgPort(wbport); + cleanup_amiga_menu(); + _device_close(emacs_console); + if (emacs_win) CloseWindow(emacs_win); + if (font_opened) CloseFont(font); + if (IntuitionBase) CloseLibrary(IntuitionBase); + if (GfxBase) CloseLibrary(GfxBase); + if (DiskfontBase) CloseLibrary(DiskfontBase); + if (WorkbenchBase) CloseLibrary(WorkbenchBase); + if (KeymapBase) CloseLibrary(KeymapBase); + _device_close(input_req); + } diff -rcP emacs-18.59-fsf/src/amiga_serial.c emacs-18.59-amiga/src/amiga_serial.c *** emacs-18.59-fsf/src/amiga_serial.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_serial.c Sat Jun 5 11:37:38 1993 *************** *** 0 **** --- 1,72 ---- + #include + #include + #include + #include + + #include + #include + + #include "amiga.h" + + static struct MsgPort *SerReadPort; + static struct IOExtSer *SerReadRequest, *SerWriteRequest; + static char ser_inbuf[2]; + char *far serial_device = "serial.device"; + long far serial_unit; + + void init_amiga_serial(void) + { + if ((SerWriteRequest = (struct IOExtSer *) + _device_open(serial_device, serial_unit, 0L, + 0L, 0, sizeof(struct IOExtSer))) && + (SerReadPort = CreateMsgPort()) && + (SerReadRequest = (struct IOExtSer *)CreateIORequest(SerReadPort, sizeof (struct IOExtSer)))) + { + SerReadRequest->IOSer.io_Device = SerWriteRequest->IOSer.io_Device; + SerReadRequest->IOSer.io_Unit = SerWriteRequest->IOSer.io_Unit; + ser_inbuf[1]=0; + SerReadRequest->IOSer.io_Command = CMD_READ; + SerWriteRequest->IOSer.io_Command = CMD_WRITE; + SerReadRequest->IOSer.io_Length = 1; + SerReadRequest->IOSer.io_Data = &ser_inbuf[0]; + SendIO(SerReadRequest); + + inputsig |= 1L << SerReadPort->mp_SigBit; + } + else _fail("No memory or serial.device missing"); + } + + void cleanup_amiga_serial(void) + { + if (SerReadRequest) + { + AbortIO(SerReadRequest); + WaitIO(SerReadRequest); + DeleteIORequest(SerReadRequest); + } + if (SerReadPort) DeletePort(SerReadPort); + _device_close(SerWriteRequest); + } + + void check_serial(int force) + { + while (CheckIO(SerReadRequest)) + { + int c = ser_inbuf[0]; + SendIO(SerReadRequest); + enque(c, FALSE); + } + } + + void serial_puts(char *str, int len) + { + + SerWriteRequest->IOSer.io_Length = len; + SerWriteRequest->IOSer.io_Data = str; + DoIO(SerWriteRequest); + } + + unsigned long serial_baud_rate(void) + { + return SerWriteRequest->io_Baud; + } diff -rcP emacs-18.59-fsf/src/amiga_sysdep.c emacs-18.59-amiga/src/amiga_sysdep.c *** emacs-18.59-fsf/src/amiga_sysdep.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_sysdep.c Sat Jun 5 11:39:12 1993 *************** *** 0 **** --- 1,375 ---- + /* Interfaces to system-dependent kernel and library entries. + Copyright (C) 1985, 1986, 1987, 1988 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Emacs General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + GNU Emacs, but only under the conditions described in the + GNU Emacs General Public License. A copy of this license is + supposed to have been given to you along with GNU Emacs so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. */ + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #undef LONGBITS + #undef NULL + #include "config.h" + #include "lisp.h" + #include "emacssignal.h" + + #define min(x,y) ((x) > (y) ? (y) : (x)) + + #include "termhooks.h" + #include "termchar.h" + #include "termopts.h" + #include "dispextern.h" + #include "amiga.h" + + #define EMACS_TOOL_SIZE 128 /* Room for path to emacs executable */ + + struct Library *IconBase; + extern struct ExecBase *SysBase; + + /*long __stack = 40000;*/ /* Minimum stack size, used by c.o */ + int amiga_process_stack_size; + + int amiga_initialized; + int amiga_create_icons; /* If true, we create icons when saving files */ + enum exit_method amiga_fail_exit = use_xcexit; + int selecting; + + /* Emacs sysdep routines */ + /* --------------------- */ + + set_exclusive_use(int fd) {} + + /* Suspend the Emacs process; give terminal to its superior. */ + sys_suspend() + { + /* This could have been iconify, but: + a) Not good for serial lines. + b) emacs stays active while iconified */ + } + + char *get_system_name() + { + static char sysname[32]; + + gethostname(sysname, sizeof sysname); + return sysname; + } + + /* + * flush any pending output + * (may flush input as well; it does not matter the way we use it) + */ + + flush_pending_output (channel) + int channel; + { + } + + wait_for_termination (pid) + int pid; + { + while (1) + { + sigsetmask (sigmask (SIGCHLD)); + if (0 > kill (pid, 0)) + { + sigsetmask (SIGEMPTYMASK); + break; + } + sigpause (SIGEMPTYMASK); + } + } + + /* A few general amiga support routines */ + /* ------------------------------------ */ + + char *expand_path(char *path, char *buf, int len) + { + BPTR dirlock; + APTR window; + + window = _us->pr_WindowPtr; + _us->pr_WindowPtr = (APTR)-1; + dirlock = Lock(path, ACCESS_READ); + _us->pr_WindowPtr = window; + if (dirlock) /* Expand lock name */ + { + if (!NameFromLock(dirlock, buf, len)) buf = 0; + UnLock(dirlock); + return buf; + } + return 0; + } + + #undef select + int emacs_select(int nfds, int *rfds, int *wfds, int *efds, struct timeval *timeout) + { + int ret; + + selecting = TRUE; + ret = select(nfds, rfds, wfds, efds, timeout); + selecting = FALSE; + return ret; + } + + void no_memory(void) + { + _fail("No memory"); + } + + char *amiga_path(void) + { + char *path, *pp, name[128]; + int pathsize; + struct CommandLineInterface *cli; + BPTR lock; + long l, *lp, nlen; + + pathsize = 128; + path = (char *)xmalloc(pathsize); + + strcpy(path, "."); + pp = path + 1; + + if (!(cli = (struct CommandLineInterface *)((long)_us->pr_CLI << 2))) + return path; + + l = (long)cli->cli_CommandDir; + while (l) { + *pp++ = ','; + l <<= 2; + lp = (long *)l; + lock = (BPTR)*(lp + 1); + NameFromLock(lock, name, 128); + nlen = strlen(name); + if (pp + nlen + 5 >= path + pathsize) + { + char *newpath; + + pathsize = 2 * pathsize + nlen; + newpath = (char *)xrealloc(path, pathsize); + pp = newpath + (pp - path); + path = newpath; + } + memcpy(pp, name, nlen); + pp += nlen; + l = *lp; + } + /* Use of +5 above guarantees that there is enough space for c: */ + strcpy(pp, ",c:"); + + return path; + } + + /* Some general amiga commands */ + /* --------------------------- */ + + #define emacs_file_icon_width 54 + #define emacs_file_icon_height 22 + #define emacs_file_icon_num_planes 2 + + static UWORD chip emacs_file_icon_data[2][22][4] = { + { + 0x0000,0x0000,0x0000,0x0400,0x0000,0x0000,0x0000,0x0c00, + 0x0000,0x0000,0x0000,0x0c00,0x07ff,0xffff,0xffe0,0x0c00, + 0x0400,0x0000,0x0030,0x0c00,0x0400,0x0000,0x0028,0x0c00, + 0x04ff,0xffff,0xfe24,0x0c00,0x0400,0x0000,0x0022,0x0c00, + 0x04ff,0xffff,0xfe3f,0x0c00,0x0400,0x0000,0x0000,0x8c00, + 0x04ff,0xffc0,0x0000,0x8c00,0x0400,0x0000,0x0000,0x8c00, + 0x0400,0x0000,0x0000,0x8c00,0x0400,0x0000,0x0000,0x8c00, + 0x04ff,0xffff,0xfe00,0x8c00,0x0400,0x0000,0x0000,0x8c00, + 0x04ff,0xffff,0xfe00,0x8c00,0x0400,0x0000,0x0000,0x8c00, + 0x07ff,0xffff,0xffff,0x8c00,0x0000,0x0000,0x0000,0x0c00, + 0x0000,0x0000,0x0000,0x0c00,0x7fff,0xffff,0xffff,0xfc00 + }, + { + 0xffff,0xffff,0xffff,0xf800,0x8000,0x0000,0x0000,0x0000, + 0x8000,0x0000,0x0000,0x0000,0x8000,0x0000,0x0000,0x0000, + 0x83ff,0xffff,0xffc0,0x0000,0x83ff,0xffff,0xffd0,0x0000, + 0x8300,0x0000,0x01d8,0x0000,0x83ff,0xffff,0xffdc,0x0000, + 0x8300,0x0000,0x01c0,0x0000,0x83ff,0xffff,0xffff,0x0000, + 0x8300,0x003f,0xffff,0x0000,0x83ff,0xffff,0xffff,0x0000, + 0x83ff,0xffff,0xffff,0x0000,0x83ff,0xffff,0xffff,0x0000, + 0x8300,0x0000,0x01ff,0x0000,0x83ff,0xffff,0xffff,0x0000, + 0x8300,0x0000,0x01ff,0x0000,0x83ff,0xffff,0xffff,0x0000, + 0x8000,0x0000,0x0000,0x0000,0x8000,0x0000,0x0000,0x0000, + 0x8000,0x0000,0x0000,0x0000,0x8000,0x0000,0x0000,0x0000 + }, + }; + struct Image far emacs_file_icon_image = { + 0, 0, + emacs_file_icon_width, emacs_file_icon_height, emacs_file_icon_num_planes, + (UWORD *)emacs_file_icon_data, + 3, 0, + 0 + }; + + static char *far emacs_file_tooltypes[] = { + "FILETYPE=TEXT", + 0 + }; + + static char far emacs_tool[EMACS_TOOL_SIZE]; + + static struct DiskObject far emacs_file_icon_object = { + WB_DISKMAGIC, WB_DISKVERSION, + { 0, 0, 0, emacs_file_icon_width, emacs_file_icon_height, + GFLG_GADGIMAGE | GADGBACKFILL, GACT_IMMEDIATE | GACT_RELVERIFY, GTYP_BOOLGADGET, + (APTR)&emacs_file_icon_image }, + WBPROJECT, emacs_tool, emacs_file_tooltypes, + NO_ICON_POSITION, NO_ICON_POSITION, + 0, 0, + 40000 /* Stack size for emacs */ + }; + + DEFUN ("amiga-put-icon", Famiga_put_icon, Samiga_put_icon, 2, 2, 0, + "Create an icon for FILE.\n\ + If FORCE is non-nil create it unconditionally, otherwise only if one doesn't exist.\n\ + Returns t if an icon was created, nil otherwise.") + (file, force) + Lisp_Object file, force; + { + char *fname; + struct DiskObject *obj; + + CHECK_STRING(file, 0); + fname = XSTRING(file)->data; + + if (NULL (force) && (obj = GetDiskObject(fname))) + { + /* Icon exists, don't overwrite */ + FreeDiskObject(obj); + return Qnil; + } + emacs_file_icon_object.do_StackSize = _stack_size; + if (PutDiskObject(fname, &emacs_file_icon_object)) return Qt; + error("Icon for %s couldn't be created", fname); + } + + /* Amiga initialisation routines */ + /* ----------------------------- */ + + syms_of_amiga () + { + DEFVAR_BOOL("amiga-initialized", &amiga_initialized, ""); + DEFVAR_INT("amiga-malloc-bytes-used", &malloc_bytes_used, + "Number of malloc bytes used when emacs was dumped"); + DEFVAR_BOOL("amiga-create-icons", &amiga_create_icons, + "If non-nil, create icons when saving files."); + defsubr(&Samiga_put_icon); + amiga_process_stack_size = 0; + DEFVAR_INT("amiga-process-stack-size", &amiga_process_stack_size, + "Size of stack for called processes. 0 means same size as emacs stack."); + syms_of_amiga_tty(); + syms_of_amiga_menu(); + syms_of_amiga_clipboard(); + } + + static void amiga_early_init(int *_argc, char ***_argv) + { + int argc = *_argc; + char **argv = *_argv; + + if (argc > 2 && !strcmp(argv[1], "-pure")) + { + puresize = atoi(argv[2]); + argc -= 2; argv += 2; + } + if (argc > 2 && !strcmp(argv[1], "-malloc")) + { + malloc_hunk_size = atoi(argv[2]); + argc -= 2; argv += 2; + } + if (argc > 2 && !strcmp(argv[1], "-prealloc")) + { + pre_alloc = atoi(argv[2]); + argc -= 2; argv += 2; + } + /* Handle the -dev switch, which specifies device & unit to use as terminal */ + if (argc > 3 && !strcmp (argv[1], "-dev")) + { + extern char *far serial_device; + extern long far serial_unit; + + serial_device = argv[2]; + serial_unit = atoi(argv[3]); + fprintf (stderr, "Using %s (unit %d)\n", serial_device ,serial_unit); + argc -= 3; argv += 3; + } + /* Patch real argc, argv to hide arguments we used */ + argv[0] = (*_argv)[0]; + *_argv = argv; + *_argc = argc; + + expand_path(argv[0], emacs_tool, EMACS_TOOL_SIZE); + } + + void cleanup_amiga(void) + { + cleanup_clipboard(); + cleanup_amiga_tty(); + if (IconBase) CloseLibrary(IconBase); + } + + void amiga_undump_reinit(void) + /* Post-undump initialisation */ + { + extern struct WBStartup *_WBenchMsg; + + emacs_malloc_init(); + early_amiga_tty(); + early_clipboard(); + + if (!onexit(cleanup_amiga)) _fail("Internal problem with onexit"); + + make_environ(); + IconBase = OpenLibrary("icon.library", 0); + if (!IconBase) _fail("Need icon.library"); + amiga_create_icons = _WBenchMsg != 0; + + init_amiga_tty(); init_clipboard(); + } + + #undef main + main(int argc, char **argv) + /* Effect: Call emacs_main after doing some early amiga initialisation for emacs. + */ + { + /* This initialisation may steal some command line options */ + amiga_early_init(&argc, &argv); + emacs_main(argc, argv); + } diff -rcP emacs-18.59-fsf/src/amiga_term.c emacs-18.59-amiga/src/amiga_term.c *** emacs-18.59-fsf/src/amiga_term.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_term.c Tue Mar 23 09:45:12 1993 *************** *** 0 **** --- 1,388 ---- + /* Amiga terminal control routines. + Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNU Emacs; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + + #include + #include + #include "config.h" + #include "termhooks.h" + #include "termchar.h" + #include "termopts.h" + + /* internal state */ + + /* nonzero means supposed to write text in standout mode. */ + static int standout_requested; + + static int standout_mode; /* Nonzero when in standout mode. */ + + static char tens[100] = { + '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', + '1', '1', '1', '1', '1', '1', '1', '1', '1', '1', + '2', '2', '2', '2', '2', '2', '2', '2', '2', '2', + '3', '3', '3', '3', '3', '3', '3', '3', '3', '3', + '4', '4', '4', '4', '4', '4', '4', '4', '4', '4', + '5', '5', '5', '5', '5', '5', '5', '5', '5', '5', + '6', '6', '6', '6', '6', '6', '6', '6', '6', '6', + '7', '7', '7', '7', '7', '7', '7', '7', '7', '7', + '8', '8', '8', '8', '8', '8', '8', '8', '8', '8', + '9', '9', '9', '9', '9', '9', '9', '9', '9', '9', + }; + + static char ones[100] = { + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + }; + + #define addnum(str, num) if (num < 100) \ + { *--str = ones[num]; *--str = tens[num]; } \ + else do { *--str = '0' + num % 10; num /= 10; } while (num != 0) + + static background_highlight (); + static turn_off_highlight (); + + + /* Cursor motion stuff (from cm.c) */ + static int curX, curY; + + /* Move to absolute position, specified origin 0 */ + + Amove_cursor (row, col) + { + char buf[32], *pos = buf + 32; + + if (curY == row && curX == col) + return; + + curX = col; curY = row; + *--pos = 'H'; + col = col + 1; row = row + 1; + addnum(pos, col); + *--pos = ';'; + addnum(pos, row); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + if (pos < buf) abort(); + } + + + Aring_bell () + { + emacs_output("\07", 1); + } + + Aset_terminal_modes () + { + } + + Areset_terminal_modes () + { + turn_off_highlight (); + } + + Aupdate_begin () + { + /* Hide cursor */ + emacs_output("\x9b\x30\x20\x70", 4); + } + + Aupdate_end () + { + background_highlight (); + standout_requested = 0; + emacs_output("\x9b\x20\x70", 3); /* Show cursor */ + } + + + /* Handle highlighting when TN_standout_width (termcap sg) is not specified. + In these terminals, output is affected by the value of standout + mode when the output is written. + + These functions are called on all terminals, but do nothing + on terminals whose standout mode does not work that way. */ + + static turn_off_highlight () + { + if (standout_mode) + { + extern int background, foreground; + extern int inverse_fill_pen, inverse_text_pen; + int b = background + 40, f = foreground + 30; + if(inverse_fill_pen < 8 && inverse_text_pen < 8) + { + char buf[32], *pos = buf + 32; + /* UnDo inverse fill */ + *--pos = '\0'; + *--pos = 'm'; + addnum(pos, b); + *--pos = ';'; + /* UnDo inverse text */ + addnum(pos, f); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + } + else + { + emacs_output("\x9b""27m", 4); + } + } + standout_mode = 0; + } + + static turn_on_highlight () + { + if (!standout_mode) + { + extern int inverse_fill_pen, inverse_text_pen; + int b = inverse_fill_pen + 40, f = inverse_text_pen + 30; + if(inverse_fill_pen < 8 && inverse_text_pen < 8) + { + char buf[32], *pos = buf + 32; + /* Do inverse fill */ + *--pos = '\0'; + *--pos = 'm'; + addnum(pos, b); + *--pos = ';'; + + /* Do inverse text */ + addnum(pos, f); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + } + else + { + emacs_output("\x9b\x37m", 3); + } + } + standout_mode = 1; + } + + /* Set standout mode to the state it should be in for + empty space inside windows. What this is, + depends on the user option inverse-video. */ + + static background_highlight () + { + if (inverse_video) + turn_on_highlight (); + else + turn_off_highlight (); + } + + /* Set standout mode to the mode specified for the text to be output. */ + + static + highlight_if_desired () + { + if (!inverse_video == !standout_requested) + turn_off_highlight (); + else + turn_on_highlight (); + } + + /* External interface to control of standout mode. + Call this when about to modify line at position VPOS + and not change whether it is highlighted. */ + + Areassert_line_highlight (highlight, vpos) + int highlight; + int vpos; + { + standout_requested = highlight; + } + + /* Call this when about to modify line at position VPOS + and change whether it is highlighted. */ + + Achange_line_highlight (new_highlight, vpos, first_unused_hpos) + int new_highlight, vpos, first_unused_hpos; + { + standout_requested = new_highlight; + + move_cursor (vpos, 0); + + background_highlight (); + clear_end_of_line (first_unused_hpos); + reassert_line_highlight (new_highlight, curY); + } + + /* Erase operations */ + + /* clear from cursor to end of screen */ + Aclear_to_end () + { + background_highlight (); + emacs_output("\x9bJ", 2); + } + + /* Clear entire screen */ + + Aclear_screen () + { + background_highlight (); + emacs_output("\f", 1); + curX = curY = 0; + } + + /* Clear to end of line, but do not clear any standout marker. + Assumes that the cursor is positioned at a character of real text, + which implies it cannot be before a standout marker + unless the marker has zero width. + + Note that the cursor may be moved. */ + + Aclear_end_of_line (first_unused_hpos) + int first_unused_hpos; + { + if (curX >= first_unused_hpos) + return; + + background_highlight (); + emacs_output("\x9bK", 2); + } + + Aoutput_chars (string, len) + register char *string; + int len; + { + highlight_if_desired (); + + curX += len; + emacs_output(string, len); + } + + /* If start is zero, insert blanks instead of a string at start */ + + Ainsert_chars (start, len) + register char *start; + int len; + { + char buf[32], *pos = buf + 32; + + highlight_if_desired (); + + *--pos = '@'; + addnum(pos, len); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + if (pos < buf) abort(); + if (start) emacs_output(start, len); + } + + Adelete_chars (n) + register int n; + { + char buf[32], *pos = buf + 32; + + *--pos = 'P'; + addnum(pos, n); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + if (pos < buf) abort(); + } + + /* Insert N lines at vpos VPOS. If N is negative, delete -N lines. */ + + Ains_del_lines (vpos, n) + int vpos, n; + { + register int i = n > 0 ? n : -n; + char buf[32], *pos = buf + 32; + + if (n > 0) + { + i = n; + *--pos = 'L'; + } + else + { + i = -n; + *--pos = 'M'; + } + if (vpos + i >= screen_height) return; + + move_cursor (vpos, 0); + background_highlight (); + addnum(pos, i); + *--pos = 0x9b; + emacs_output(pos, buf + 32 - pos); + if (pos < buf) abort(); + } + + Acalculate_costs (extra, costvec, ncostvec) + int extra; + int *costvec, *ncostvec; + { + CalcLID(2, 40, extra, 0, costvec, ncostvec); + } + + Aset_terminal_window (size) + int size; + { + } + + + amiga_term_init () + { + must_write_spaces = FALSE; + min_padding_speed = 0; + memory_below_screen = FALSE; + meta_key = TRUE; + scroll_region_ok = FALSE; + line_ins_del_ok = FALSE; /* much cleaner display when FALSE -ch3/19/93. */ + char_ins_del_ok = FALSE; + fast_clear_end_of_line = TRUE; + no_redraw_on_reenter = FALSE; + + clear_screen_hook = Aclear_screen; + clear_end_of_line_hook = Aclear_end_of_line; + clear_to_end_hook = Aclear_to_end; + ins_del_lines_hook = Ains_del_lines; + change_line_highlight_hook = Achange_line_highlight; + insert_chars_hook = Ainsert_chars; + output_chars_hook = Aoutput_chars; + delete_chars_hook = Adelete_chars; + ring_bell_hook = Aring_bell; + reset_terminal_modes_hook = Areset_terminal_modes; + set_terminal_modes_hook = Aset_terminal_modes; + update_begin_hook = Aupdate_begin; + update_end_hook = Aupdate_end; + set_terminal_window_hook = Aset_terminal_window; + move_cursor_hook = Amove_cursor; + reassert_line_highlight_hook = Areassert_line_highlight; + + dont_calculate_costs = 1; + calculate_costs_hook = Acalculate_costs; + + /* Get screen size from system, or else from somewhere ... */ + get_screen_size (&screen_width, &screen_height); + /* Random defaults to avoid any problems */ + if (screen_width <= 0) screen_width = 80; + if (screen_height <= 0) screen_height = 23; + + init_baud_rate (); + } diff -rcP emacs-18.59-fsf/src/amiga_tty.c emacs-18.59-amiga/src/amiga_tty.c *** emacs-18.59-fsf/src/amiga_tty.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/amiga_tty.c Sat Jun 5 13:20:50 1993 *************** *** 0 **** --- 1,305 ---- + #include "config.h" + #undef NULL + #include "lisp.h" + #include "termchar.h" + + #include + #include + #include + #include + + #undef LONGBITS + + #include + #include + #include + + #include "amiga.h" + #include "termhooks.h" + + static int term_initialised; + ULONG inputsig; + + /* A few tty system dependent routines unused on the Amiga */ + + setpgrp_of_tty(int pid) {} + init_sigio() {} + reset_sigio() {} + request_sigio() {} + unrequest_sigio() {} + + /* Return nonzero if safe to use tabs in output. + At the time this is called, init_sys_modes has not been done yet. */ + + tabs_safe_p() + { + if (noninteractive) + return 1; + + return 0; /* Not safe on Amiga !? */ + } + + /* Get terminal size from system. + Store number of lines into *heightp and width into *widthp. + If zero or a negative number is stored, the value is not valid. */ + + get_screen_size (widthp, heightp) + int *widthp, *heightp; + { + if (term_initialised && !inhibit_window_system) + get_window_size(widthp, heightp); + else /* We don't known what size the terminal is */ + { + *widthp = 0; + *heightp = 0; + } + } + + init_baud_rate () + { + if (noninteractive || !term_initialised) baud_rate = 1200; + else if (!inhibit_window_system) baud_rate = 38400; + else baud_rate = serial_baud_rate(); + } + + void check_intuition () + { + if (noninteractive || inhibit_window_system) + error ("You aren't using a window."); + } + + #define TTYBUFSIZE 256 /* Same size as kbd_buffer */ + static char ttybuf[TTYBUFSIZE]; + static int tty_count; + #define TTYPUT(c) { if (tty_count < TTYBUFSIZE) ttybuf[tty_count++] = c; } + + static int interrupt_char; + + void enque(unsigned int c, int meta) + /* place input keys in keyboard buffer + If high bit is set, precede character with ^Q (hack). + If meta is true, set high bit. + If both the high bit & meta are true, we have a problem. Ignore it. + If c == AMIGASEQ (256) enqueue the amiga sequence introducer (C-x C-^) + */ + { + /* Hack CSI to be AMIGASEQ (to allow defining function keys, etc) */ + if (c == 0233 || c == AMIGASEQ) + { + TTYPUT('x' & 037); + TTYPUT('^' & 037); + } + else if (c >= 0200) /* Special character, precede with ^Q */ + { + TTYPUT('q' & 037); + TTYPUT(c); + } + else + { + if (meta) c |= 0200; + if (c == interrupt_char) Signal(_us, SIGBREAKF_CTRL_C); + else TTYPUT(c); + } + } + + int get_ttycount(void) + { + return tty_count; + } + + init_sys_modes () + { + extern int quit_char; + + if (noninteractive) + return; + + if (inhibit_window_system) clear_screen(); + + interrupt_char = quit_char; + if (!inhibit_window_system) setup_intchar(interrupt_char); + } + + reset_sys_modes () + { + if (noninteractive) + { + fflush (stdout); + return; + } + move_cursor (screen_height - 1, 0); + clear_end_of_line (screen_width); + /* clear_end_of_line may move the cursor */ + move_cursor (screen_height - 1, 0); + } + + void amiga_consume_input(void) + { + extern int this_command_key_count; + int force = this_command_key_count == 0; + /* If force is TRUE & some non-keyboard (eg mouse events) input is pending, + insert the appropriate magic sequence in the input stream */ + + if (term_initialised) + { + if (!inhibit_window_system) check_window(force); + else check_serial(force); + check_arexx(force, TRUE); + } + } + + discard_tty_input () + { + if (noninteractive) + return; + + amiga_consume_input(); + tty_count = 0; + chkabort(); + } + + /* Code for the fd describing the emacs input (terminal or window) */ + + static ULONG __regargs ttyin_select_start(void *userinfo, int rd, int wr) + { + if (!inhibit_window_system) force_window(); + + return tty_count ? -1 : inputsig; + } + + static void __regargs ttyin_select_poll(void *userinfo, int *rd, int *wr) + { + amiga_consume_input(); + if (!tty_count) *rd = 0; + } + + static int __regargs ttyin_read(void *userinfo, void *buffer, unsigned int length) + { + amiga_consume_input(); + if (length > tty_count) length = tty_count; + memcpy(buffer, ttybuf, length); + tty_count -= length; + if (tty_count) memmove(ttybuf, ttybuf + length, tty_count - length); + + return (int)length; + } + + static int __regargs ttyin_write(void *userinfo, void *buffer, unsigned int length) + { + errno = EACCES; + return -1; + } + + static int __regargs ttyin_lseek(void *userinfo, long rpos, int mode) + { + errno = ESPIPE; + return -1; + } + + static int __regargs ttyin_close(void *userinfo, int internal) + { + return 0; + } + + static int __regargs ttyin_ioctl(void *userinfo, int request, void *data) + { + errno = EINVAL; + return -1; + } + + #define CBUFSIZE 1024 + #undef fwrite + #undef fflush + + char cbuffer[CBUFSIZE + 16], *cbuffer_pos; + + int emacs_fflush(FILE *f) + { + if (noninteractive || f != stdout) return fflush(f); + else + { + int len; + + len = cbuffer_pos - cbuffer; + if (term_initialised) + if (!inhibit_window_system) screen_puts(cbuffer, len); + else serial_puts(cbuffer, len); + if (termscript) fwrite (cbuffer, 1, len, termscript); + cbuffer_pos = cbuffer; + + return 0; + } + } + + void emacs_putchar(int c) + { + if (cbuffer_pos >= cbuffer + CBUFSIZE) emacs_fflush(stdout); + *cbuffer_pos++ = c; + } + + void emacs_output(char *str, int size) + { + if (cbuffer_pos + size > cbuffer + CBUFSIZE) emacs_fflush(stdout); + if (size > CBUFSIZE) + { + if (term_initialised) + if (!inhibit_window_system) screen_puts(str, size); + else serial_puts(str, size); + } + else + { + memcpy(cbuffer_pos, str, size); + cbuffer_pos += size; + } + } + + void emacs_fwrite(char *str, unsigned int nblocks, unsigned int len, FILE *f) + { + if (noninteractive || f != stdout) fwrite (str, nblocks, len, f); + else + { + unsigned int size; + + if (nblocks == 1) size = len; /* Emacs always uses 1 "block" */ + else size = nblocks * len; + + emacs_output(str, size); + } + } + + void syms_of_amiga_tty(void) + { + syms_of_amiga_screen(); + syms_of_amiga_rexx(); + } + + void init_amiga_tty() + { + inputsig = 0; + term_initialised = FALSE; + init_amiga_rexx(); + } + + void cleanup_amiga_tty() + { + cleanup_amiga_rexx(); + cleanup_amiga_serial(); + cleanup_amiga_screen(); + } + + void early_amiga_tty() + { + cbuffer_pos = cbuffer; + tty_count = 0; + } + + void amiga_term_open(void) + { + inhibit_window_system ? init_amiga_serial() : init_amiga_screen(); + close(0); + if (_alloc_fd((void *)1, FI_READ, ttyin_select_start, ttyin_select_poll, ttyin_read, + ttyin_write, ttyin_lseek, ttyin_close, ttyin_ioctl) == 0) + term_initialised = TRUE; + else _fail("Failed to initialise I/O, no memory ?"); + } + diff -rcP emacs-18.59-fsf/src/buffer.c emacs-18.59-amiga/src/buffer.c *** emacs-18.59-fsf/src/buffer.c Wed May 13 19:39:33 1992 --- emacs-18.59-amiga/src/buffer.c Sun Nov 22 10:13:24 1992 *************** *** 1137,1143 **** #ifndef VMS /* Maybe this should really use some standard subroutine whose definition is filename syntax dependent. */ ! if (buf[strlen (buf) - 1] != '/') strcat (buf, "/"); #endif /* not VMS */ current_buffer->directory = build_string (buf); --- 1137,1147 ---- #ifndef VMS /* Maybe this should really use some standard subroutine whose definition is filename syntax dependent. */ ! if (buf[strlen (buf) - 1] != '/' ! #ifdef AMIGA ! && buf[strlen (buf) -1] != ':' ! #endif /*AMIGA */ ! ) strcat (buf, "/"); #endif /* not VMS */ current_buffer->directory = build_string (buf); diff -rcP emacs-18.59-fsf/src/callproc.c emacs-18.59-amiga/src/callproc.c *** emacs-18.59-fsf/src/callproc.c Sun Jul 12 03:26:01 1992 --- emacs-18.59-amiga/src/callproc.c Sun Nov 22 10:13:32 1992 *************** *** 124,134 **** CHECK_STRING (args[0], 0); if (nargs <= 1 || NULL (args[1])) ! #ifdef VMS ! args[1] = build_string ("NLA0:"); ! #else ! args[1] = build_string ("/dev/null"); ! #endif /* not VMS */ else args[1] = Fexpand_file_name (args[1], current_buffer->directory); --- 124,130 ---- CHECK_STRING (args[0], 0); if (nargs <= 1 || NULL (args[1])) ! args[1] = build_string (PATH_NULL); else args[1] = Fexpand_file_name (args[1], current_buffer->directory); *************** *** 177,186 **** if (XTYPE (buffer) == Lisp_Int) #ifdef VMS ! fd[1] = open ("NLA0:", 0), fd[0] = -1; #else ! fd[1] = open ("/dev/null", O_WRONLY), fd[0] = -1; ! #endif /* not VMS */ else { pipe (fd); --- 173,181 ---- if (XTYPE (buffer) == Lisp_Int) #ifdef VMS ! fd[1] = open (PATH_NULL, 0), fd[0] = -1; #else ! fd[1] = open (PATH_NULL, O_WRONLY), fd[0] = -1; else { pipe (fd); *************** *** 193,198 **** --- 188,209 ---- synch_process_death = 0; synch_process_retcode = 0; + #ifdef AMIGA + { + register unsigned char *temp; + + if (XTYPE (current_buffer->directory) == Lisp_String) + { + register int i; + + i = XSTRING (current_buffer->directory)->size; + temp = (unsigned char *) alloca (i + 1); + bcopy (XSTRING (current_buffer->directory)->data, temp, i); + temp[i] = 0; + } + pid = exec(new_argv[0], new_argv, filefd, fd[1], temp, amiga_process_stack_size); + } + #else { /* child_setup must clobber environ in systems with true vfork. Protect it from permanent change. */ *************** *** 230,235 **** --- 241,247 ---- close (filefd); close (fd1); } + #endif /* not AMIGA */ if (pid < 0) { *************** *** 302,308 **** register Lisp_Object filename_string, start, end, status; char tempfile[20]; ! strcpy (tempfile, "/tmp/emacsXXXXXX"); mktemp (tempfile); filename_string = build_string (tempfile); --- 314,320 ---- register Lisp_Object filename_string, start, end, status; char tempfile[20]; ! strcpy (tempfile, PATH_TEMP); mktemp (tempfile); filename_string = build_string (tempfile); *************** *** 318,323 **** --- 330,336 ---- unlink (tempfile); return status; } + #ifndef AMIGA /* This is the last thing run in a newly forked inferior either synchronous or asynchronous. *************** *** 425,430 **** --- 438,444 ---- write (1, new_argv[0], strlen (new_argv[0])); _exit (1); } + #endif /* not AMIGA */ init_callproc () { *************** *** 437,442 **** --- 451,465 ---- Vexec_path = decode_env_path (0, PATH_EXEC); Vexec_directory = Ffile_name_as_directory (Fcar (Vexec_path)); Vexec_path = nconc2 (decode_env_path ("PATH", ""), Vexec_path); + #ifdef AMIGA + { + char *amiga_path(), *apath = amiga_path(); + + Vexec_path = nconc2 (decode_env_path (0, apath), Vexec_path); + Vexec_path = nconc2 (decode_env_path (0, "GNUEmacs:c"), Vexec_path); + free(apath); + } + #endif execdir = Fdirectory_file_name (Vexec_directory); if (access (XSTRING (execdir)->data, 0) < 0) *************** *** 447,453 **** } sh = (char *) egetenv ("SHELL"); ! Vshell_file_name = build_string (sh ? sh : "/bin/sh"); #ifndef MAINTAIN_ENVIRONMENT /* The equivalent of this operation was done --- 470,476 ---- } sh = (char *) egetenv ("SHELL"); ! Vshell_file_name = build_string (sh ? sh : PATH_SHELL); #ifndef MAINTAIN_ENVIRONMENT /* The equivalent of this operation was done diff -rcP emacs-18.59-fsf/src/dired.c emacs-18.59-amiga/src/dired.c *** emacs-18.59-fsf/src/dired.c Mon Mar 23 04:16:41 1992 --- emacs-18.59-amiga/src/dired.c Sun Nov 22 10:13:54 1992 *************** *** 385,391 **** --- 385,395 ---- bcopy (XSTRING (dirname)->data, fullname, pos); #ifndef VMS + #ifdef AMIGA + if ((fullname[pos - 1] != '/')&&(fullname[pos - 1] != ':')) + #else if (fullname[pos - 1] != '/') + #endif fullname[pos++] = '/'; #endif diff -rcP emacs-18.59-fsf/src/dispnew.c emacs-18.59-amiga/src/dispnew.c *** emacs-18.59-fsf/src/dispnew.c Fri Jul 24 19:31:36 1992 --- emacs-18.59-amiga/src/dispnew.c Sun Nov 22 10:14:00 1992 *************** *** 674,684 **** --- 674,700 ---- int preempt_count = baud_rate / 2400 + 1; extern input_pending; + start_count(0); + if (screen_height == 0) abort (); /* Some bug zeros some core */ if (force_redisplay) force = 1; + #ifdef FAST_DISPLAY + /* Don't compute for i/d line if just want cursor motion. */ + /* Don't allow preemption, etc either */ + for (i = 0; i < screen_height; i++) + if (new_screen->enable[i]) + break; + + if (i >= screen_height) + { + update_begin(); + goto update_done; + } + #endif + if (!force) detect_input_pending (); if (!force *************** *** 695,704 **** if (!line_ins_del_ok) inhibit_hairy_id = 1; /* Don't compute for i/d line if just want cursor motion. */ for (i = 0; i < screen_height; i++) ! if (new_screen->enable) break; /* Try doing i/d line, if not yet inhibited. */ if (!inhibit_hairy_id && i < screen_height) --- 711,722 ---- if (!line_ins_del_ok) inhibit_hairy_id = 1; + #ifndef FAST_DISPLAY /* Don't compute for i/d line if just want cursor motion. */ for (i = 0; i < screen_height; i++) ! if (new_screen->enable[i]) break; + #endif /* Try doing i/d line, if not yet inhibited. */ if (!inhibit_hairy_id && i < screen_height) *************** *** 742,747 **** --- 760,768 ---- update_line (i); } } + #ifdef FAST_DISPLAY + update_done: + #endif pause = (i < screen_height - 1) ? i + 1 : 0; /* Now just clean up termcap drivers and set cursor, etc. */ *************** *** 781,786 **** --- 802,808 ---- } bzero (new_screen->enable, screen_height); + stop_count(0); return pause; } *************** *** 894,899 **** --- 916,972 ---- else reassert_line_highlight (new_screen->highlight[vpos], vpos); + #ifdef FAST_DISPLAY + if (current_screen->enable[vpos]) + { + obody = current_screen->contents[vpos]; + olen = current_screen->used[vpos]; + } + else olen = 0; + + nbody = new_screen->contents[vpos]; + nlen = new_screen->used[vpos]; + + /* Pretend trailing spaces are not there at all, + unless for one reason or another we must write all spaces. */ + /* We know that the previous character byte contains 0. */ + if (! new_screen->highlight[vpos]) + { + if (!must_write_spaces) + while (nbody[nlen - 1] == ' ') + nlen--; + } + else + { + /* For an inverse-video line, give it extra trailing spaces + all the way to the screen edge + so that the reverse video extends all the way across. */ + while (nlen < screen_width - 1) + nbody[nlen++] = ' '; + } + + while (olen > 0 && nlen > 0 && *obody == *nbody) + { + olen--; nlen--; obody++; nbody++; + } + if (olen > 0 || nlen > 0) + move_cursor (vpos, nbody - new_screen->contents[vpos]); + if (nlen > 0) output_chars (nbody, nlen); + + if (olen > nlen && new_screen->used[vpos] != screen_width) + clear_end_of_line(current_screen->used[vpos]); + /* Exchange contents between current_screen and new_screen. */ + temp = new_screen->contents[vpos]; + new_screen->contents[vpos] = current_screen->contents[vpos]; + current_screen->contents[vpos] = temp; + + /* One way or another, this will enable the line being updated. */ + current_screen->enable[vpos] = 1; + current_screen->used[vpos] = new_screen->used[vpos]; + current_screen->highlight[vpos] = new_screen->highlight[vpos]; + + #else /* not FAST_DISPLAY */ + /* ??? */ if (! current_screen->enable[vpos]) { *************** *** 1172,1177 **** --- 1245,1251 ---- temp = new_screen->contents[vpos]; new_screen->contents[vpos] = current_screen->contents[vpos]; current_screen->contents[vpos] = temp; + #endif /* not FAST_DISPLAY */ } count_blanks (str) *************** *** 1577,1584 **** --- 1651,1668 ---- cursor_in_echo_area = 0; terminal_type = (char *) 0; + #ifdef AMIGA + amiga_term_open(); + #endif if (!inhibit_window_system) { + #ifdef AMIGA + amiga_term_init(); + /* Using Intuition V2.04 */ + Vwindow_system = intern ("intuition"); + Vwindow_system_version = make_number (2); + goto term_init_done; + #endif /* AMIGA */ #ifdef HAVE_X_WINDOWS extern char *alternate_display; char *disp = (char *) egetenv ("DISPLAY"); diff -rcP emacs-18.59-fsf/src/doc.c emacs-18.59-amiga/src/doc.c *** emacs-18.59-fsf/src/doc.c Tue Jan 8 17:25:38 1991 --- emacs-18.59-amiga/src/doc.c Sun Nov 22 10:14:02 1992 *************** *** 21,26 **** --- 21,27 ---- #include "config.h" #include "lisp.h" #include "buffer.h" + #include "paths.h" #include #include /* Must be after sys/types.h for USG and BSD4_1*/ *************** *** 188,194 **** #ifndef CANNOT_DUMP name = (char *) alloca (XSTRING (filename)->size + 8); ! strcpy (name, "../etc/"); #else /* CANNOT_DUMP */ CHECK_STRING (Vexec_directory, 0); name = (char *) alloca (XSTRING (filename)->size + --- 189,195 ---- #ifndef CANNOT_DUMP name = (char *) alloca (XSTRING (filename)->size + 8); ! strcpy (name, RELPATH_DOC); #else /* CANNOT_DUMP */ CHECK_STRING (Vexec_directory, 0); name = (char *) alloca (XSTRING (filename)->size + diff -rcP emacs-18.59-fsf/src/dostrip.c emacs-18.59-amiga/src/dostrip.c *** emacs-18.59-fsf/src/dostrip.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/dostrip.c Sun Nov 22 10:14:02 1992 *************** *** 0 **** --- 1,23 ---- + #include + + #define SIZE 2048 + + main(int argc, char **argv) + { + char buf[SIZE]; + + buf[SIZE - 1] = 0; + while (fgets(buf, SIZE - 1, stdin)) + { + if (buf[0] != '#') + { + char *p = buf, *e; + + while (*p && *p == ' ') p++; + e = p + strlen(p); + while (e > p && (e[-1] == ' ' || e[-1] == '\t' || e[-1] == '\n')) e--; + *e = '\0'; + if (*p) puts(p); + } + } + } diff -rcP emacs-18.59-fsf/src/emacs.c emacs-18.59-amiga/src/emacs.c *** emacs-18.59-fsf/src/emacs.c Sat Oct 17 03:51:00 1992 --- emacs-18.59-amiga/src/emacs.c Sun Nov 22 10:14:08 1992 *************** *** 78,83 **** --- 78,87 ---- #endif #endif + #ifdef AMIGA_DUMP + #define HAVE_SHM /* Simplifies the ifdefs */ + #endif + #ifndef O_RDWR #define O_RDWR 2 #endif *************** *** 323,328 **** --- 327,333 ---- xargc = argc; #endif + #ifndef AMIGA /* Handle the -t switch, which specifies filename to use as terminal */ if (skip_args + 2 < argc && !strcmp (argv[skip_args + 1], "-t")) { *************** *** 336,341 **** --- 341,347 ---- inhibit_window_system = 1; /* -t => -nw */ #endif } + #endif #ifdef HAVE_X_WINDOWS /* Handle the -d switch, which means use a different display for X */ if (skip_args + 2 < argc && (!strcmp (argv[skip_args + 1], "-d") || *************** *** 717,723 **** --- 723,733 ---- #ifdef VMS #define SEPCHAR ',' #else + #ifdef AMIGA /* Can't use : on Amiga */ + #define SEPCHAR ',' + #else #define SEPCHAR ':' + #endif #endif Lisp_Object diff -rcP emacs-18.59-fsf/src/exec.c emacs-18.59-amiga/src/exec.c *** emacs-18.59-fsf/src/exec.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/exec.c Sat Oct 24 12:59:54 1992 *************** *** 0 **** --- 1,138 ---- + #include "amiga.h" + #include "processes.h" + #include + #include + #include + #include + #include + + int eexec(char *program, char **argv, int input, int output, int error, + char *dir, int stacksize) + /* input = -1 -> inherit Input() + output = -1 -> inherit Output() + error = -1 -> inherit pr_CES + error = -2 -> stderr = stdout */ + { + int index, comsize, close_input, close_output, close_error; + char *combuf, *bp; + BPTR in, out, err, dirlock; + int _pseudo_close(int fd); + + comsize = 256; + combuf = malloc(comsize); + + if (input == -1) + { + in = Input(); + close_input = FALSE; + } + else + { + if (ioctl(input, _AMIGA_GET_FH, &in) == -1) in = 0; + close_input = TRUE; + _pseudo_close(input); + } + + if (output == -1) + { + out = Output(); + close_output = FALSE; + } + else + { + if (ioctl(output, _AMIGA_GET_FH, &out) == -1) out = 0; + close_output = out != in; + _pseudo_close(output); + } + + if (error == -1) + { + err = _us->pr_CES; + close_error = FALSE; + } + else if (error == -2) + { + err = out; + close_error = FALSE; + } + else + { + if (ioctl(error, _AMIGA_GET_FH, &err) == -1) err = 0; + close_error = err != out && err != in; + _pseudo_close(error); + } + + /* pr_CES is not always defined */ + if (in && out && (err || error == -1)) + if (combuf) + { + bp = combuf; + for (index = 0; argv[index] != 0; index++) + { + /* Use program as argv[0]. This loses some information, but ... */ + char *arg = index == 0 ? program : argv[index]; + char *s; + int len; + + len = 3; + s = arg; + while (*s) + { + len++; + if (*s == '*' || *s == '"' || *s == '\n') len++; + s++; + } + if (bp + len + 1 >= combuf + comsize) + { + char *newbuf; + + comsize += comsize + len; + newbuf = realloc(combuf, comsize); + if (!newbuf) { errno = ENOMEM; goto error; } + bp = newbuf + (bp - combuf); + combuf = newbuf; + } + *bp++ = ' '; + *bp++ = '"'; + s = arg; + while (*s) + { + if (*s == '"' || *s == '*') *bp++ = '*'; + else if (*s == '\n') *bp++ = '+'; + *bp++ = *s++; + } + *bp++ = '"'; + } + *bp = '\0'; + if (dir) dirlock = Lock(dir, SHARED_LOCK); + else dirlock = 0; + + if (dirlock || !dir) + { + int pid = _start_process(combuf, in, close_input, out, close_output, + err, close_error, dirlock, stacksize); + + if (pid != -1) + { + free(combuf); + return pid; + } + } + else errno = convert_oserr(IoErr()); + if (dirlock) UnLock(dirlock); + } + else errno = ENOMEM; + + error: + if (in && close_input) Close(in); + if (out && close_output) Close(out); + if (err && close_error) Close(err); + if (combuf) free(combuf); + return -1; + } + + int exec(char *program, char **argv, int input, int output, + char *dir, int stacksize) + { + return eexec(program, argv, input, output, -1, dir, stacksize); + } diff -rcP emacs-18.59-fsf/src/fileio.c emacs-18.59-amiga/src/fileio.c *** emacs-18.59-fsf/src/fileio.c Tue Oct 6 22:02:20 1992 --- emacs-18.59-amiga/src/fileio.c Sun Nov 22 10:14:24 1992 *************** *** 147,152 **** --- 147,155 ---- p = beg + XSTRING (file)->size; while (p != beg && p[-1] != '/' + #ifdef AMIGA + && p[-1] != ':' + #endif /* AMIGA */ #ifdef VMS && p[-1] != ':' && p[-1] != ']' && p[-1] != '>' #endif /* VMS */ *************** *** 174,179 **** --- 177,185 ---- end = p = beg + XSTRING (file)->size; while (p != beg && p[-1] != '/' + #ifdef AMIGA + && p[-1] != ':' + #endif /* AMIGA */ #ifdef VMS && p[-1] != ':' && p[-1] != ']' && p[-1] != '>' #endif /* VMS */ *************** *** 248,256 **** --- 254,268 ---- out[size] = '\0'; } #else /* not VMS */ + #ifdef AMIGA + /* AmigaDOS syntax, append slash if the last char isn't a ':' or '/' */ + if (out[size] != '/' && out[size] != ':' && size != 0) + strcat (out, "/"); + #else /* not AMIGA */ /* For Unix syntax, Append a slash if necessary */ if (out[size] != '/') strcat (out, "/"); + #endif /* not AMIGA */ #endif /* not VMS */ return out; } *************** *** 464,469 **** --- 476,585 ---- (name, defalt) Lisp_Object name, defalt; { + #ifdef AMIGA + unsigned char *nm, *tilde, *newdir, *colon, *t_pos, *target; + + CHECK_STRING (name, 0); + + nm = XSTRING (name)->data; + /* Find base directory */ + if (NULL (defalt)) + defalt = current_buffer->directory; + CHECK_STRING (defalt, 1); + newdir = XSTRING (defalt)->data; + + /* Concat newdir w/ nm and canonicalize */ + /* newdir always contains at least the device name. + It is assumed canonical */ + target = (unsigned char *)alloca(strlen(nm) + strlen(newdir) + 2); + file_name_as_directory (target, newdir); + t_pos = target + strlen(target); + + while (*nm) + { + unsigned char *comp_end = nm; + int comp_len; + + /* Find next component of path (everything upto the next /) */ + do comp_end++; while (comp_end[0] && comp_end[-1] != '/' && comp_end[-1] != ':'); + comp_len = comp_end - nm; + + if (comp_len == 1 && nm[0] == '/' || + nm[0] == '.' && nm[1] == '.' && + (comp_len == 2 || comp_len == 3 && nm[2] == '/')) + { + /* Previous directory */ + if (t_pos > target && t_pos[-1] != ':') + { + t_pos--; /* Back up over / */ + while (t_pos > target && + t_pos[-1] != ':' && t_pos[-1] != '/') t_pos--; + } + } + else if (comp_len == 2 && nm[0] == '.' && nm[1] == '/' || + comp_len == 1 && nm[0] == '.') ; /* Ignore . */ + else if (nm[0] == ':') /* Just keep disk name */ + { + char *new_pos; + + *t_pos = 0; /* Limit search for : */ + t_pos = index(target, ':'); + if (t_pos) t_pos++; + else t_pos = target; + } + else if (nm[0] == '~' || index(nm, ':')) + { + char *exp_name; + + if (nm[0] == '~') + if (nm[1] == '/' || nm[1] == 0) /* Home directory */ + { + newdir = (unsigned char *) egetenv ("HOME"); + if (!newdir) newdir = (unsigned char *) "s:"; + } + else + { + /* Handle ~ followed by user name. */ + char lastc = nm[comp_len - 1]; + int len = comp_len - 1; + + if (lastc == ':' || lastc == '/') len--; + + /* ~name becomes name: */ + newdir = (unsigned char *) alloca (len + 2); + bcopy((char *) nm + 1, newdir, len); + newdir[len] = ':'; + newdir[len + 1] = 0; + } + else /* we have name: */ + { + newdir = (char *)alloca(comp_len + 1); + bcopy(nm, newdir, comp_len); + newdir[comp_len] = 0; + } + exp_name = (char *)alloca(1024); + if (expand_path(newdir, exp_name, 1024)) + { + char *colon = strchr(exp_name, ':'); + + /* Detect paths with multiple colons (eg from PATH:) and + leave them alone. They create confusion. */ + if (!(colon && strchr(colon + 1, ':'))) newdir = exp_name; + } + target = (unsigned char *)alloca(strlen(nm) + strlen(newdir) + 2); + file_name_as_directory (target, newdir); + t_pos = target + strlen(target); + } + else /* Copy component */ + { + bcopy(nm, t_pos, comp_len); + t_pos += comp_len; + } + + nm = comp_end; + } + return make_string (target, t_pos - target); + #else /* not AMIGA */ unsigned char *nm; register unsigned char *newdir, *p, *o; *************** *** 795,800 **** --- 911,917 ---- } return make_string (target, o - target); + #endif /* not AMIGA */ } DEFUN ("substitute-in-file-name", Fsubstitute_in_file_name, *************** *** 825,830 **** --- 942,964 ---- for (p = nm; p != endp; p++) { + #ifdef AMIGA + if (p[0] == '~' && p != nm && p[-1] == '/') + { + nm = p; + substituted = 1; + } + else if (p[0] == ':') + { + char *p2 = p; + while (p2 > nm && p2[-1] != ':' && p2[-1] != '/') p2--; + if (p2 != nm) + { + nm = p2; + substituted = 1; + } + } + #else /* not AMIGA */ if ((p[0] == '~' || #ifdef APOLLO /* // at start of file name is meaningful in Apollo system */ *************** *** 845,850 **** --- 979,985 ---- nm = p; substituted = 1; } + #endif /* not AMIGA */ } #ifdef VMS *************** *** 1353,1358 **** --- 1488,1500 ---- CHECK_STRING (filename, 0); ptr = XSTRING (filename)->data; + #ifdef AMIGA + /* An absolute filename has a non-leading ':' in it */ + if (*ptr != ':') + while (*ptr) + if (*ptr++ == ':') return Qt; + return Qnil; + #else /* not AMIGA */ if (*ptr == '/' || *ptr == '~' #ifdef VMS /* ??? This criterion is probably wrong for '<'. */ *************** *** 1364,1369 **** --- 1506,1512 ---- return Qt; else return Qnil; + #endif /* not AMIGA */ } DEFUN ("file-exists-p", Ffile_exists_p, Sfile_exists_p, 1, 1, 0, diff -rcP emacs-18.59-fsf/src/firstfile.c emacs-18.59-amiga/src/firstfile.c *** emacs-18.59-fsf/src/firstfile.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/firstfile.c Sun Nov 22 10:14:28 1992 *************** *** 0 **** --- 1,4 ---- + int first_data = 1; + int first_bss; + + void first_function() { } diff -rcP emacs-18.59-fsf/src/indent.c emacs-18.59-amiga/src/indent.c *** emacs-18.59-fsf/src/indent.c Sat Apr 18 16:01:07 1992 --- emacs-18.59-amiga/src/indent.c Sun Nov 22 10:14:38 1992 *************** *** 35,40 **** --- 35,45 ---- #define min(a, b) ((a) < (b) ? (a) : (b)) #define max(a, b) ((a) > (b) ? (a) : (b)) + #ifdef EIGHT_BIT + /* Visible characters */ + extern char visible[]; + #endif + /* These three values memoize the current column to avoid recalculation */ /* Some things in set last_known_column_point to -1 to mark the memoized value as invalid */ *************** *** 115,121 **** --- 120,130 ---- } c = *--ptr; + #ifdef EIGHT_BIT + if (visible[c]) + #else if (c >= 040 && c < 0177) + #endif { col++; } *************** *** 326,332 **** --- 335,345 ---- } else if (ctl_arrow && (c < 040 || c == 0177)) col++; + #ifdef EIGHT_BIT + else if (!visible[c]) + #else else if (c < 040 || c >= 0177) + #endif col += 3; } *************** *** 373,381 **** prev_hpos = hpos; c = FETCH_CHAR (pos); if (c >= 040 && c < 0177) ! hpos++; ! else if (c == '\t') { hpos += tab_width - ((hpos + tab_offset + hscroll - (hscroll > 0) /* Add tab_width here to make sure positive. --- 386,442 ---- prev_hpos = hpos; c = FETCH_CHAR (pos); + #ifdef EIGHT_BIT + if (visible[c]) + #else if (c >= 040 && c < 0177) ! #endif ! { ! unsigned char *p; ! int gap_pos; ! int maxhpos; ! ! if (vpos == tovpos) ! { ! maxhpos = tohpos; ! if (maxhpos > width) maxhpos = width; ! } ! else maxhpos = width; ! ! if (pos < GPT) ! { ! gap_pos = GPT; ! p = BEG_ADDR + pos; ! } ! else ! { ! gap_pos = -1; ! p = GAP_SIZE + BEG_ADDR + pos; ! } ! do ! { ! hpos++; ! if (hpos >= maxhpos) ! { ! prev_hpos = hpos - 1; ! if (hpos >= width) goto check_hpos; ! /* We've reached the target pos */ ! pos++; ! goto done; ! } ! pos++; ! if (pos >= to) ! { ! prev_hpos = hpos - 1; ! goto done; ! } ! if (gap_pos == pos) p += GAP_SIZE; ! c = *p++; ! } ! while (visible[c]); ! prev_hpos = hpos; ! } ! if (c == '\t') { hpos += tab_width - ((hpos + tab_offset + hscroll - (hscroll > 0) /* Add tab_width here to make sure positive. *************** *** 433,438 **** --- 494,500 ---- else hpos += (ctl_arrow && c < 0200) ? 2 : 4; + check_hpos: /* Handle right margin. */ if (hpos >= width && (hpos > width *************** *** 462,467 **** --- 524,530 ---- } } + done: val_compute_motion.bufpos = pos; val_compute_motion.hpos = hpos; diff -rcP emacs-18.59-fsf/src/keyboard.c emacs-18.59-amiga/src/keyboard.c *** emacs-18.59-fsf/src/keyboard.c Sun May 17 06:57:15 1992 --- emacs-18.59-amiga/src/keyboard.c Sun Nov 22 10:14:48 1992 *************** *** 1313,1319 **** --- 1313,1325 ---- #endif fcntl (fileno (stdin), F_SETFL, 0); #else /* not USG */ + #ifdef AMIGA /* This is where the input work finally gets done */ + /* Note, The nread != 0 case isn't handled as it doesn't arise on the Amiga. + (Look carefully at calls to read_avail_input) */ + nread = read(0, buf, sizeof buf); + #else /* not AMIGA */ you lose + #endif /* not AMIGA */ #endif /* not USG */ #endif /* no FIONREAD */ diff -rcP emacs-18.59-fsf/src/keymap.c emacs-18.59-amiga/src/keymap.c *** emacs-18.59-fsf/src/keymap.c Sat Jul 27 17:43:27 1991 --- emacs-18.59-amiga/src/keymap.c Sun Nov 22 10:14:52 1992 *************** *** 29,34 **** --- 29,38 ---- /* Actually allocate storage for these variables */ + #ifdef AMIGA + #define HAVE_X_WINDOWS /* We want the mouse map too */ + #endif + #ifdef HAVE_X_WINDOWS Lisp_Object MouseMap; /* Keymap for mouse commands */ #endif /* HAVE_X_WINDOWS */ diff -rcP emacs-18.59-fsf/src/lastfile.c emacs-18.59-amiga/src/lastfile.c *** emacs-18.59-fsf/src/lastfile.c Sat Mar 30 23:05:55 1991 --- emacs-18.59-amiga/src/lastfile.c Sat Dec 5 18:16:44 1992 *************** *** 35,43 **** --- 35,57 ---- coming from libraries. */ + #ifdef AMIGA + /* I need to find the end of initialised and unitialised data, as well as of + executable code. + */ + int last_data = 1; + int last_bss; + + void last_function() { } + + /* Some data that shouldn't be dumped */ + #include "amiga_data.c" + + #else /* not AMIGA */ #ifdef VMS /* Prevent the file from being totally empty. */ static dummy () {} #endif char my_edata = 0; + #endif /* not AMIGA */ diff -rcP emacs-18.59-fsf/src/lisp.h emacs-18.59-amiga/src/lisp.h *** emacs-18.59-fsf/src/lisp.h Thu Mar 5 23:11:31 1992 --- emacs-18.59-amiga/src/lisp.h Sun Nov 22 10:14:58 1992 *************** *** 287,293 **** (XUINT (a) | (XUINT (a) > PURESIZE ? DATA_SEG_BITS : PURE_SEG_BITS)) #else /* not HAVE_SHM */ #ifdef DATA_SEG_BITS ! /* This case is used for the rt-pc. In the diffs I was given, it checked for ptr = 0 and did not adjust it in that case. But I don't think that zero should ever be found --- 287,293 ---- (XUINT (a) | (XUINT (a) > PURESIZE ? DATA_SEG_BITS : PURE_SEG_BITS)) #else /* not HAVE_SHM */ #ifdef DATA_SEG_BITS ! /* This case is used for the rt-pc and the Amiga. In the diffs I was given, it checked for ptr = 0 and did not adjust it in that case. But I don't think that zero should ever be found *************** *** 520,525 **** --- 520,532 ---- { if (XTYPE ((x)) == Lisp_Marker) XFASTINT (x) = marker_position (x); \ else if (XTYPE ((x)) != Lisp_Int) x = wrong_type_argument (Qinteger_or_marker_p, (x)); } + #ifdef AMIGA_DUMP + #define CHECK_IMPURE(obj) \ + { extern int *pure, puresize; \ + if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + puresize) \ + && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) \ + pure_write_error (); } + #else /* not AMIGA_DUMP */ #ifdef VIRT_ADDR_VARIES /* For machines like APOLLO where text and data can go anywhere *************** *** 529,535 **** if ((PNTR_COMPARISON_TYPE) XPNTR (obj) < (PNTR_COMPARISON_TYPE) ((char *) pure + PURESIZE) \ && (PNTR_COMPARISON_TYPE) XPNTR (obj) >= (PNTR_COMPARISON_TYPE) pure) \ pure_write_error (); } - #else /* not VIRT_ADDR_VARIES */ #ifdef PNTR_COMPARISON_TYPE --- 536,541 ---- *************** *** 548,553 **** --- 554,560 ---- #endif /* PNTR_COMPARISON_TYPE */ #endif /* VIRT_ADDRESS_VARIES */ + #endif /* not AMIGA_DUMP */ /* Cast pointers to this type to compare them. Some machines want int. */ #ifndef PNTR_COMPARISON_TYPE diff -rcP emacs-18.59-fsf/src/lread.c emacs-18.59-amiga/src/lread.c *** emacs-18.59-fsf/src/lread.c Mon Mar 23 04:18:17 1992 --- emacs-18.59-amiga/src/lread.c Sun Nov 22 10:15:02 1992 *************** *** 240,250 **** --- 240,254 ---- Lisp_Object pathname; { register unsigned char *s = XSTRING (pathname)->data; + #ifdef AMIGA + return (*s && index(s + 1, ':')); /* Non-leading : */ + #else return (*s == '~' || *s == '/' #ifdef VMS || index (s, ':') #endif /* VMS */ ); + #endif /* not AMIGA */ } /* Search for a file whose name is STR, looking in directories *************** *** 559,565 **** } static int read_buffer_size; ! static char *read_buffer; static Lisp_Object read1 (readcharfun) --- 563,569 ---- } static int read_buffer_size; ! char *read_buffer; static Lisp_Object read1 (readcharfun) diff -rcP emacs-18.59-fsf/src/m-amiga.h emacs-18.59-amiga/src/m-amiga.h *** emacs-18.59-fsf/src/m-amiga.h Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/m-amiga.h Sun Nov 22 10:20:16 1992 *************** *** 0 **** --- 1,129 ---- + /* m- file for GNU Emacs running on AmigaDOS 2.04, SAS C compiler 5.10b + Copyright (C) 1985, 1986 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Emacs General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + GNU Emacs, but only under the conditions described in the + GNU Emacs General Public License. A copy of this license is + supposed to have been given to you along with GNU Emacs so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. */ + + + /* The following three symbols give information on + the size of various data types. */ + /* lisp.h doesn't make any concessions for INTBITS = 16 and + NO_UNION_TYPE (use int as lisp object) defined. The following is + assuming that the Manx 32 bit int. math package is faster than + bitfield implementation, overall. If you want to use INTBITS = 16, + you *cannot* define NO_UNION_TYPE. */ + + #define SHORTBITS 16 /* Number of bits in a short */ + + #define INTBITS 32 /* Number of bits in an int */ + + #define LONGBITS 32 /* Number of bits in a long */ + + #define VALBITS 26 /* Number of bits in an int or pointer offset */ + + #define GCTYPEBITS 5 /* Number of bits in a type. */ + + /* Define BIG_ENDIAN iff lowest-numbered byte in a word + is the most significant byte. */ + + #define BIG_ENDIAN + + /* Define NO_ARG_ARRAY if you cannot take the address of the first of a + * group of arguments and treat it as an array of the arguments. */ + + /* #define NO_ARG_ARRAY */ + + /* Define WORD_MACHINE if addresses and such have + * to be corrected before they can be used as byte counts. */ + + #define WORD_MACHINE + + /* Define how to take a char and sign-extend into an int. + On machines where char is signed, this is a no-op. */ + + #define SIGN_EXTEND_CHAR(c) (c) + + /* Now define a symbol for the cpu type, if your compiler + does not define it automatically: + Ones defined so far include vax, m68000, ns16000, pyramid, + orion, tahoe, APOLLO and many others */ + + #ifndef m68000 + #define m68000 + #endif + + /* Use type int rather than a union, to represent Lisp_Object */ + /* This is desirable for most machines. */ + + #define NO_UNION_TYPE + /* Use a struct rather than an int. */ + + + /* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend + the 24-bit bit field into an int. In other words, if bit fields + are always unsigned. + + If you use NO_UNION_TYPE, this flag does not matter. */ + + #define EXPLICIT_SIGN_EXTEND + + /* We don't have /dev/kmem, so LOAD_AVE_TYPE and LOAD_AVE_CVT are + not defined. */ + + /* Define CANNOT_DUMP on machines where unexec does not work. + Then the function dump-emacs will not be defined + and temacs will do (load "loadup") automatically unless told otherwise. */ + + /* #define CANNOT_DUMP */ + + /* Define VIRT_ADDR_VARIES if the virtual addresses of + pure and impure space as loaded can vary, and even their + relative order cannot be relied on. + + Otherwise Emacs assumes that text space precedes data space, + numerically. */ + + /* #define VIRT_ADDR_VARIES */ + /* I now rely on AMIGA_DUMP to make appropriate patches in the source */ + + /* Define C_ALLOCA if this machine does not support a true alloca + and the one written in C should be used instead. + Define HAVE_ALLOCA to say that the system provides a properly + working alloca function and it should be used. + Define neither one if an assembler-language alloca + in the file alloca.s should be used. */ + + #define C_ALLOCA + /* #define HAVE_ALLOCA */ + + /* Define STACK_DIRECTION for alloca.c */ + #define STACK_DIRECTION -1 /* Grows downward */ + + /* Define NO_REMAP if memory segmentation makes it not work well + to change the boundary between the text section and data section + when Emacs is dumped. If you define this, the preloaded Lisp + code will not be sharable; but that's better than failing completely. */ + + #define NO_REMAP + + /* Set high (32 - VALBITS) = 6 bits of every pointer to the same as those of + &pure[0]. + */ + #ifdef emacs + extern long far DataSegBits; + #endif + #define DATA_SEG_BITS DataSegBits diff -rcP emacs-18.59-fsf/src/paths.h-dist emacs-18.59-amiga/src/paths.h-dist *** emacs-18.59-fsf/src/paths.h-dist Wed Sep 12 00:51:18 1990 --- emacs-18.59-amiga/src/paths.h-dist Sun Nov 22 10:16:24 1992 *************** *** 17,19 **** --- 17,35 ---- /* the name of the file !!!SuperLock!!! in the directory specified by PATH_LOCK. Yes, this is redundant. */ #define PATH_SUPERLOCK "/usr/local/emacs/lock/!!!SuperLock!!!" + + /* The path to the file containing the termcap descriptions */ + #define PATH_TERMCAP "/etc/termcap" + + /* The relative path (while dumping) to the directory containing + the DOC file */ + #define RELPATH_DOC "../etc/" + + /* The path for a /dev/null-like device */ + #define PATH_NULL "/dev/null" + + /* Path for temporary files (for call-process-region) */ + #define PATH_TEMP "/tmp/emacsXXXXXX" + + /* Path to the shell (the one in shell-file-name) */ + #define PATH_SHELL "/bin/sh" diff -rcP emacs-18.59-fsf/src/process.c emacs-18.59-amiga/src/process.c *** emacs-18.59-fsf/src/process.c Sun Oct 25 04:42:04 1992 --- emacs-18.59-amiga/src/process.c Sun Nov 22 10:16:38 1992 *************** *** 1203,1209 **** --- 1203,1226 ---- If fork fails, remove_process will clear the bit. */ FD_SET (inchannel, &input_wait_mask); + #ifdef AMIGA { + register unsigned char *temp; + + if (XTYPE (current_buffer->directory) == Lisp_String) + { + register int i; + + i = XSTRING (current_buffer->directory)->size; + temp = (unsigned char *) alloca (i + 1); + bcopy (XSTRING (current_buffer->directory)->data, temp, i); + temp[i] = 0; + } + pid = exec(new_argv[0], new_argv, forkin, forkout, temp, + amiga_process_stack_size); + } + #else /* not AMIGA */ + { /* child_setup must clobber environ on systems with true vfork. Protect it from permanent change. */ char **save_environ = environ; *************** *** 1305,1310 **** --- 1322,1328 ---- } environ = save_environ; } + #endif /* not AMIGA */ if (pid < 0) { *************** *** 1314,1319 **** --- 1332,1338 ---- XFASTINT (XPROCESS (process)->pid) = pid; + #ifndef AMIGA /* If the subfork execv fails, and it exits, this close hangs. I don't know why. So have an interrupt jar it loose. */ *************** *** 1326,1331 **** --- 1345,1351 ---- start_polling (); if (forkin != forkout && forkout >= 0) close (forkout); + #endif #ifdef SIGCHLD #ifdef BSD4_1 diff -rcP emacs-18.59-fsf/src/s-amiga.h emacs-18.59-amiga/src/s-amiga.h *** emacs-18.59-fsf/src/s-amiga.h Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/s-amiga.h Sat Oct 2 15:32:32 1993 *************** *** 0 **** --- 1,215 ---- + /* file for GNU Emacs running on AmigaDOS 2.04, SAS C compiler 5.10b + Copyright (C) 1985, 1986 Free Software Foundation, Inc. + + This file is part of GNU Emacs. + + GNU Emacs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY. No author or distributor + accepts responsibility to anyone for the consequences of using it + or for whether it serves any particular purpose or works at all, + unless he says so in writing. Refer to the GNU Emacs General Public + License for full details. + + Everyone is granted permission to copy, modify and redistribute + GNU Emacs, but only under the conditions described in the + GNU Emacs General Public License. A copy of this license is + supposed to have been given to you along with GNU Emacs so you + can know your rights and responsibilities. It should be in a + file named COPYING. Among other things, the copyright notice + and this notice must be preserved on all copies. */ + + + /* + * Define symbols to identify the version of Unix this is. + * Define all the symbols that apply correctly. + */ + + #ifndef AMIGA + #define AMIGA + #endif /* AMIGA */ + + /* SYSTEM_TYPE should indicate the kind of system you are using. + It sets the Lisp variable system-type. */ + + #define SYSTEM_TYPE "amigados" + + /* Define this if you want a faster redisplay. This saves a lot of CPU + time at the expense of more characters to be redrawn. + On a bitmapped display you win, with a serial line you probably lose. + */ + #define FAST_DISPLAY + + /* Define this to display eight bit characters. The actual characters + that are visible can be set in init_xdisp (). + */ + #define EIGHT_BIT + + /* nomultiplejobs should be defined if your system's shell + does not have "job control" (the ability to stop a program, + run some other program, then continue the first one). */ + + #define NOMULTIPLEJOBS + + /* Define this to include various patches that allow the Amiga to dump. + This *must* be defined on the Amiga! + */ + #define AMIGA_DUMP + + /* Do not use interrupt_input = 1 by default, because in 4.3 + we can make noninterrupt input work properly. */ + + /* #undef INTERRUPT_INPUT */ /* This file borrowed from s-bsd4-3.h */ + + /* First pty name is /dev/ptyp0. */ + + /* #define FIRST_PTY_LETTER 'p' */ + /* + * Define HAVE_TIMEVAL if the system supports the BSD style clock values. + * Look in for a timeval structure. + */ + + #define HAVE_TIMEVAL + #define USE_UTIME + + /* + * Define HAVE_SELECT if the system supports the `select' system call. + */ + + #define HAVE_SELECT + + /* + * Define HAVE_PTYS if the system supports pty devices. + */ + + /* #define HAVE_PTYS */ + + /* Define HAVE_SOCKETS if system supports 4.2-compatible sockets. */ + + /* #define HAVE_SOCKETS */ + + /* But we do have socket pairs for processes ... */ + #define SKTPAIR + + /* + * Define NONSYSTEM_DIR_LIBRARY to make Emacs emulate + * The 4.2 opendir, etc., library functions. + */ + + /* #define NONSYSTEM_DIR_LIBRARY */ + #define SYSV_SYSTEM_DIR + + /* Define this symbol if your system has the functions bcopy, etc. */ + + #define BSTRING /* #define'ed later on */ + + /* subprocesses should be defined if you want to + have code for asynchronous subprocesses + (as used in M-x compile and M-x shell). + This is generally OS dependent, and not supported + under most USG systems. */ + + #define subprocesses + + #define DID_REMOTE /* Use 0 length write to send eof */ + + /* If your system uses COFF (Common Object File Format) then define the + preprocessor symbol "COFF". */ + + /* #define COFF */ + + /* define MAIL_USE_FLOCK if the mailer uses flock + to interlock access to /usr/spool/mail/$USER. + The alternative is that a lock file named + /usr/spool/mail/$USER.lock. */ + + /* #define MAIL_USE_FLOCK */ + + /* Define CLASH_DETECTION if you want lock files to be written + so that Emacs can tell instantly when you try to modify + a file that someone else has modified in his Emacs. */ + + /* #define CLASH_DETECTION */ + + /* We use the Berkeley (and usg5.2.2) interface to nlist. */ + + /* #define NLIST_STRUCT */ + + /* The file containing the kernel's symbol table is called /vmunix. */ + + /* #define KERNEL_FILE "/vmunix" */ + + /* The symbol in the kernel where the load average is found + is named _avenrun. */ + + /* #define LDAV_SYMBOL "_avenrun" */ + + /* We use our own malloc for 2 reasons: + - To check that the 6 (INTBITS - VALBITS) of allocated data are + the same as &pure[0]. + - To release unused memory to the system (SAS's malloc keeps it + till you quit) + */ + + #define SYMS_SYSTEM syms_of_amiga() + + #define SYSTEM_MALLOC /* But I have replaced the system malloc ... */ + + #define DEF_PURESIZE 132000 /* Leave space for extra code for Amiga */ + #ifdef emacs + extern int puresize; + #endif + #define PURESIZE puresize /* Puresize is variable ... */ + + #ifdef emacs + /* Stdio must be included before redefining putchar */ + #include + extern char cbuffer[], *cbuffer_pos; + #define PENDING_OUTPUT_COUNT(x) (cbuffer_pos - cbuffer) + #endif + /* We divert some calls to our routines */ + #define putchar(c) do { extern int noninteractive; \ + if (noninteractive) putc (c, stdout); \ + else emacs_putchar(c); } while(0) + #define fwrite emacs_fwrite + #define fflush emacs_fflush + #define random rand + #define srandom srand + #define main emacs_main + #define select emacs_select + + #ifdef emacs + #include + #undef index + #undef rindex + #define index strchr + #define rindex strrchr + #endif + + #define fsync(x) 0 /* Emulate fsync ... */ + + #ifdef emacs + #include /* process.c doesn't have appropriate #ifdef's */ + extern int amiga_process_stack_size; + #endif + + /* Here are some symbols for ymakefile's benefit */ + + #define LIB_STANDARD //unix/src/unix.lib lib:sc.lib lib:amiga.lib + #define START_FILES lib:c.o firstfile.o + #define C_DEBUG_SWITCH debug s + #define C_OPTIMIZE_SWITCH opt + #define LD_SWITCH_SYSTEM + #define C_SWITCH_SYSTEM + #define S_SWITCH_MACHINE /* Nothing! */ + #define UNEXEC amiga_dump.o + #define OBJECTS_SYSTEM amiga_clipboard.o amiga_tty.o amiga_serial.o \ + amiga_screen.o amiga_menu.o amiga_malloc.o \ + amiga_rexx.o simplerexx.o amiga_term.o + + + /* Amiga window-specific stuff */ + + #define VERS "1.28DG Beta" + + #define FALSE 0 + #define TRUE 1 diff -rcP emacs-18.59-fsf/src/scroll.c emacs-18.59-amiga/src/scroll.c *** emacs-18.59-fsf/src/scroll.c Tue Jan 8 18:04:52 1991 --- emacs-18.59-amiga/src/scroll.c Sun Nov 22 10:17:30 1992 *************** *** 55,60 **** --- 55,61 ---- int *ILncost; int *DLncost; + #ifdef FAST_DISPLAY scrolling_1 (window_size, unchanged_at_top, unchanged_at_bottom, draw_cost, old_hash, new_hash, free_at_end) int window_size, unchanged_at_top, unchanged_at_bottom; *************** *** 63,68 **** --- 64,127 ---- int *new_hash; int free_at_end; { + int lines, i; + int window_end = unchanged_at_top + window_size; + + /* Rebase arrays at line 0 */ + old_hash -= unchanged_at_top - 1; + new_hash -= unchanged_at_top - 1; + draw_cost -= unchanged_at_top - 1; + + /* We can't allow un-enabled lines to be scrolled (they are not redrawable). + Restrict window to the first set of contiguous enabled lines + (an enabled line has draw_cost[x] != INFINITY) */ + for (i = unchanged_at_top; i < window_end && draw_cost[i] != INFINITY; i++) ; + /*unchanged_at_bottom += window_size - i;*/ + /*window_size = i - unchanged_at_top;*/ + window_end = i; + + if (lines = calc_scroll(old_hash, new_hash, unchanged_at_top, window_end)) + scroll_screen_lines(unchanged_at_top, window_end - lines, lines); + else if (lines = calc_scroll(new_hash, old_hash, unchanged_at_top, window_end)) + scroll_screen_lines(unchanged_at_top + lines, window_end, -lines); + } + + int calc_scroll(int *old_hash, int *new_hash, int from, int to) + /* For insert attempt, the parameters are correct. + For delete attempt, swap the old & new hash parameters + */ + { + int try = from + 1, lines, i; + int hash1 = old_hash[from]; + + do + { + if (hash1 == new_hash[try]) + { + /* Check if other lines match too */ + lines = try - from; /* Amount to insert */ + for (i = try + 1; i < to; i++) + if (old_hash[i - lines] != new_hash[i]) break; + if (i == to) /* It works ! */ + return lines; + } + try++; + } + while (try < to); + + return 0; + } + + #else /* not FAST_DISPLAY */ + + scrolling_1 (window_size, unchanged_at_top, unchanged_at_bottom, + draw_cost, old_hash, new_hash, free_at_end) + int window_size, unchanged_at_top, unchanged_at_bottom; + int *draw_cost; + int *old_hash; + int *new_hash; + int free_at_end; + { struct matrix_elt *matrix; matrix = ((struct matrix_elt *) alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix)); *************** *** 320,325 **** --- 379,385 ---- if (window) set_terminal_window (0); } + #endif /* not FAST_DISPLAY */ /* Return number of lines in common between current screen contents and the text to be displayed, diff -rcP emacs-18.59-fsf/src/simplerexx.c emacs-18.59-amiga/src/simplerexx.c *** emacs-18.59-fsf/src/simplerexx.c Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/simplerexx.c Mon May 10 14:35:42 1993 *************** *** 0 **** --- 1,416 ---- + /* + * Simple ARexx interface by Michael Sinz + * + * This is a very "Simple" interface to the world of ARexx... + * For more complex interfaces into ARexx, it is best that you + * understand the functions that are provided by ARexx. + * In many cases they are more powerful than what is presented + * here. + * + * This code is fully re-entrant and self-contained other than + * the use of SysBase/AbsExecBase and the ARexx RVI support + * library which is also self-contained... + */ + + #include + #include + #include + #include + #include + + #include + + #include + #include + + #include + #include + + /* + * The prototypes for the few ARexx functions we will call... + */ + struct RexxMsg *CreateRexxMsg(struct MsgPort *,char *,char *); + void *CreateArgstring(char *,long); + void DeleteRexxMsg(struct RexxMsg *); + void DeleteArgstring(char *); + BOOL IsRexxMsg(struct Message *); + + /* + * Pragmas for the above functions... (To make this all self-contained...) + * If you use RexxGlue.o, this is not needed... + * + * These are for Lattice C 5.x (Note the use of RexxContext->RexxSysBase) + */ + #pragma libcall RexxContext->RexxSysBase CreateRexxMsg 90 09803 + #pragma libcall RexxContext->RexxSysBase CreateArgstring 7E 0802 + #pragma libcall RexxContext->RexxSysBase DeleteRexxMsg 96 801 + #pragma libcall RexxContext->RexxSysBase DeleteArgstring 84 801 + #pragma libcall RexxContext->RexxSysBase IsRexxMsg A8 801 + + /* + * Now, we have made the pragmas needed, let's get to work... + */ + + /* + * A structure for the ARexx handler context + * This is *VERY* *PRIVATE* and should not be touched... + */ + struct ARexxContext + { + struct MsgPort *ARexxPort; /* The port messages come in at... */ + struct Library *RexxSysBase; /* We will hide the library pointer here... */ + long Outstanding; /* The count of outstanding ARexx messages... */ + char PortName[24]; /* The port name goes here... */ + char ErrorName[28]; /* The name of the .LASTERROR... */ + char Extension[8]; /* Default file name extension... */ + }; + + #define AREXXCONTEXT struct ARexxContext * + + #include "SimpleRexx.h" + + /* + * This function returns the port name of your ARexx port. + * It will return NULL if there is no ARexx port... + * + * This string is *READ ONLY* You *MUST NOT* modify it... + */ + char *ARexxName(AREXXCONTEXT RexxContext) + { + register char *tmp=NULL; + + if (RexxContext) tmp=RexxContext->PortName; + return(tmp); + } + + /* + * This function returns the signal mask that the Rexx port is + * using. It returns NULL if there is no signal... + * + * Use this signal bit in your Wait() loop... + */ + ULONG ARexxSignal(AREXXCONTEXT RexxContext) + { + register ULONG tmp=NULL; + + if (RexxContext) tmp=1L << (RexxContext->ARexxPort->mp_SigBit); + return(tmp); + } + + /* + * This function returns a structure that contains the commands sent from + * ARexx or the results of commands you sent. You will need to parse it + * and return the structure back so that the memory can be freed. + * + * This returns NULL if there was no message. + */ + struct RexxMsg *GetARexxMsg(AREXXCONTEXT RexxContext) + { + register struct RexxMsg *tmp=NULL; + register short flag; + + if (RexxContext) tmp=(struct RexxMsg *)GetMsg(RexxContext->ARexxPort); + return(tmp); + } + + /* Use this to delete a message sent via SendARexxMsg and that has now been + returned to you. + */ + void DeleteARexxMsg(AREXXCONTEXT RexxContext, struct RexxMsg *rmsg) + { + /* + * Free the arguments and the message... + */ + if(rmsg->rm_Action & RXFF_RESULT) { + if(rmsg->rm_Result1 == 0 && rmsg->rm_Result2) { + DeleteArgstring((STRPTR)rmsg->rm_Result2); + } + } + DeleteArgstring(rmsg->rm_Args[0]); + DeleteRexxMsg(rmsg); + RexxContext->Outstanding-=1; + } + + /* + * Use this to return a ARexx message... + * + * If you wish to return something, it must be in the RString. + * If you wish to return an Error, it must be in the Error. + * If there is an error, the RString is ignored. + */ + void ReplyARexxMsg(AREXXCONTEXT RexxContext,struct RexxMsg *rmsg, + char *RString,LONG Error) + { + if (RexxContext) if (rmsg) if (rmsg!=REXX_RETURN_ERROR) + { + rmsg->rm_Result2=0; + if (!(rmsg->rm_Result1=Error)) + { + /* + * if you did not have an error we return the string + */ + if (rmsg->rm_Action & (1L << RXFB_RESULT)) if (RString) + { + rmsg->rm_Result2=(LONG)CreateArgstring(RString, + (LONG)strlen(RString)); + } + } + + /* + * Reply the message to ARexx... + */ + ReplyMsg((struct Message *)rmsg); + } + } + + /* + * This function will set an error string for the ARexx + * application in the variable defined as .LASTERROR + * + * Note that this can only happen if there is an ARexx message... + * + * This returns TRUE if it worked, FALSE if it did not... + */ + short SetARexxLastError(AREXXCONTEXT RexxContext,struct RexxMsg *rmsg, + char *ErrorString) + { + register short OkFlag=FALSE; + + if (RexxContext) if (rmsg) if (CheckRexxMsg(rmsg)) + { + /* + * Note that SetRexxVar() has more than just a TRUE/FALSE + * return code, but for this "basic" case, we just care if + * it works or not. + */ + if (!SetRexxVar(rmsg,RexxContext->ErrorName,ErrorString, + (long)strlen(ErrorString))) + { + OkFlag=TRUE; + } + } + return(OkFlag); + } + + /* + * This function will send a string to ARexx... + * + * The default host port will be that of your task... + * + * If you set StringFile to TRUE, it will set that bit for the message... + * + * Returns the message sent, or NULL in case of error. + */ + struct RexxMsg *SendARexxMsg(AREXXCONTEXT RexxContext,char *RString, + short StringFile, short results) + { + register struct MsgPort *RexxPort; + register struct RexxMsg *rmsg; + register short flag=FALSE; + + if (RexxContext) if (RString) + { + if (rmsg=CreateRexxMsg(RexxContext->ARexxPort, + RexxContext->Extension, + RexxContext->PortName)) + { + rmsg->rm_Action=RXCOMM | (StringFile ? + (1L << RXFB_STRING):0); + rmsg->rm_Action |= (results ? RXFF_RESULT : 0); + if (rmsg->rm_Args[0]=CreateArgstring(RString, + (LONG)strlen(RString))) + { + /* + * We need to find the RexxPort and this needs + * to be done in a Forbid() + */ + Forbid(); + if (RexxPort=FindPort(RXSDIR)) + { + /* + * We found the port, so put the + * message to ARexx... + */ + PutMsg(RexxPort,(struct Message *)rmsg); + RexxContext->Outstanding+=1; + flag=TRUE; + } + else + { + /* + * No port, so clean up... + */ + DeleteArgstring(rmsg->rm_Args[0]); + DeleteRexxMsg(rmsg); + } + Permit(); + } + else DeleteRexxMsg(rmsg); + } + } + return flag ? rmsg : NULL; + } + + int PendingCommands(AREXXCONTEXT RexxContext) + { + if (RexxContext) return RexxContext->Outstanding; + else return 0; + } + + /* + * This function closes down the ARexx context that was opened + * with InitARexx... + */ + void FreeARexx(AREXXCONTEXT RexxContext) + { + register struct RexxMsg *rmsg; + + if (RexxContext) + { + /* + * Clear port name so it can't be found... + */ + RexxContext->PortName[0]='\0'; + + /* + * Clean out any outstanding messages we had sent out... + */ + while (RexxContext->Outstanding) + { + WaitPort(RexxContext->ARexxPort); + while (rmsg=GetARexxMsg(RexxContext)) + { + if (rmsg!=REXX_RETURN_ERROR) + { + /* + * Any messages that come now are blown + * away... + */ + SetARexxLastError(RexxContext,rmsg, + "99: Port Closed!"); + /* removed ReplyARexxMsg() this was a bug that would */ + /* obviously cause a loop (we would continue to reply and */ + /* then get the message. It now deletes the message as */ + /* should be done. -ch5/10/93. */ + DeleteARexxMsg(RexxContext,rmsg); + } + } + } + + /* + * Clean up the port and delete it... + */ + if (RexxContext->ARexxPort) + { + while (rmsg=GetARexxMsg(RexxContext)) + { + /* + * Any messages that still are coming in are + * "dead" We just set the LASTERROR and + * reply an error of 100... + */ + SetARexxLastError(RexxContext,rmsg, + "99: Port Closed!"); + ReplyARexxMsg(RexxContext,rmsg,NULL,100); + } + RemPort(RexxContext->ARexxPort); + DeleteMsgPort(RexxContext->ARexxPort); + } + + /* + * Make sure we close the library... + */ + if (RexxContext->RexxSysBase) + { + CloseLibrary(RexxContext->RexxSysBase); + } + + /* + * Free the memory of the RexxContext + */ + FreeMem(RexxContext,sizeof(struct ARexxContext)); + } + } + + /* + * This routine initializes an ARexx port for your process + * This should only be done once per process. You must call it + * with a valid application name and you must use the handle it + * returns in all other calls... + * + * NOTE: The AppName should not have spaces in it... + * Example AppNames: "MyWord" or "FastCalc" etc... + * The name *MUST* be less that 16 characters... + * If it is not, it will be trimmed... + * The name will also be UPPER-CASED... + * + * NOTE: The Default file name extension, if NULL will be + * "rexx" (the "." is automatic) + */ + AREXXCONTEXT InitARexx(char *AppName,char *Extension) + { + register AREXXCONTEXT RexxContext=NULL; + register short loop; + register short count; + register char *tmp; + + if (RexxContext=AllocMem(sizeof(struct ARexxContext), + MEMF_PUBLIC|MEMF_CLEAR)) + { + if (RexxContext->RexxSysBase=OpenLibrary("rexxsyslib.library", NULL)) + { + /* + * Set up the extension... + */ + if (!Extension) Extension="rexx"; + tmp=RexxContext->Extension; + for (loop=0;(loop<7)&&(Extension[loop]);loop++) + { + *tmp++=Extension[loop]; + } + *tmp='\0'; + + /* + * Set up a port name... + */ + tmp=RexxContext->PortName; + for (loop=0;(loop<16)&&(AppName[loop]);loop++) + { + *tmp++=toupper(AppName[loop]); + } + *tmp='\0'; + + /* + * Set up the last error RVI name... + * + * This is .LASTERROR + */ + strcpy(RexxContext->ErrorName,RexxContext->PortName); + strcat(RexxContext->ErrorName,".LASTERROR"); + + /* We need to make a unique port name... */ + Forbid(); + for (count=1,RexxContext->ARexxPort=(VOID *)1; + RexxContext->ARexxPort;count++) + { + stci_d(tmp,count); + RexxContext->ARexxPort= + FindPort(RexxContext->PortName); + } + + /*RexxContext->ARexxPort=CreatePort(RexxContext->PortName,NULL);*/ + RexxContext->ARexxPort=CreateMsgPort(); + RexxContext->ARexxPort->mp_Node.ln_Name = RexxContext->PortName; + RexxContext->ARexxPort->mp_Node.ln_Pri = 0; + AddPort(RexxContext->ARexxPort); + Permit(); + } + + if (!RexxContext->RexxSysBase || !RexxContext->ARexxPort) + { + FreeARexx(RexxContext); + RexxContext=NULL; + } + } + return(RexxContext); + } diff -rcP emacs-18.59-fsf/src/simplerexx.h emacs-18.59-amiga/src/simplerexx.h *** emacs-18.59-fsf/src/simplerexx.h Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/simplerexx.h Mon May 10 14:35:42 1993 *************** *** 0 **** --- 1,119 ---- + /* + * Simple ARexx interface by Michael Sinz + * + * This is a very "Simple" interface... + */ + + #ifndef SIMPLE_REXX_H + #define SIMPLE_REXX_H + + #include + #include + #include + #include + + #include + #include + + /* + * This is the handle that SimpleRexx will give you + * when you initialize an ARexx port... + * + * The conditional below is used to skip this if we have + * defined it earlier... + */ + #ifndef AREXXCONTEXT + + typedef void *AREXXCONTEXT; + + #endif /* AREXXCONTEXT */ + + /* + * The value of RexxMsg (from GetARexxMsg) if there was an error returned + */ + #define REXX_RETURN_ERROR ((struct RexxMsg *)-1L) + #define REXX_RETURN_OK ((struct RexxMsg *)-3L) + + /* + * This function closes down the ARexx context that was opened + * with InitARexx... + */ + void FreeARexx(AREXXCONTEXT); + + /* + * This routine initializes an ARexx port for your process + * This should only be done once per process. You must call it + * with a valid application name and you must use the handle it + * returns in all other calls... + * + * NOTE: The AppName should not have spaces in it... + * Example AppNames: "MyWord" or "FastCalc" etc... + * The name *MUST* be less that 16 characters... + * If it is not, it will be trimmed... + * The name will also be UPPER-CASED... + * + * NOTE: The Default file name extension, if NULL will be + * "rexx" (the "." is automatic) + */ + AREXXCONTEXT InitARexx(char *,char *); + + /* + * This function returns the port name of your ARexx port. + * It will return NULL if there is no ARexx port... + * + * This string is *READ ONLY* You *MUST NOT* modify it... + */ + char *ARexxName(AREXXCONTEXT); + + /* + * This function returns the signal mask that the Rexx port is + * using. It returns NULL if there is no signal... + * + * Use this signal bit in your Wait() loop... + */ + ULONG ARexxSignal(AREXXCONTEXT); + + /* + * This function returns a structure that contains the commands sent from + * ARexx... You will need to parse it and return the structure back + * so that the memory can be freed... + * + * This returns NULL if there was no message... + */ + struct RexxMsg *GetARexxMsg(AREXXCONTEXT); + + /* Use this to delete a message sent via SendARexxMsg and that has now been + returned to you. + */ + void DeleteARexxMsg(AREXXCONTEXT RexxContext, struct RexxMsg *rmsg); + + /* + * Use this to return a ARexx message... + * + * If you wish to return something, it must be in the RString. + * If you wish to return an Error, it must be in the Error. + */ + void ReplyARexxMsg(AREXXCONTEXT,struct RexxMsg *,char *,LONG); + + /* + * This function will send a string to ARexx... + * + * The default host port will be that of your task... + * + * If you set StringFile to TRUE, it will set that bit for the message... + * + * Returns the message sent, or NULL in case of error. + */ + struct RexxMsg *SendARexxMsg(AREXXCONTEXT,char *,short,short); + + /* + * This function will set an error string for the ARexx + * application in the variable defined as .LASTERROR + * + * Note that this can only happen if there is an ARexx message... + * + * This returns TRUE if it worked, FALSE if it did not... + */ + short SetARexxLastError(AREXXCONTEXT,struct RexxMsg *,char *); + + #endif /* SIMPLE_REXX_H */ diff -rcP emacs-18.59-fsf/src/smakefile emacs-18.59-amiga/src/smakefile *** emacs-18.59-fsf/src/smakefile Thu Jan 1 00:00:00 1970 --- emacs-18.59-amiga/src/smakefile Sat Dec 5 16:43:56 1992 *************** *** 0 **** --- 1,45 ---- + CPP = /cpp/cpp -DAMIGA + MAKE = smake # BSD doesn't have it as a default. + #Note: an alternative is CPP = /lib/cpp + + all: xmakefile doall + + doall: + $(MAKE) $(MAKEOVERRIDES) -f xmakefile ${MFLAGS} all + + #This is used in making a distribution. + #Do not use it on development directories! + distclean: + -delete force paths.h config.h emacs-* temacs xemacs xmakefile \ + *! @* *.o + + clean: + -delete force temacs xemacs xmakefile @* *.o + + xemacs: xmakefile doxemacs + + doxemacs: + $(MAKE) $(MAKEOVERRIDES) -f xmakefile ${MFLAGS} xemacs + + temacs: xmakefile dotemacs + + dotemacs: + $(MAKE) $(MAKEOVERRIDES) -f xmakefile ${MFLAGS} temacs + + demacs: xmakefile dodemacs + + dodemacs: + $(MAKE) $(MAKEOVERRIDES) -f xmakefile ${MFLAGS} demacs + + # If you have a problem with cc -E here, changing + # the definition of CPP above may fix it. + xmakefile: ymakefile config.h dostrip + -delete force xmakefile + ${CPP} ymakefile > t:ymkf + dostrip xmakefile + + dostrip: dostrip.c + sc link dostrip + + tags: + etags [a-z]*.h [a-z]*.c /lisp/[a-z]*.el diff -rcP emacs-18.59-fsf/src/term.c emacs-18.59-amiga/src/term.c *** emacs-18.59-fsf/src/term.c Fri Jan 3 07:46:47 1992 --- emacs-18.59-amiga/src/term.c Sun Nov 22 10:18:02 1992 *************** *** 161,167 **** or'd with 0100. Zero if no standout marker at all. */ /* used iff TN_standout_width >= 0. */ char *chars_wasted; ! static char *copybuf; /* nonzero means supposed to write text in standout mode. */ int standout_requested; --- 161,167 ---- or'd with 0100. Zero if no standout marker at all. */ /* used iff TN_standout_width >= 0. */ char *chars_wasted; ! char *copybuf; /* nonzero means supposed to write text in standout mode. */ int standout_requested; diff -rcP emacs-18.59-fsf/src/termcap.c emacs-18.59-amiga/src/termcap.c *** emacs-18.59-fsf/src/termcap.c Tue Jan 8 18:08:50 1991 --- emacs-18.59-amiga/src/termcap.c Sun Nov 22 10:18:04 1992 *************** *** 30,35 **** --- 30,36 ---- #ifdef emacs #include "config.h" + #include "paths.h" #endif #ifndef BUFSIZE *************** *** 344,350 **** --- 345,355 ---- #ifdef VMS filep = tem && legal_filename_p (tem); #else + #ifdef AMIGA + filep = tem != 0; /* Always assume that it is a file */ + #else filep = tem && (*tem == '/'); + #endif #endif /* VMS */ /* If tem is non-null and starts with / (in the un*x case, that is), *************** *** 374,384 **** indirect = (char *) 0; if (!tem) ! #ifdef VMS ! tem = "emacs_library:[etc]termcap.dat"; ! #else ! tem = "/etc/termcap"; ! #endif /* Here we know we must search a file and tem has its name. */ --- 379,385 ---- indirect = (char *) 0; if (!tem) ! tem = PATH_TERMCAP; /* Here we know we must search a file and tem has its name. */ diff -rcP emacs-18.59-fsf/src/tparam.c emacs-18.59-amiga/src/tparam.c *** emacs-18.59-fsf/src/tparam.c Tue Jan 8 18:09:27 1991 --- emacs-18.59-amiga/src/tparam.c Sun Nov 22 10:18:10 1992 *************** *** 258,264 **** return outstring; } ! #ifdef DEBUG main (argc, argv) int argc; --- 258,264 ---- return outstring; } ! #ifdef TPARAM_DEBUG main (argc, argv) int argc; *************** *** 274,277 **** return 0; } ! #endif /* DEBUG */ --- 274,277 ---- return 0; } ! #endif /* TPARAM_DEBUG */ diff -rcP emacs-18.59-fsf/src/xdisp.c emacs-18.59-amiga/src/xdisp.c *** emacs-18.59-fsf/src/xdisp.c Fri Jul 24 19:08:13 1992 --- emacs-18.59-amiga/src/xdisp.c Sun Nov 22 10:19:14 1992 *************** *** 31,36 **** --- 31,47 ---- #include "commands.h" #include "macros.h" + #define MAX_WIN_LINE 64 + static int win_line_bufpos[MAX_WIN_LINE]; + static int win_line_modified; + static struct buffer *win_line_buffer; + #define CLEAR_WIN_LINE() (win_line_buffer = 0) + + #ifdef EIGHT_BIT + char visible[256]; /* visible[i] is true if character i is + displayable */ + #endif + extern int interrupt_input; extern int command_loop_level; *************** *** 275,281 **** windows_or_buffers_changed++; if (EQ (minibuf_window, selected_window)) ! this_line_bufpos = 0; prev_echo_area_contents = echo_area_contents; } --- 286,295 ---- windows_or_buffers_changed++; if (EQ (minibuf_window, selected_window)) ! { ! this_line_bufpos = 0; ! CLEAR_WIN_LINE(); ! } prev_echo_area_contents = echo_area_contents; } *************** *** 327,332 **** --- 341,348 ---- must_finish = 1; } + if (windows_or_buffers_changed) CLEAR_WIN_LINE(); + if (clip_changed || windows_or_buffers_changed) update_mode_lines++; *************** *** 453,458 **** --- 469,475 ---- Also, don't forget to check every line to update the arrow. */ if (pause) { + CLEAR_WIN_LINE(); this_line_bufpos = 0; if (!NULL (last_arrow_position)) { *************** *** 709,717 **** && (just_this_one || XFASTINT (w->width) == screen_width) && !EQ (window, minibuf_window)) { ! pos = *compute_motion (startp, 0, (hscroll ? 1 - hscroll : 0), point, height + 1, 10000, width, hscroll, ! pos_tab_offset (w, startp)); if (pos.vpos < height) { --- 726,754 ---- && (just_this_one || XFASTINT (w->width) == screen_width) && !EQ (window, minibuf_window)) { ! int *wlb; ! int line, best_startp, best_vpos; ! ! best_startp = startp; best_vpos = 0; ! if (win_line_buffer && BUF_MODIFF(win_line_buffer) > win_line_modified) ! CLEAR_WIN_LINE(); ! if (current_buffer == win_line_buffer && current_buffer == XBUFFER (w->buffer)) ! { ! /* Try & find line to start from */ ! wlb = win_line_bufpos; line = 0; ! while (line < MAX_WIN_LINE) ! { ! if (*wlb && point > *wlb && *wlb > best_startp) ! { ! best_startp = *wlb; ! best_vpos = line; ! } ! line++; wlb++; ! } ! } ! pos = *compute_motion (best_startp, best_vpos, (hscroll ? 1 - hscroll : 0), point, height + 1, 10000, width, hscroll, ! pos_tab_offset (w, best_startp)); if (pos.vpos < height) { *************** *** 843,848 **** --- 880,887 ---- struct position val; + if (XBUFFER(w->buffer) == win_line_buffer) CLEAR_WIN_LINE(); + Fset_marker (w->start, make_number (pos), Qnil); point_vpos = -1; *************** *** 908,913 **** --- 947,954 ---- int delta; int tab_offset, epto; + if (XBUFFER(w->buffer) == win_line_buffer) CLEAR_WIN_LINE(); + if (GPT - BEG < beg_unchanged) beg_unchanged = GPT - BEG; if (Z - GPT < end_unchanged) *************** *** 1334,1339 **** --- 1375,1381 ---- pause = pos; while (p1 < endp) { + restart: p1prev = p1; if (pos == pause) { *************** *** 1354,1366 **** p = &FETCH_CHAR (pos); } c = *p++; if (c >= 040 && c < 0177) ! { if (p1 >= startp) ! *p1 = c; ! p1++; ! } ! else if (c == '\n') { invis = 0; while (pos < end --- 1396,1439 ---- p = &FETCH_CHAR (pos); } c = *p++; + #ifdef EIGHT_BIT + if (visible[c]) + #else if (c >= 040 && c < 0177) ! #endif ! /* This optimises the frequent part (displayable characters) of ! this inner loop. If the conditions aren't met, return to old ! inner loop. */ ! { if (p1 >= startp) ! { ! do ! { ! *p1++ = c; ! pos++; ! if (p1 >= endp) ! { ! p1prev = p1 - 1; ! goto done; ! } ! if (pos == pause) goto restart; ! c = *p++; ! } ! #ifdef EIGHT_BIT ! while (visible[c]); ! #else ! while (c >= 040 && c < 0177); ! #endif ! p1prev = p1; ! } ! else ! { ! p1++; ! pos++; ! goto restart; ! } ! } ! if (c == '\n') { invis = 0; while (pos < end *************** *** 1434,1439 **** --- 1507,1513 ---- } pos++; } + done: val.hpos = - XINT (w->hscroll); if (val.hpos) *************** *** 1525,1530 **** --- 1599,1623 ---- this_line_bufpos = 0; } } + /* Save positions of all lines of current window */ + if (w == XWINDOW(selected_window) && vpos < MAX_WIN_LINE) + { + /* Line is not continued and did not start in middle of character */ + if (hpos == (XINT (w->hscroll) ? 1 - XINT (w->hscroll) : 0) + && val.vpos) + { + if (current_buffer != win_line_buffer || + !(win_line_modified >= MODIFF)) + { + win_line_buffer = current_buffer; + win_line_modified = MODIFF; + bzero(win_line_bufpos, sizeof win_line_bufpos); + } + win_line_bufpos[vpos - XINT (w->top)] = start; + } + else + win_line_bufpos[vpos - XINT (w->top)] = 0; + } /* If hscroll and line not empty, insert truncation-at-left marker */ if (hscroll && lastpos != start) *************** *** 1994,2000 **** --- 2087,2097 ---- { c = *string++; if (!c) break; + #ifdef EIGHT_BIT + if (visible[c]) + #else if (c >= 040 && c < 0177) + #endif { if (p1 >= start) *p1 = c; *************** *** 2109,2115 **** --- 2206,2216 ---- register #endif COMPILER_REGISTER_BUG struct window *mini_w; + #ifdef EIGHT_BIT + int i; + #endif + CLEAR_WIN_LINE(); this_line_bufpos = 0; mini_w = XWINDOW (minibuf_window); *************** *** 2128,2131 **** --- 2229,2238 ---- XFASTINT (XWINDOW (root_window)->width) = screen_width; XFASTINT (mini_w->width) = screen_width; } + #ifdef EIGHT_BIT + for (i = 040; i < 0177; i++) visible[i] = 1; + #ifdef AMIGA + for (i = 0240; i <= 0377; i++) visible[i] = 1; + #endif + #endif } diff -rcP emacs-18.59-fsf/src/ymakefile emacs-18.59-amiga/src/ymakefile *** emacs-18.59-fsf/src/ymakefile Tue Oct 6 18:44:28 1992 --- emacs-18.59-amiga/src/ymakefile Thu Sep 30 20:52:04 1993 *************** *** 18,24 **** --- 18,32 ---- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + #ifdef amiga + #undef amiga + #endif + + #ifdef AMIGA + dot = + #else dot = . + #endif /* on Xenix, replace double-dot below with $(dot)$(dot) */ lispdir = $(dot)$(dot)/lisp/ etcdir = $(dot)$(dot)/etc/ *************** *** 161,167 **** #define LINKER gcc -nostdlib #else #define LINKER ld ! #endif #endif /* not ORDINARY_LINK */ #endif /* no LINKER */ --- 169,175 ---- #define LINKER gcc -nostdlib #else #define LINKER ld ! #endif #endif /* not ORDINARY_LINK */ #endif /* no LINKER */ *************** *** 191,197 **** --- 199,209 ---- SHORT= shortnames #endif /* SHORTNAMES */ + #ifdef AMIGA + CFLAGS= C_DEBUG_SWITCH def emacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM + #else CFLAGS= C_DEBUG_SWITCH -Demacs $(MYCPPFLAG) C_SWITCH_MACHINE C_SWITCH_SYSTEM C_SWITCH_X_MACHINE C_SWITCH_X_SYSTEM + #endif /* DO NOT use -R. There is a special hack described in lastfile.c which is used instead. Some initialized data areas are modified at initial startup, then labeled as part of the text area when *************** *** 258,264 **** GNULIB_VAR = `if [ -f LIB_GCC ] ; then echo LIB_GCC; else echo; fi` #endif /* __GNUC__ <= 1 */ #else ! GNULIB_VAR = #endif #ifdef MAINTAIN_ENVIRONMENT --- 270,276 ---- GNULIB_VAR = `if [ -f LIB_GCC ] ; then echo LIB_GCC; else echo; fi` #endif /* __GNUC__ <= 1 */ #else ! GNULIB_VAR = #endif #ifdef MAINTAIN_ENVIRONMENT *************** *** 270,280 **** #define UNEXEC unexec.o #endif /* lastfile must follow all files whose initialized data areas should be dumped as pure by dump-emacs. */ obj= dispnew.o scroll.o xdisp.o window.o \ ! term.o cm.o $(XOBJ) \ ! emacs.o keyboard.o macros.o keymap.o sysdep.o \ buffer.o filelock.o insdel.o marker.o \ minibuf.o fileio.o dired.o filemode.o \ cmds.o casefiddle.o indent.o search.o regex.o undo.o \ --- 282,300 ---- #define UNEXEC unexec.o #endif + termobjs= term.o cm.o + + #ifdef AMIGA + SYSDEP= amiga_sysdep.o + #else + SYSDEP= sysdep.o + #endif + /* lastfile must follow all files whose initialized data areas should be dumped as pure by dump-emacs. */ obj= dispnew.o scroll.o xdisp.o window.o \ ! $(termobjs) $(XOBJ) \ ! emacs.o keyboard.o macros.o keymap.o $(SYSDEP) \ buffer.o filelock.o insdel.o marker.o \ minibuf.o fileio.o dired.o filemode.o \ cmds.o casefiddle.o indent.o search.o regex.o undo.o \ *************** *** 360,376 **** --- 380,422 ---- #ifdef CANNOT_DUMP mv temacs xemacs #else + #ifdef AMIGA + -delete ${etcdir}EMACS-DATA xemacs force + temacs -nl -batch -l inc-vers + temacs -nl -batch -l loadup.el dump + -touch xemacs + -delete /temacs force + makelink from /temacs temacs + #else ./temacs -batch -l inc-vers ./temacs -batch -l loadup.el dump + #endif /* not AMIGA */ #endif /* not CANNOT_DUMP */ #endif /* not HAVE_SHM */ ${etcdir}DOC: ${etcdir}make-docfile ${obj} ${lisp} + #ifdef AMIGA + REDIRECT_IN= < + -delete force ${etcdir}DOC + ${etcdir}make-docfile >${etcdir}DOC $(REDIRECT_IN) < < + ${obj} + ${lisp} + ${lispdir}version.el + ${lispdir}amiga-menu.elc ${lispdir}amiga-init.elc ${lispdir}amiga-mouse.elc + OBJECTS_SYSTEM + < + #else rm -f ${etcdir}DOC ${etcdir}make-docfile ${obj} ${lisp} ${lispdir}version.el > ${etcdir}DOC + #endif + #ifdef AMIGA + ${etcdir}make-docfile: ${etcdir}make-docfile.c + sc link /etc/make-docfile + #else ${etcdir}make-docfile: cd ${etcdir}; ${MAKE} ${MFLAGS} make-docfile + #endif /* Some systems define this to cause parallel Make-ing. */ #ifndef MAKE_PARALLEL *************** *** 378,384 **** --- 424,453 ---- #endif temacs: MAKE_PARALLEL $(LOCALCPP) $(SHORT) $(STARTFILES) $(OLDXMENU) ${obj} ${otherobj} OBJECTS_SYSTEM OBJECTS_MACHINE + #ifdef AMIGA + slink