Annotation of 43BSD/contrib/emacs/src/fns.c, revision 1.1

1.1     ! root        1: /* Random utility Lisp functions.
        !             2:    Copyright (C) 1985 Richard M. Stallman.
        !             3: 
        !             4: This file is part of GNU Emacs.
        !             5: 
        !             6: GNU Emacs is distributed in the hope that it will be useful,
        !             7: but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: accepts responsibility to anyone for the consequences of using it
        !             9: or for whether it serves any particular purpose or works at all,
        !            10: unless he says so in writing.  Refer to the GNU Emacs General Public
        !            11: License for full details.
        !            12: 
        !            13: Everyone is granted permission to copy, modify and redistribute
        !            14: GNU Emacs, but only under the conditions described in the
        !            15: GNU Emacs General Public License.   A copy of this license is
        !            16: supposed to have been given to you along with GNU Emacs so you
        !            17: can know your rights and responsibilities.  It should be in a
        !            18: file named COPYING.  Among other things, the copyright notice
        !            19: and this notice must be preserved on all copies.  */
        !            20: 
        !            21: 
        !            22: #include "config.h"
        !            23: 
        !            24: /* Define two macros KERNEL_FILE (file to find kernel symtab in)
        !            25:    and LDAV_SYMBOL (symbol name to look for), based on system type.
        !            26:    Also define NLIST_STRUCT if the type `nlist' is a structure we
        !            27:    can get from nlist.h; otherwise must use a.out.h and initialize
        !            28:    with strcpy.  Note that config.h may define NLIST_STRUCT
        !            29:    for more modrern USG systems.  */
        !            30: 
        !            31: #ifdef USG
        !            32: #ifdef HPUX
        !            33: #define LDAV_SYMBOL "_avenrun"
        !            34: #define KERNEL_FILE "/hp-ux"
        !            35: #define NLIST_STRUCT
        !            36: #else /* not HPUX */
        !            37: #define LDAV_SYMBOL "avenrun"
        !            38: #define KERNEL_FILE "/unix"
        !            39: #endif /* not HPUX */
        !            40: #else /* not USG */
        !            41: #define LDAV_SYMBOL "_avenrun"
        !            42: #define NLIST_STRUCT
        !            43: #ifndef KERNEL_FILE
        !            44: #define KERNEL_FILE "/vmunix"
        !            45: #endif /* no KERNEL_FILE yet */
        !            46: #endif /* not USG */
        !            47: 
        !            48: #ifdef LOAD_AVE_TYPE
        !            49: #ifdef BSD
        !            50: #include <sys/param.h>
        !            51: #endif /* BSD */
        !            52: #ifndef eunice
        !            53: #ifndef NLIST_STRUCT
        !            54: #include <a.out.h> 
        !            55: #else /* NLIST_STRUCT */
        !            56: #include <nlist.h>
        !            57: #endif /* NLIST_STRUCT */
        !            58: #endif /* not eunice */
        !            59: #endif /* LOAD_AVE_TYPE */
        !            60: 
        !            61: #undef NULL
        !            62: #include "lisp.h"
        !            63: #include "commands.h"
        !            64: 
        !            65: #ifdef lint
        !            66: #include "buffer.h"
        !            67: #endif /* lint */
        !            68: 
        !            69: Lisp_Object Qstring_lessp;
        !            70: 
        !            71: DEFUN ("identity", Fidentity, Sidentity, 1, 1, 0,
        !            72:   "Return the argument unchanged.")
        !            73:   (arg)
        !            74:      Lisp_Object arg;
        !            75: {
        !            76:   return arg;
        !            77: }
        !            78: 
        !            79: DEFUN ("random", Frandom, Srandom, 0, 1, 0,
        !            80:   "Return a pseudo-random number.\n\
        !            81: On most systems all integers representable in Lisp are equally likely.\n\
        !            82:   This is 24 bits' worth.\n\
        !            83: If optional argument is supplied as  t,\n\
        !            84:  the random number seed is set based on the current time and pid.")
        !            85:   (arg)
        !            86:      Lisp_Object arg;
        !            87: {
        !            88:   extern long random ();
        !            89:   extern srandom ();
        !            90:   extern long time ();
        !            91: 
        !            92:   if (EQ (arg, Qt))
        !            93:     srandom (getpid () + time (0));
        !            94:   return make_number ((int) random ());
        !            95: }
        !            96: 
        !            97: /* Random data-structure functions */
        !            98: 
        !            99: DEFUN ("length", Flength, Slength, 1, 1, 0,
        !           100:   "Return the length of vector, list or string SEQUENCE.")
        !           101:   (obj)
        !           102:      register Lisp_Object obj;
        !           103: {
        !           104:   register Lisp_Object tail, val;
        !           105:   register int i;
        !           106: 
        !           107:  retry:
        !           108:   if (XTYPE (obj) == Lisp_Vector || XTYPE (obj) == Lisp_String)
        !           109:     return Farray_length (obj);
        !           110:   else if (LISTP(obj))
        !           111:     {
        !           112:       for (i = 0, tail = obj; !NULL(tail); i++)
        !           113:        {
        !           114:          QUIT;
        !           115:          tail = Fcdr (tail);
        !           116:        }
        !           117: 
        !           118:       XFASTINT (val) = i;
        !           119:       return val;
        !           120:     }
        !           121:   else if (NULL(obj))
        !           122:     {
        !           123:       XFASTINT (val) = 0;
        !           124:       return val;
        !           125:     }
        !           126:   else
        !           127:     {
        !           128:       obj = wrong_type_argument (Qsequencep, obj);
        !           129:       goto retry;
        !           130:     }
        !           131: }
        !           132: 
        !           133: DEFUN ("string-equal", Fstring_equal, Sstring_equal, 2, 2, 0,
        !           134:   "T if two strings have identical contents.\n\
        !           135: Symbols are also allowed; their print names are used instead.")
        !           136:   (s1, s2)
        !           137:      register Lisp_Object s1, s2;
        !           138: {
        !           139:   if (XTYPE (s1) == Lisp_Symbol)
        !           140:     XSETSTRING (s1, XSYMBOL (s1)->name), XSETTYPE (s1, Lisp_String);
        !           141:   if (XTYPE (s2) == Lisp_Symbol)
        !           142:     XSETSTRING (s2, XSYMBOL (s2)->name), XSETTYPE (s2, Lisp_String);
        !           143:   CHECK_STRING (s1, 0);
        !           144:   CHECK_STRING (s2, 1);
        !           145: 
        !           146:   if (XSTRING (s1)->size != XSTRING (s2)->size ||
        !           147:       bcmp (XSTRING (s1)->data, XSTRING (s2)->data, XSTRING (s1)->size))
        !           148:     return Qnil;
        !           149:   return Qt;
        !           150: }
        !           151: 
        !           152: DEFUN ("string-lessp", Fstring_lessp, Sstring_lessp, 2, 2, 0,
        !           153:   "T if first arg string is less than second in lexicographic order.\n\
        !           154: Symbols are also allowed; their print names are used instead.")
        !           155:   (s1, s2)
        !           156:      register Lisp_Object s1, s2;
        !           157: {
        !           158:   register int i;
        !           159:   register unsigned char *p1, *p2;
        !           160:   register int end;
        !           161: 
        !           162:   if (XTYPE (s1) == Lisp_Symbol)
        !           163:     XSETSTRING (s1, XSYMBOL (s1)->name), XSETTYPE (s1, Lisp_String);
        !           164:   if (XTYPE (s2) == Lisp_Symbol)
        !           165:     XSETSTRING (s2, XSYMBOL (s2)->name), XSETTYPE (s2, Lisp_String);
        !           166:   CHECK_STRING (s1, 0);
        !           167:   CHECK_STRING (s2, 1);
        !           168: 
        !           169:   p1 = XSTRING (s1)->data;
        !           170:   p2 = XSTRING (s2)->data;
        !           171:   end = XSTRING (s1)->size;
        !           172:   if (end > XSTRING (s2)->size)
        !           173:     end = XSTRING (s2)->size;
        !           174: 
        !           175:   for (i = 0; i < end; i++)
        !           176:     {
        !           177:       if (p1[i] != p2[i])
        !           178:        return p1[i] < p2[i] ? Qt : Qnil;
        !           179:     }
        !           180:   return i < XSTRING (s2)->size ? Qt : Qnil;
        !           181: }
        !           182: 
        !           183: static Lisp_Object concat ();
        !           184: 
        !           185: /* ARGSUSED */
        !           186: Lisp_Object
        !           187: concat2 (s1, s2)
        !           188:      Lisp_Object s1, s2;
        !           189: {
        !           190: #ifdef NO_ARG_ARRAY
        !           191:   Lisp_Object args[2];
        !           192:   args[0] = s1;
        !           193:   args[1] = s2;
        !           194:   return concat (2, args, Lisp_String, 0);
        !           195: #else
        !           196:   return concat (2, &s1, Lisp_String, 0);
        !           197: #endif /* NO_ARG_ARRAY */
        !           198: }
        !           199: 
        !           200: DEFUN ("append", Fappend, Sappend, 0, MANY, 0,
        !           201:   "Concatenate arguments and make the result a list.\n\
        !           202: The result is a list whose elements are the elements of all the arguments.\n\
        !           203: Each argument may be a list, vector or string.")
        !           204:   (nargs, args)
        !           205:      int nargs;
        !           206:      Lisp_Object *args;
        !           207: {
        !           208:   return concat (nargs, args, Lisp_Cons, 1);
        !           209: }
        !           210: 
        !           211: DEFUN ("concat", Fconcat, Sconcat, 0, MANY, 0,
        !           212:   "Concatenate arguments and make the result a string.\n\
        !           213: The result is a string whose elements are the elements of all the arguments.\n\
        !           214: Each argument may be a list, vector or string; but all elements\n\
        !           215: of a list or vector must be numbers, or an error is signaled.")
        !           216:   (nargs, args)
        !           217:      int nargs;
        !           218:      Lisp_Object *args;
        !           219: {
        !           220:   return concat (nargs, args, Lisp_String, 0);
        !           221: }
        !           222: 
        !           223: DEFUN ("vconcat", Fvconcat, Svconcat, 0, MANY, 0,
        !           224:   "Concatenate arguments and make the result a vector.\n\
        !           225: The result is a list whose elements are the elements of all the arguments.\n\
        !           226: Each argument may be a list, vector or string.")
        !           227:   (nargs, args)
        !           228:      int nargs;
        !           229:      Lisp_Object *args;
        !           230: {
        !           231:   return concat (nargs, args, Lisp_Vector, 0);
        !           232: }
        !           233: 
        !           234: DEFUN ("copy-sequence", Fcopy_sequence, Scopy_sequence, 1, 1, 0,
        !           235:   "Return a copy of a list, vector or string.")
        !           236:   (arg)
        !           237:      Lisp_Object arg;
        !           238: {
        !           239:   if (NULL (arg)) return arg;
        !           240:   if (!LISTP (arg) && XTYPE (arg) != Lisp_Vector && XTYPE (arg) != Lisp_String)
        !           241:     arg = wrong_type_argument (Qsequencep, arg);
        !           242:   return concat (1, &arg, LISTP (arg) ? Lisp_Cons : XTYPE (arg), 0);
        !           243: }
        !           244: 
        !           245: static Lisp_Object
        !           246: concat (nargs, args, target_type, last_special)
        !           247:      int nargs;
        !           248:      Lisp_Object *args;
        !           249:      enum Lisp_Type target_type;
        !           250:      int last_special;
        !           251: {
        !           252:   Lisp_Object val;
        !           253:   Lisp_Object len;
        !           254:   register Lisp_Object tail;
        !           255:   register Lisp_Object this;
        !           256:   int toindex;
        !           257:   register int leni;
        !           258:   register int argnum;
        !           259:   Lisp_Object last_tail;
        !           260:   Lisp_Object prev;
        !           261: 
        !           262:   /* In append, the last arg isn't treated like the others */
        !           263:   if (last_special && nargs > 0)
        !           264:     {
        !           265:       nargs--;
        !           266:       last_tail = args[nargs];
        !           267:     }
        !           268:   else
        !           269:     last_tail = Qnil;
        !           270: 
        !           271:   for (argnum = 0; argnum < nargs; argnum++)
        !           272:     {
        !           273:       this = args[argnum];
        !           274:       if (!(LISTP (this) || NULL (this)
        !           275:           || XTYPE (this) == Lisp_Vector || XTYPE (this) == Lisp_String))
        !           276:        {
        !           277:          if (XTYPE (this) == Lisp_Int)
        !           278:             args[argnum] = Fint_to_string (this);
        !           279:          else
        !           280:            args[argnum] = wrong_type_argument (Qsequencep, this);
        !           281:        }
        !           282:     }
        !           283: 
        !           284:   for (argnum = 0, leni = 0; argnum < nargs; argnum++)
        !           285:     {
        !           286:       this = args[argnum];
        !           287:       len = Flength (this);
        !           288:       leni += XFASTINT (len);
        !           289:     }
        !           290: 
        !           291:   XFASTINT (len) = leni;
        !           292: 
        !           293:   if (target_type == Lisp_Cons)
        !           294:     val = Fmake_list (len, Qnil);
        !           295:   else if (target_type == Lisp_Vector)
        !           296:     val = Fmake_vector (len, Qnil);
        !           297:   else
        !           298:     val = Fmake_string (len, len);
        !           299: 
        !           300:   /* In append, if all but last arg are nil, return last arg */
        !           301:   if (target_type == Lisp_Cons && EQ (val, Qnil))
        !           302:     return last_tail;
        !           303: 
        !           304:   if (LISTP (val))
        !           305:     tail = val, toindex = -1;          /* -1 in toindex is flag we are making a list */
        !           306:   else
        !           307:     toindex = 0;
        !           308: 
        !           309:   prev = Qnil;
        !           310: 
        !           311:   for (argnum = 0; argnum < nargs; argnum++)
        !           312:     {
        !           313:       Lisp_Object thislen;
        !           314:       int thisleni;
        !           315:       register int thisindex = 0;
        !           316: 
        !           317:       this = args[argnum];
        !           318:       if (!LISTP (this))
        !           319:        thislen = Flength (this), thisleni = XINT (thislen);
        !           320: 
        !           321:       while (1)
        !           322:        {
        !           323:          register Lisp_Object elt;
        !           324: 
        !           325:          /* Fetch next element of `this' arg into `elt', or break if `this' is exhausted. */
        !           326:          if (NULL (this)) break;
        !           327:          if (LISTP (this))
        !           328:            elt = Fcar (this), this = Fcdr (this);
        !           329:          else
        !           330:            {
        !           331:              if (thisindex >= thisleni) break;
        !           332:              if (XTYPE (this) == Lisp_String)
        !           333:                XFASTINT (elt) = XSTRING (this)->data[thisindex++];
        !           334:              else
        !           335:                elt = XVECTOR (this)->contents[thisindex++];
        !           336:            }
        !           337: 
        !           338:          /* Store into result */
        !           339:          if (toindex < 0)
        !           340:            {
        !           341:              XCONS (tail)->car = elt;
        !           342:              prev = tail;
        !           343:              tail = XCONS (tail)->cdr;
        !           344:            }
        !           345:          else if (XTYPE (val) == Lisp_Vector)
        !           346:            XVECTOR (val)->contents[toindex++] = elt;
        !           347:          else
        !           348:            {
        !           349:              if (XTYPE (elt) != Lisp_Int)
        !           350:                elt = wrong_type_argument (Qintegerp, elt);
        !           351:              else
        !           352:                XSTRING (val)->data[toindex++] = XINT (elt);
        !           353:            }
        !           354:        }
        !           355:     }
        !           356:   if (!NULL (prev))
        !           357:     XCONS (prev)->cdr = last_tail;
        !           358: 
        !           359:   return val;  
        !           360: }
        !           361: 
        !           362: DEFUN ("substring", Fsubstring, Ssubstring, 2, 3, 0,
        !           363:   "Return a substring of STRING, starting at index FROM and reaching until TO.\n\
        !           364: TO may be nil or omitted; then the substring runs to the end of STRING.\n\
        !           365: If FROM or TO is negative, it counts from the end.")
        !           366:   (string, from, to)
        !           367:      Lisp_Object string;
        !           368:      register Lisp_Object from, to;
        !           369: {
        !           370:   register Lisp_Object val, len;
        !           371: 
        !           372:   CHECK_STRING (string, 0);
        !           373:   CHECK_NUMBER (from, 1);
        !           374:   if (NULL (to))
        !           375:     to = Flength (string);
        !           376:   else
        !           377:     CHECK_NUMBER (to, 2);
        !           378: 
        !           379:   if (XINT (from) < 0)
        !           380:     XSETINT (from, XINT (from) + XSTRING (string)->size);
        !           381:   if (XINT (to) < 0)
        !           382:     XSETINT (to, XINT (to) + XSTRING (string)->size);
        !           383:   if (!(0 <= XINT (from) && XINT (from) <= XINT (to)
        !           384:         && XINT (to) <= XSTRING (string)->size))
        !           385:     args_out_of_range_3 (string, from, to);
        !           386: 
        !           387:   XFASTINT (len) = XINT (to) - XINT (from);
        !           388:   val = Fmake_string (len, len);
        !           389: 
        !           390:   bcopy (XSTRING (string)->data + XINT (from), XSTRING (val)->data, XINT (len));
        !           391: 
        !           392:   return val;
        !           393: }
        !           394: 
        !           395: DEFUN ("nthcdr", Fnthcdr, Snthcdr, 2, 2, 0,
        !           396:   "Takes cdr N times on LIST, returns the result.")
        !           397:   (n, list)
        !           398:      Lisp_Object n;
        !           399:      register Lisp_Object list;
        !           400: {
        !           401:   register int i, num;
        !           402:   CHECK_NUMBER (n, 0);
        !           403:   num = XINT (n);
        !           404:   for (i = 0; i < num; i++)
        !           405:     {
        !           406:       QUIT;
        !           407:       list = Fcdr (list);
        !           408:     }
        !           409:   return list;
        !           410: }
        !           411: 
        !           412: DEFUN ("nth", Fnth, Snth, 2, 2, 0,
        !           413:   "Returns the Nth element of LIST.\n\
        !           414: N counts from zero.  If LIST is not that long, nil is returned.")
        !           415:   (n, list)
        !           416:      Lisp_Object n, list;
        !           417: {
        !           418:   CHECK_NUMBER (n, 0);
        !           419:   if (!(XTYPE (list) == Lisp_Cons || NULL (list)))
        !           420:     list = wrong_type_argument (Qlistp, list);
        !           421:   return Fcar (Fnthcdr (n, list));
        !           422: }
        !           423: 
        !           424: DEFUN ("elt", Felt, Selt, 2, 2, 0,
        !           425:   "Returns element of SEQUENCE at index N.")
        !           426:   (seq, n)
        !           427:      register Lisp_Object seq, n;
        !           428: {
        !           429:   CHECK_NUMBER (n, 0);
        !           430:   while (1)
        !           431:     {
        !           432:       if (XTYPE (seq) == Lisp_Cons || NULL (seq))
        !           433:        return Fcar (Fnthcdr (n, seq));
        !           434:       else if (XTYPE (seq) == Lisp_String ||
        !           435:               XTYPE (seq) == Lisp_Vector)
        !           436:        return Faref (seq, n);
        !           437:       else
        !           438:        seq = wrong_type_argument (Qsequencep, seq);
        !           439:     }
        !           440: }
        !           441: 
        !           442: DEFUN ("memq", Fmemq, Smemq, 2, 2, 0,
        !           443:   "Returns non-nil if ELT is an element of LIST.  Comparison done with EQ.\n\
        !           444: The value is actually the tail of LIST whose car is ELT.")
        !           445:   (elt, list)
        !           446:      register Lisp_Object elt;
        !           447:      Lisp_Object list;
        !           448: {
        !           449:   register Lisp_Object tail;
        !           450:   for (tail = list; !NULL (tail); tail = Fcdr (tail))
        !           451:     {
        !           452:       register Lisp_Object tem;
        !           453:       tem = Fcar (tail);
        !           454:       if (EQ (elt, tem)) return tail;
        !           455:       QUIT;
        !           456:     }
        !           457:   return Qnil;
        !           458: }
        !           459: 
        !           460: DEFUN ("assq", Fassq, Sassq, 2, 2, 0,
        !           461:   "Returns non-nil if ELT is the car of an element of LIST.  Comparison done with eq.\n\
        !           462: The value is actually the element of LIST whose car is ELT.")
        !           463:   (key, list)
        !           464:      register Lisp_Object key;
        !           465:      Lisp_Object list;
        !           466: {
        !           467:   register Lisp_Object tail;
        !           468:   for (tail = list; !NULL (tail); tail = Fcdr (tail))
        !           469:     {
        !           470:       register Lisp_Object elt, tem;
        !           471:       elt = Fcar (tail);
        !           472:       if (!LISTP (elt)) continue;
        !           473:       tem = Fcar (elt);
        !           474:       if (EQ (key, tem)) return elt;
        !           475:       QUIT;
        !           476:     }
        !           477:   return Qnil;
        !           478: }
        !           479: 
        !           480: DEFUN ("assoc", Fassoc, Sassoc, 2, 2, 0,
        !           481:   "Returns non-nil if ELT is the car of an element of LIST.  Comparison done with  equal.\n\
        !           482: The value is actually the element of LIST whose car is ELT.")
        !           483:   (key, list)
        !           484:      register Lisp_Object key;
        !           485:      Lisp_Object list;
        !           486: {
        !           487:   register Lisp_Object tail;
        !           488:   for (tail = list; !NULL (tail); tail = Fcdr (tail))
        !           489:     {
        !           490:       register Lisp_Object elt, tem;
        !           491:       elt = Fcar (tail);
        !           492:       if (!LISTP (elt)) continue;
        !           493:       tem = Fequal (Fcar (elt), key);
        !           494:       if (!NULL (tem)) return elt;
        !           495:       QUIT;
        !           496:     }
        !           497:   return Qnil;
        !           498: }
        !           499: 
        !           500: DEFUN ("rassq", Frassq, Srassq, 2, 2, 0,
        !           501:   "Returns non-nil if ELT is the cdr of an element of LIST.  Comparison done with EQ.\n\
        !           502: The value is actually the element of LIST whose cdr is ELT.")
        !           503:   (key, list)
        !           504:      register Lisp_Object key;
        !           505:      Lisp_Object list;
        !           506: {
        !           507:   register Lisp_Object tail;
        !           508:   for (tail = list; !NULL (tail); tail = Fcdr (tail))
        !           509:     {
        !           510:       register Lisp_Object elt, tem;
        !           511:       elt = Fcar (tail);
        !           512:       if (!LISTP (elt)) continue;
        !           513:       tem = Fcdr (elt);
        !           514:       if (EQ (key, tem)) return elt;
        !           515:       QUIT;
        !           516:     }
        !           517:   return Qnil;
        !           518: }
        !           519: 
        !           520: DEFUN ("delq", Fdelq, Sdelq, 2, 2, 0,
        !           521:   "Deletes by side effect any occurrences of ELT as a member of LIST.\n\
        !           522: The modified LIST is returned.\n\
        !           523: If the first member of LIST is ELT, there is no way to remove it by side effect;\n\
        !           524: therefore, write  (setq foo (delq element foo))  to be sure of changing  foo.")
        !           525:   (elt, list)
        !           526:      register Lisp_Object elt;
        !           527:      Lisp_Object list;
        !           528: {
        !           529:   register Lisp_Object tail, prev;
        !           530:   register Lisp_Object tem;
        !           531: 
        !           532:   tail = list;
        !           533:   prev = Qnil;
        !           534:   while (!NULL (tail))
        !           535:     {
        !           536:       tem = Fcar (tail);
        !           537:       if (EQ (elt, tem))
        !           538:        {
        !           539:          if (NULL (prev))
        !           540:            list = Fcdr (tail);
        !           541:          else
        !           542:            Fsetcdr (prev, Fcdr (tail));
        !           543:        }
        !           544:       else
        !           545:        prev = tail;
        !           546:       tail = Fcdr (tail);
        !           547:       QUIT;
        !           548:     }
        !           549:   return list;
        !           550: }
        !           551: 
        !           552: DEFUN ("nreverse", Fnreverse, Snreverse, 1, 1, 0,
        !           553:   "Reverses LIST by modifying cdr pointers.  Returns the beginning of the reversed list.")
        !           554:   (list)
        !           555:      Lisp_Object list;
        !           556: {
        !           557:   register Lisp_Object prev, tail, next;
        !           558: 
        !           559:   if (NULL (list)) return list;
        !           560:   prev = Qnil;
        !           561:   tail = list;
        !           562:   while (!NULL (tail))
        !           563:     {
        !           564:       QUIT;
        !           565:       next = Fcdr (tail);
        !           566:       Fsetcdr (tail, prev);
        !           567:       prev = tail;
        !           568:       tail = next;
        !           569:     }
        !           570:   return prev;
        !           571: }
        !           572: 
        !           573: DEFUN ("reverse", Freverse, Sreverse, 1, 1, 0,
        !           574:   "Reverses LIST, copying.  Returns the beginning of the reversed list.")
        !           575:   (list)
        !           576:      Lisp_Object list;
        !           577: {
        !           578:   Lisp_Object length;
        !           579:   register Lisp_Object *vector;
        !           580:   register Lisp_Object tail;
        !           581:   register int i;
        !           582: 
        !           583:   length = Flength (list);
        !           584:   vector = (Lisp_Object *) alloca (XINT (length) * sizeof (Lisp_Object));
        !           585:   for (i = XINT (length) - 1, tail = list; i >= 0; i--, tail = Fcdr (tail))
        !           586:     vector[i] = Fcar (tail);
        !           587: 
        !           588:   return Flist (XINT (length), vector);
        !           589: }
        !           590: 
        !           591: Lisp_Object merge ();
        !           592: 
        !           593: DEFUN ("sort", Fsort, Ssort, 2, 2, 0,
        !           594:   "Sort LIST, stably, comparing elements using PREDICATE.\n\
        !           595: Returns the sorted list.  LIST is modified by side effects.\n\
        !           596: PREDICATE is called with two elements of LIST, and should return T\n\
        !           597: if the first element is \"less\" than the second.")
        !           598:   (list, pred)
        !           599:      Lisp_Object list, pred;
        !           600: {
        !           601:   Lisp_Object front, back;
        !           602:   register Lisp_Object len, tem;
        !           603:   struct gcpro gcpro1, gcpro2;
        !           604:   register int length;
        !           605: 
        !           606:   front = list;
        !           607:   len = Flength (list);
        !           608:   length = XINT (len);
        !           609:   if (length < 2)
        !           610:     return list;
        !           611: 
        !           612:   XSETINT (len, (length / 2) - 1);
        !           613:   tem = Fnthcdr (len, list);
        !           614:   back = Fcdr (tem);
        !           615:   Fsetcdr (tem, Qnil);
        !           616: 
        !           617:   GCPRO2 (front, back);
        !           618:   front = Fsort (front, pred);
        !           619:   back = Fsort (back, pred);
        !           620:   UNGCPRO;
        !           621:   return merge (front, back, pred);
        !           622: }
        !           623: 
        !           624: Lisp_Object
        !           625: merge (org_l1, org_l2, pred)
        !           626:      Lisp_Object org_l1, org_l2;
        !           627:      Lisp_Object pred;
        !           628: {
        !           629:   Lisp_Object value;
        !           630:   register Lisp_Object tail;
        !           631:   Lisp_Object tem;
        !           632:   register Lisp_Object l1, l2;
        !           633:   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
        !           634: 
        !           635:   l1 = org_l1;
        !           636:   l2 = org_l2;
        !           637:   tail = Qnil;
        !           638:   value = Qnil;
        !           639: 
        !           640:   /* It is sufficient to protect org_l1 and org_l2.
        !           641:      When l1 and l2 are updated, we copy the new values
        !           642:      back into the org_ vars.  */
        !           643:   GCPRO4 (org_l1, org_l2, pred, value);
        !           644: 
        !           645:   while (1)
        !           646:     {
        !           647:       if (NULL (l1))
        !           648:        {
        !           649:          UNGCPRO;
        !           650:          if (NULL (tail))
        !           651:            return l2;
        !           652:          Fsetcdr (tail, l2);
        !           653:          return value;
        !           654:        }
        !           655:       if (NULL (l2))
        !           656:        {
        !           657:          UNGCPRO;
        !           658:          if (NULL (tail))
        !           659:            return l1;
        !           660:          Fsetcdr (tail, l1);
        !           661:          return value;
        !           662:        }
        !           663:       tem = call2 (pred, Fcar (l1), Fcar (l2));
        !           664:       if (!NULL (tem))
        !           665:        {
        !           666:          tem = l1;
        !           667:          l1 = Fcdr (l1);
        !           668:          org_l1 = l1;
        !           669:        }
        !           670:       else
        !           671:        {
        !           672:          tem = l2;
        !           673:          l2 = Fcdr (l2);
        !           674:          org_l2 = l2;
        !           675:        }
        !           676:       if (NULL (tail))
        !           677:        value = tem;
        !           678:       else
        !           679:        Fsetcdr (tail, tem);
        !           680:       tail = tem;
        !           681:     }
        !           682: }
        !           683: 
        !           684: DEFUN ("get", Fget, Sget, 2, 2, 0,
        !           685:   "Return the value of SYMBOL's PROPNAME property.\n\
        !           686: This is the last VALUE stored with  (put SYMBOL PROPNAME VALUE).")
        !           687:   (sym, prop)
        !           688:      Lisp_Object sym;
        !           689:      register Lisp_Object prop;
        !           690: {
        !           691:   register Lisp_Object tail;
        !           692:   for (tail = Fsymbol_plist (sym); !NULL (tail); tail = Fcdr (Fcdr (tail)))
        !           693:     {
        !           694:       register Lisp_Object tem;
        !           695:       tem = Fcar (tail);
        !           696:       if (EQ (prop, tem))
        !           697:        return Fcar (Fcdr (tail));
        !           698:     }
        !           699:   return Qnil;
        !           700: }
        !           701: 
        !           702: DEFUN ("put", Fput, Sput, 3, 3, 0,
        !           703:   "Store SYMBOL's PROPNAME property with value VALUE.\n\
        !           704: It can be retrieved with  (get SYMBOL PROPNAME).")
        !           705:   (sym, prop, val)
        !           706:      Lisp_Object sym;
        !           707:      register Lisp_Object prop;
        !           708:      Lisp_Object val;
        !           709: {
        !           710:   register Lisp_Object tail, prev;
        !           711:   Lisp_Object newcell;
        !           712:   prev = Qnil;
        !           713:   for (tail = Fsymbol_plist (sym); !NULL (tail); tail = Fcdr (Fcdr (tail)))
        !           714:     {
        !           715:       register Lisp_Object tem;
        !           716:       tem = Fcar (tail);
        !           717:       if (EQ (prop, tem))
        !           718:        return Fsetcar (Fcdr (tail), val);
        !           719:       prev = tail;
        !           720:     }
        !           721:   newcell = Fcons (prop, Fcons (val, Qnil));
        !           722:   if (NULL (prev))
        !           723:     Fsetplist (sym, newcell);
        !           724:   else
        !           725:     Fsetcdr (Fcdr (prev), newcell);
        !           726:   return val;
        !           727: }
        !           728: 
        !           729: DEFUN ("equal", Fequal, Sequal, 2, 2, 0,
        !           730:   "T if two Lisp objects have similar structure and contents.\n\
        !           731: They must have the same data type.\n\
        !           732: Conses are compared by comparing the cars and the cdrs.\n\
        !           733: Vectors and strings are compared element by element.\n\
        !           734: Numbers are compared by value.  Symbols must match exactly.")
        !           735:   (o1, o2)
        !           736:      register Lisp_Object o1, o2;
        !           737: {
        !           738: do_cdr:
        !           739:   QUIT;
        !           740:   if (XTYPE (o1) != XTYPE (o2)) return Qnil;
        !           741:   if (XINT (o1) == XINT (o2)) return Qt;
        !           742:   if (XTYPE (o1) == Lisp_Cons)
        !           743:     {
        !           744:       Lisp_Object v1;
        !           745:       v1 = Fequal (Fcar (o1), Fcar (o2));
        !           746:       if (NULL (v1))
        !           747:        return v1;
        !           748:       o1 = Fcdr (o1), o2 = Fcdr (o2);
        !           749:       goto do_cdr;
        !           750:     }
        !           751:   if (XTYPE (o1) == Lisp_Marker)
        !           752:     {
        !           753:       return (XMARKER (o1)->buffer == XMARKER (o2)->buffer
        !           754:              && XMARKER (o1)->bufpos == XMARKER (o2)->bufpos)
        !           755:        ? Qt : Qnil;
        !           756:     }
        !           757:   if (XTYPE (o1) == Lisp_Vector)
        !           758:     {
        !           759:       register int index;
        !           760:       if (XVECTOR (o1)->size != XVECTOR (o2)->size)
        !           761:        return Qnil;
        !           762:       for (index = 0; index < XVECTOR (o1)->size; index++)
        !           763:        {
        !           764:          Lisp_Object v, v1, v2;
        !           765:          v1 = XVECTOR (o1)->contents [index];
        !           766:          v2 = XVECTOR (o2)->contents [index];
        !           767:          v = Fequal (v1, v2);
        !           768:          if (NULL (v)) return v;
        !           769:        }
        !           770:       return Qt;
        !           771:     }
        !           772:   if (XTYPE (o1) == Lisp_String)
        !           773:     {
        !           774:       if (XSTRING (o1)->size != XSTRING (o2)->size)
        !           775:        return Qnil;
        !           776:       if (bcmp (XSTRING (o1)->data, XSTRING (o2)->data, XSTRING (o1)->size))
        !           777:        return Qnil;
        !           778:       return Qt;
        !           779:     }
        !           780:   return Qnil;
        !           781: }
        !           782: 
        !           783: DEFUN ("fillarray", Ffillarray, Sfillarray, 2, 2, 0,
        !           784:   "Store each element of ARRAY with ITEM.  ARRAY is a vector or string.")
        !           785:   (array, item)
        !           786:      Lisp_Object array, item;
        !           787: {
        !           788:   register int size, index, charval;
        !           789:  retry:
        !           790:   if (XTYPE (array) == Lisp_Vector)
        !           791:     {
        !           792:       register Lisp_Object *p = XVECTOR (array)->contents;
        !           793:       size = XVECTOR (array)->size;
        !           794:       for (index = 0; index < size; index++)
        !           795:        p[index] = item;
        !           796:     }
        !           797:   else if (XTYPE (array) == Lisp_String)
        !           798:     {
        !           799:       register unsigned char *p = XSTRING (array)->data;
        !           800:       CHECK_NUMBER (item, 1);
        !           801:       charval = XINT (item);
        !           802:       size = XSTRING (array)->size;
        !           803:       for (index = 0; index < size; index++)
        !           804:        p[index] = charval;
        !           805:     }
        !           806:   else
        !           807:     {
        !           808:       array = wrong_type_argument (Qarrayp, array);
        !           809:       goto retry;
        !           810:     }
        !           811:   return array;
        !           812: }
        !           813: 
        !           814: /* ARGSUSED */
        !           815: Lisp_Object
        !           816: nconc2 (s1, s2)
        !           817:      Lisp_Object s1, s2;
        !           818: {
        !           819: #ifdef NO_ARG_ARRAY
        !           820:   Lisp_Object args[2];
        !           821:   args[0] = s1;
        !           822:   args[1] = s2;
        !           823:   return Fnconc (2, args);
        !           824: #else
        !           825:   return Fnconc (2, &s1);
        !           826: #endif /* NO_ARG_ARRAY */
        !           827: }
        !           828: 
        !           829: DEFUN ("nconc", Fnconc, Snconc, 0, MANY, 0,
        !           830:   "Concatenate any number of lists by altering them.\n\
        !           831: Only the last argument is not altered, and need not be a list.")
        !           832:   (nargs, args)
        !           833:      int nargs;
        !           834:      Lisp_Object *args;
        !           835: {
        !           836:   register int argnum;
        !           837:   register Lisp_Object tail, tem, val;
        !           838: 
        !           839:   val = Qnil;
        !           840: 
        !           841:   for (argnum = 0; argnum < nargs; argnum++)
        !           842:     {
        !           843:       tem = args[argnum];
        !           844:       if (NULL (tem)) continue;
        !           845: 
        !           846:       if (!LISTP (tem))
        !           847:        tem = wrong_type_argument (Qlistp, tem);
        !           848: 
        !           849:       if (NULL (val))
        !           850:        val = tem;
        !           851: 
        !           852:       if (argnum + 1 == nargs) break;
        !           853: 
        !           854:       while (LISTP (tem))
        !           855:        {
        !           856:          tail = tem;
        !           857:          tem = Fcdr (tail);
        !           858:          QUIT;
        !           859:        }
        !           860: 
        !           861:       tem = args[argnum + 1];
        !           862:       Fsetcdr (tail, tem);
        !           863:       if (NULL (tem))
        !           864:        args[argnum + 1] = tail;
        !           865:     }
        !           866: 
        !           867:   return val;
        !           868: }
        !           869: 
        !           870: /* This is the guts of all mapping functions.
        !           871:  Apply fn to each element of seq, one by one,
        !           872:  storing the results into elements of vals, a C vector of Lisp_Objects.
        !           873:  leni is the length of vals, which should also be the length of seq. */
        !           874: 
        !           875: static void
        !           876: mapcar1 (leni, vals, fn, seq)
        !           877:      int leni;
        !           878:      Lisp_Object *vals;
        !           879:      Lisp_Object fn, seq;
        !           880: {
        !           881:   register Lisp_Object tail;
        !           882:   Lisp_Object dummy;
        !           883:   register int i;
        !           884:   struct gcpro gcpro1, gcpro2, gcpro3;
        !           885: 
        !           886:   /* Don't let vals contain any garbage when GC happens.  */
        !           887:   for (i = 0; i < leni; i++)
        !           888:     vals[i] = Qnil;
        !           889: 
        !           890:   GCPRO3 (dummy, fn, seq);
        !           891:   gcpro1.var = vals;
        !           892:   gcpro1.nvars = leni;
        !           893:   /* We need not explicitly protect `tail' because it is used only on lists, and
        !           894:     1) lists are not relocated and 2) the list is marked via `seq' so will not be freed */
        !           895: 
        !           896:   if (XTYPE (seq) == Lisp_Vector)
        !           897:     {
        !           898:       for (i = 0; i < leni; i++)
        !           899:        {
        !           900:          dummy = XVECTOR (seq)->contents[i];
        !           901:          vals[i] = call1 (fn, dummy);
        !           902:        }
        !           903:     }
        !           904:   else if (XTYPE (seq) == Lisp_String)
        !           905:     {
        !           906:       for (i = 0; i < leni; i++)
        !           907:        {
        !           908:          XFASTINT (dummy) = XSTRING (seq)->data[i];
        !           909:          vals[i] = call1 (fn, dummy);
        !           910:        }
        !           911:     }
        !           912:   else   /* Must be a list, since Flength did not get an error */
        !           913:     {
        !           914:       tail = seq;
        !           915:       for (i = 0; i < leni; i++)
        !           916:        {
        !           917:          vals[i] = call1 (fn, Fcar (tail));
        !           918:          tail = Fcdr (tail);
        !           919:        }
        !           920:     }
        !           921: 
        !           922:   UNGCPRO;
        !           923: }
        !           924: 
        !           925: DEFUN ("mapconcat", Fmapconcat, Smapconcat, 3, 3, 0,
        !           926:   "Apply FN to each element of SEQ, and concat the results as strings.\n\
        !           927: In between each pair of results, stick in SEP.\n\
        !           928: Thus, \" \" as SEP results in spaces between the values return by FN.")
        !           929:   (fn, seq, sep)
        !           930:      Lisp_Object fn, seq, sep;
        !           931: {
        !           932:   Lisp_Object len;
        !           933:   register int leni;
        !           934:   int nargs;
        !           935:   register Lisp_Object *args;
        !           936:   register int i;
        !           937: 
        !           938:   len = Flength (seq);
        !           939:   leni = XINT (len);
        !           940:   nargs = leni + leni - 1;
        !           941:   if (nargs < 0) return build_string ("");
        !           942: 
        !           943:   args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
        !           944: 
        !           945:   mapcar1 (leni, args, fn, seq);
        !           946: 
        !           947:   for (i = leni - 1; i >= 0; i--)
        !           948:     args[i + i] = args[i];
        !           949:       
        !           950:   for (i = 1; i < nargs; i += 2)
        !           951:     args[i] = sep;
        !           952: 
        !           953:   return Fconcat (nargs, args);
        !           954: }
        !           955: 
        !           956: DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0,
        !           957:   "Apply FUNCTION to each element of LIST, and make a list of the results.\n\
        !           958: The result is a list just as long as LIST.")
        !           959:   (fn, seq)
        !           960:      Lisp_Object fn, seq;
        !           961: {
        !           962:   register Lisp_Object len;
        !           963:   register int leni;
        !           964:   register Lisp_Object *args;
        !           965: 
        !           966:   len = Flength (seq);
        !           967:   leni = XFASTINT (len);
        !           968:   args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object));
        !           969: 
        !           970:   mapcar1 (leni, args, fn, seq);
        !           971: 
        !           972:   return Flist (leni, args);
        !           973: }
        !           974: 
        !           975: DEFUN ("y-or-n-p", Fy_or_n_p, Sy_or_n_p, 1, 1, 0,
        !           976:   "Ask user a \"y or n\" question.  Return t if answer is \"y\".\n\
        !           977: No confirmation of the answer is requested; a single character is enough.\n\
        !           978: Also accepts Space to mean yes, or Delete to mean no.")
        !           979:   (prompt)
        !           980:      Lisp_Object prompt;
        !           981: {
        !           982:   register int ans;
        !           983:   register Lisp_Object xprompt;
        !           984:   Lisp_Object args[2];
        !           985: 
        !           986:   CHECK_STRING (prompt, 0);
        !           987:   xprompt = prompt;
        !           988:   while (1)
        !           989:     {
        !           990:       message ("%s(y or n) ", XSTRING (xprompt)->data);
        !           991:       ans = get_char (0);
        !           992:       message ("%s(y or n) %c", XSTRING (xprompt)->data, ans);
        !           993:       QUIT;
        !           994:       if (ans >= 'A' && ans <= 'Z') ans += 'a' - 'A';
        !           995:       if (ans == 'y' || ans == ' ')
        !           996:        return Qt;
        !           997:       if (ans == 'n' || ans == 127)
        !           998:        return Qnil;
        !           999:       if (EQ (xprompt, prompt))
        !          1000:        {
        !          1001:          Fdiscard_input ();
        !          1002:          args[0] = build_string ("Please answer y or n.  ");
        !          1003:          args[1] = prompt;
        !          1004:          xprompt = Fconcat (2, args);
        !          1005:        }
        !          1006:     }
        !          1007: }
        !          1008: 
        !          1009: DEFUN ("yes-or-no-p", Fyes_or_no_p, Syes_or_no_p, 1, 1, 0,
        !          1010:   "Ask user a yes or no question.  Return t if answer is yes.\n\
        !          1011: The user must confirm the answer with a newline, and can rub it out if not confirmed.")
        !          1012:   (prompt)
        !          1013:      Lisp_Object prompt;
        !          1014: {
        !          1015:   register Lisp_Object ans;
        !          1016:   Lisp_Object args[2];
        !          1017:   CHECK_STRING (prompt, 0);
        !          1018: 
        !          1019:   args[0] = prompt;
        !          1020:   args[1] = build_string ("(yes or no) ");
        !          1021:   prompt = Fconcat (2, args);
        !          1022:   while (1)
        !          1023:     {
        !          1024:       ans = Fdowncase (read_minibuf_string (Vminibuffer_local_map,
        !          1025:                                            Qnil,
        !          1026:                                            prompt));
        !          1027:       if (XSTRING (ans)->size == 3 && !strcmp (XSTRING (ans)->data, "yes"))
        !          1028:        return Qt;
        !          1029:       if (XSTRING (ans)->size == 2 && !strcmp (XSTRING (ans)->data, "no"))
        !          1030:        return Qnil;
        !          1031: 
        !          1032:       Fdiscard_input ();
        !          1033:       message ("Please answer yes or no.");
        !          1034:       Fsleep_for (make_number (2));
        !          1035:     }
        !          1036: }
        !          1037: 
        !          1038: /* Avoid static vars inside a function since in HPUX they dump as pure.  */
        !          1039: static int ldav_initialized;
        !          1040: static int ldav_channel;
        !          1041: #ifdef LOAD_AVE_TYPE
        !          1042: static struct nlist ldav_nl[2];
        !          1043: #endif /* LOAD_AVE_TYPE */
        !          1044: 
        !          1045: #define channel ldav_channel
        !          1046: #define initialized ldav_initialized
        !          1047: #define nl ldav_nl
        !          1048: 
        !          1049: DEFUN ("load-average", Fload_average, Sload_average, 0, 0, 0,
        !          1050:   "Return the current 1 minute, 5 minute and 15 minute load averages\n\
        !          1051: in a list (all floating point load average values are multiplied by 100\n\
        !          1052: and then turned into integers).")
        !          1053:   ()
        !          1054: {
        !          1055: #ifdef eunice
        !          1056: #include <vms/iodef.h>
        !          1057:   /*
        !          1058:    *   VMS/Eunice specific code -- read from the Load Ave driver
        !          1059:    */
        !          1060:   float load_ave[3];
        !          1061:   struct {int size; char *ptr;} descriptor;
        !          1062: 
        !          1063:   /* If this fails for any reason, we can return (0 0 0) */
        !          1064:   load_ave[0] = 0.0; load_ave[1] = 0.0; load_ave[2] = 0.0;
        !          1065: 
        !          1066:   /*
        !          1067:    *   Ensure that there is a channel open to the load ave device
        !          1068:    */
        !          1069:   if (initialized == 0)
        !          1070:     {
        !          1071:       /* Attempt to open the channel */
        !          1072:       descriptor.size = 18;
        !          1073:       descriptor.ptr  = "$$VMS_LOAD_AVERAGE";
        !          1074:       if (sys$assign (&descriptor, &channel, 0, 0) & 1)
        !          1075:        initialized = 1;
        !          1076:     }
        !          1077:   /*
        !          1078:    *   Read the load average vector
        !          1079:    */
        !          1080:   if (initialized)
        !          1081:     {
        !          1082:       if (!(sys$qiow (0, channel, IO$_READVBLK, 0, 0, 0,
        !          1083:                     load_ave, 12, 0, 0, 0, 0)
        !          1084:            & 1))
        !          1085:        {
        !          1086:          sys$dassgn (channel);
        !          1087:          initialized = 0;
        !          1088:        }
        !          1089:     }
        !          1090: #else  /* not eunice */
        !          1091: 
        !          1092: #ifndef LOAD_AVE_TYPE
        !          1093:   error ("load-average not implemented for this operating system");
        !          1094: #define LOAD_AVE_CVT(x) 0
        !          1095: #else /* LOAD_AVE_TYPE defined */
        !          1096:   /*
        !          1097:    *   4.2BSD UNIX-specific code -- read _avenrun from /dev/kmem
        !          1098:    */
        !          1099: 
        !          1100:   LOAD_AVE_TYPE load_ave[3];
        !          1101: 
        !          1102:   /* If this fails for any reason, we can return (0 0 0) */
        !          1103:   load_ave[0] = 0.0; load_ave[1] = 0.0; load_ave[2] = 0.0;
        !          1104: 
        !          1105:   /*
        !          1106:    *   Make sure we have the address of _avenrun
        !          1107:    */
        !          1108:   if (nl[0].n_value == 0)
        !          1109:     {
        !          1110:       /*
        !          1111:        *       Get the address of _avenrun
        !          1112:        */
        !          1113: #ifndef NLIST_STRUCT
        !          1114:       strcpy (nl[0].n_name, LDAV_SYMBOL);
        !          1115:       nl[1].n_zeroes = 0;
        !          1116: #else /* NLIST_STRUCT */
        !          1117:       nl[0].n_name = LDAV_SYMBOL;
        !          1118:       nl[1].n_name = 0;
        !          1119: #endif /* NLIST_STRUCT */
        !          1120: 
        !          1121:       nlist (KERNEL_FILE, nl);
        !          1122: 
        !          1123: #ifdef FIXUP_KERNEL_SYMBOL_ADDR
        !          1124:       if ((nl[0].n_type & N_TYPE) != N_ABS)
        !          1125:        nl[0].n_value = (nlp->n_value >> 2) | 0xc0000000;
        !          1126: #endif /* FIXUP_KERNEL_SYMBOL_ADDR */
        !          1127:     }
        !          1128:   /*
        !          1129:    *   Make sure we have /dev/kmem open
        !          1130:    */
        !          1131:   if (initialized == 0)
        !          1132:     {
        !          1133:       /*
        !          1134:        *       Open /dev/kmem
        !          1135:        */
        !          1136:       channel = open ("/dev/kmem", 0);
        !          1137:       if (channel >= 0) initialized = 1;
        !          1138:     }
        !          1139:   /*
        !          1140:    *   If we can, get the load ave values
        !          1141:    */
        !          1142:   if ((nl[0].n_value != 0) && (initialized != 0))
        !          1143:     {
        !          1144:       /*
        !          1145:        *       Seek to the correct address
        !          1146:        */
        !          1147:       lseek (channel, (long) nl[0].n_value, 0);
        !          1148:       if (read (channel, load_ave, sizeof load_ave)
        !          1149:          != sizeof(load_ave))
        !          1150:        {
        !          1151:          close (channel);
        !          1152:          initialized = 0;
        !          1153:        }
        !          1154:     }
        !          1155: #endif /* LOAD_AVE_TYPE */
        !          1156: #endif /* not eunice */
        !          1157: 
        !          1158:   /*
        !          1159:    *   Return the list of load average values
        !          1160:    */
        !          1161:   return Fcons (make_number (LOAD_AVE_CVT (load_ave[0])),
        !          1162:                Fcons (make_number (LOAD_AVE_CVT (load_ave[1])),
        !          1163:                       Fcons (make_number (LOAD_AVE_CVT (load_ave[2])),
        !          1164:                              Qnil)));
        !          1165: }
        !          1166: 
        !          1167: #undef channel
        !          1168: #undef initialized
        !          1169: #undef nl
        !          1170: 
        !          1171: Lisp_Object Vfeatures;
        !          1172: 
        !          1173: DEFUN ("featurep", Ffeaturep, Sfeaturep, 1, 1, 0,
        !          1174:   "Returns t if FEATURE is present in this Emacs.\n\
        !          1175: Use this to conditionalize execution of lisp code based on the presence or\n\
        !          1176: absence of emacs or environment extensions.\n\
        !          1177: Use  provide  to declare that a feature is available.\n\
        !          1178: This function looks at the value of the variable  features.")
        !          1179:      (feature)
        !          1180:      Lisp_Object feature;
        !          1181: {
        !          1182:   register Lisp_Object tem;
        !          1183:   CHECK_SYMBOL (feature, 0);
        !          1184:   tem = Fmemq (feature, Vfeatures);
        !          1185:   return (NULL (tem)) ? Qnil : Qt;
        !          1186: }
        !          1187: 
        !          1188: DEFUN ("provide", Fprovide, Sprovide, 1, 1, 0,
        !          1189:   "Announce that FEATURE is a feature of the current Emacs.")
        !          1190:      (feature)
        !          1191:      Lisp_Object feature;
        !          1192: {
        !          1193:   register Lisp_Object tem;
        !          1194:   CHECK_SYMBOL (feature, 0);
        !          1195:   if (!NULL (Vautoload_queue))
        !          1196:     Vautoload_queue = Fcons (Fcons (Vfeatures, Qnil), Vautoload_queue);
        !          1197:   tem = Fmemq (feature, Vfeatures);
        !          1198:   if (NULL (tem))
        !          1199:     Vfeatures = Fcons (feature, Vfeatures);
        !          1200:   return feature;
        !          1201: }
        !          1202: 
        !          1203: DEFUN ("require", Frequire, Srequire, 1, 2, 0,
        !          1204:   "If FEATURE is not present in Emacs (ie (featurep FEATURE) is false),\n\
        !          1205: load FILENAME.  FILENAME is optional and defaults to FEATURE.")
        !          1206:      (feature, file_name)
        !          1207:      Lisp_Object feature, file_name;
        !          1208: {
        !          1209:   register Lisp_Object tem;
        !          1210:   CHECK_SYMBOL (feature, 0);
        !          1211:   tem = Fmemq (feature, Vfeatures);
        !          1212:   if (NULL (tem))
        !          1213:     {
        !          1214:       Fload (NULL (file_name) ? Fsymbol_name (feature) : file_name,
        !          1215:             Qnil, Qt);
        !          1216:       tem = Fmemq (feature, Vfeatures);
        !          1217:       if (NULL (tem))
        !          1218:        error ("Required feature %s was not provided",
        !          1219:               XSYMBOL (feature)->name->data );
        !          1220:     }
        !          1221:   return feature;
        !          1222: }
        !          1223: 
        !          1224: syms_of_fns ()
        !          1225: {
        !          1226:   Qstring_lessp = intern ("string-lessp");
        !          1227:   staticpro (&Qstring_lessp);
        !          1228: 
        !          1229:   DefLispVar ("features", &Vfeatures,
        !          1230:     "A list of symbols which are the features of the executing emacs.\n\
        !          1231: Used by  featurep  and  require, and altered by  provide.");
        !          1232:   Vfeatures = Qnil;
        !          1233: 
        !          1234:   defsubr (&Sidentity);
        !          1235:   defsubr (&Srandom);
        !          1236:   defsubr (&Slength);
        !          1237:   defsubr (&Sstring_equal);
        !          1238:   defsubr (&Sstring_lessp);
        !          1239:   defalias (&Sstring_equal, "string=");
        !          1240:   defalias (&Sstring_lessp, "string<");
        !          1241:   defsubr (&Sappend);
        !          1242:   defsubr (&Sconcat);
        !          1243:   defsubr (&Svconcat);
        !          1244:   defsubr (&Scopy_sequence);
        !          1245:   defsubr (&Ssubstring);
        !          1246:   defsubr (&Snthcdr);
        !          1247:   defsubr (&Snth);
        !          1248:   defsubr (&Selt);
        !          1249:   defsubr (&Smemq);
        !          1250:   defsubr (&Sassq);
        !          1251:   defsubr (&Sassoc);
        !          1252:   defsubr (&Srassq);
        !          1253:   defsubr (&Sdelq);
        !          1254:   defsubr (&Snreverse);
        !          1255:   defsubr (&Sreverse);
        !          1256:   defsubr (&Ssort);
        !          1257:   defsubr (&Sget);
        !          1258:   defsubr (&Sput);
        !          1259:   defsubr (&Sequal);
        !          1260:   defsubr (&Sfillarray);
        !          1261:   defsubr (&Snconc);
        !          1262:   defsubr (&Smapcar);
        !          1263:   defsubr (&Smapconcat);
        !          1264:   defsubr (&Sy_or_n_p);
        !          1265:   defsubr (&Syes_or_no_p);
        !          1266:   defsubr (&Sload_average);
        !          1267:   defsubr (&Sfeaturep);
        !          1268:   defsubr (&Srequire);
        !          1269:   defsubr (&Sprovide);
        !          1270: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.