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

1.1     ! root        1: /* Lisp parsing and input streams.
        !             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 <stdio.h>
        !            23: #include <sys/types.h>
        !            24: #include <sys/stat.h>
        !            25: #include <sys/file.h>
        !            26: #undef NULL
        !            27: #include "config.h"
        !            28: #include "lisp.h"
        !            29: 
        !            30: #ifndef standalone
        !            31: #include "buffer.h"
        !            32: #include "paths.h"
        !            33: #endif
        !            34: 
        !            35: #ifdef lint
        !            36: #include <sys/inode.h>
        !            37: #endif /* lint */
        !            38: 
        !            39: #ifndef X_OK
        !            40: #define X_OK 01
        !            41: #endif
        !            42: 
        !            43: Lisp_Object Qread_char, Qget_file_char, Qstandard_input;
        !            44: Lisp_Object Qvariable_documentation, Vvalues, Vstandard_input;
        !            45: 
        !            46: /* 1 iff inside of load */
        !            47: int load_in_progress;
        !            48: 
        !            49: /* Search path for files to be loaded. */
        !            50: Lisp_Object Vload_path;
        !            51: 
        !            52: /* File for get_file_char to read from.  Use by load */
        !            53: static FILE *instream;
        !            54: 
        !            55: /* When nonzero, read conses in pure space */
        !            56: static int read_pure;
        !            57: 
        !            58: /* For use within read-from-string (this reader is non-reentrant!!) */
        !            59: static int read_from_string_index;
        !            60: static int read_from_string_limit;
        !            61: 
        !            62: /* Handle unreading and rereading of characters.
        !            63:  Write READCHAR to read a character, UNREAD(c) to unread c to be read again. */
        !            64: 
        !            65: static int unrch;
        !            66: 
        !            67: static int readchar (readcharfun)
        !            68:      Lisp_Object readcharfun;
        !            69: {
        !            70:   Lisp_Object tem;
        !            71:   register struct buffer_text *inbuffer;
        !            72:   register int c, mpos;
        !            73: 
        !            74:   if (unrch >= 0)
        !            75:     {
        !            76:       c = unrch;
        !            77:       unrch = -1;
        !            78:       return c;
        !            79:     }
        !            80:   if (XTYPE (readcharfun) == Lisp_Buffer)
        !            81:     {
        !            82:       if (XBUFFER (readcharfun) == bf_cur)
        !            83:        inbuffer = &bf_text;
        !            84:       else
        !            85:        inbuffer = &XBUFFER (readcharfun)->text;
        !            86: 
        !            87:       if (inbuffer->pointloc >
        !            88:          inbuffer->size1 + inbuffer->size2 - inbuffer->tail_clip)
        !            89:        return -1;
        !            90:       c = *(unsigned char *) &(inbuffer->pointloc > inbuffer->size1 ? inbuffer->p2 : inbuffer->p1)[inbuffer->pointloc];
        !            91:       inbuffer->pointloc++;
        !            92:       return c;
        !            93:     }
        !            94:   if (XTYPE (readcharfun) == Lisp_Marker)
        !            95:     {
        !            96:       if (XMARKER (readcharfun)->buffer == bf_cur)
        !            97:        inbuffer = &bf_text;
        !            98:       else
        !            99:        inbuffer = &XMARKER (readcharfun)->buffer->text;
        !           100:       mpos = marker_position (readcharfun);
        !           101: 
        !           102:       if (mpos >
        !           103:          inbuffer->size1 + inbuffer->size2 - inbuffer->tail_clip)
        !           104:        return -1;
        !           105:       c = *(unsigned char *) &(mpos > inbuffer->size1 ? inbuffer->p2 : inbuffer->p1)[mpos];
        !           106:       if (mpos != inbuffer->size1 + 1)
        !           107:        XMARKER (readcharfun)->bufpos++;
        !           108:       else
        !           109:        Fset_marker (readcharfun, make_number (mpos + 1),
        !           110:                     Fmarker_buffer (readcharfun));
        !           111:       return c;
        !           112:     }
        !           113:   if (EQ (readcharfun, Qget_file_char))
        !           114:     return getc (instream);
        !           115: 
        !           116:   if (XTYPE (readcharfun) == Lisp_String)
        !           117:     return (read_from_string_index < read_from_string_limit) ?
        !           118:       XSTRING (readcharfun)->data[read_from_string_index++] : -1;
        !           119: 
        !           120:   tem = Fapply (readcharfun, Qnil);
        !           121: 
        !           122:   if (NULL (tem))
        !           123:     return -1;
        !           124:   return XINT (tem);
        !           125: }
        !           126: 
        !           127: #define READCHAR readchar(readcharfun)
        !           128: #define UNREAD(c) (unrch = c)
        !           129: 
        !           130: static Lisp_Object read0 (), read1 (), read_list (), read_vector ();
        !           131: 
        !           132: /* get a character from the tty */
        !           133: 
        !           134: DEFUN ("read-char", Fread_char, Sread_char, 0, 0, 0,
        !           135:   "Read a character from the command input (keyboard or macro).\n\
        !           136: It is returned as a number.")
        !           137:   ()
        !           138: {
        !           139:   register Lisp_Object val;
        !           140: 
        !           141: #ifndef standalone
        !           142:   XSET (val, Lisp_Int, get_char (0));
        !           143: #else
        !           144:   XSET (val, Lisp_Int, getchar ());
        !           145: #endif
        !           146: 
        !           147:   return val;
        !           148: }
        !           149: 
        !           150: DEFUN ("get-file-char", Fget_file_char, Sget_file_char, 0, 0, 0,
        !           151:   "Don't use this yourself.")
        !           152:   ()
        !           153: {
        !           154:   register Lisp_Object val;
        !           155:   XSET (val, Lisp_Int, getc (instream));
        !           156:   return val;
        !           157: }
        !           158: 
        !           159: void readevalloop ();
        !           160: Lisp_Object load_unwind ();
        !           161: 
        !           162: DEFUN ("load", Fload, Sload, 1, 3, "sLoad file: ",
        !           163:   "Execute a file of Lisp code named FILE.\n\
        !           164: First tries FILE with .elc appended, then tries with .el,\n\
        !           165:  then tries FILE unmodified.  Searches directories in  load-path.\n\
        !           166: If optional second arg MISSING-OK is non-nil,\n\
        !           167:  report no error if FILE doesn't exist.\n\
        !           168: Print messages at start and end of loading unless\n\
        !           169:  optional third arg NOMESSAGE is non-nil.\n\
        !           170: Return t if file exists.")
        !           171:   (str, missing_ok, nomessage)
        !           172:      Lisp_Object str, missing_ok, nomessage;
        !           173: {
        !           174:   register FILE *stream;
        !           175:   register int fd = -1;
        !           176:   register Lisp_Object lispstream;
        !           177:   int count = specpdl_ptr - specpdl;
        !           178:   struct gcpro gcpro1;
        !           179: 
        !           180:   CHECK_STRING (str, 0);
        !           181:   str = Fsubstitute_in_file_name (str);
        !           182: 
        !           183:   /* Avoid weird lossage with null string as arg,
        !           184:      since it would try to load a directory as a Lisp file */
        !           185:   if (XSTRING (str)->size > 0)
        !           186:     {
        !           187:       fd = openp (Vload_path, str, ".elc", 0, 0);
        !           188:       if (fd < 0)
        !           189:        fd = openp (Vload_path, str, ".el", 0, 0);
        !           190:       if (fd < 0)
        !           191:        fd = openp (Vload_path, str, "", 0, 0);
        !           192:     }
        !           193: 
        !           194:   if (fd < 0)
        !           195:     if (NULL (missing_ok))
        !           196:       while (1)
        !           197:        Fsignal (Qfile_error, Fcons (build_string ("Cannot open load file"),
        !           198:                                     Fcons (str, Qnil)));
        !           199:     else return Qnil;
        !           200: 
        !           201:   stream = fdopen (fd, "r");
        !           202:   if (stream == 0)
        !           203:     {
        !           204:       close (fd);
        !           205:       error ("Failure to create stdio stream for %s", XSTRING (str)->data);
        !           206:     }
        !           207:   XSET (lispstream, Lisp_Internal_Stream, (int) stream);
        !           208: 
        !           209:   if (NULL (nomessage))
        !           210:     message ("Loading %s...", XSTRING (str)->data);
        !           211: 
        !           212:   GCPRO1 (str);
        !           213:   record_unwind_protect (load_unwind, lispstream);
        !           214:   load_in_progress = 1;
        !           215:   readevalloop (Qget_file_char, stream, Feval, 0);
        !           216:   unbind_to (count);
        !           217:   UNGCPRO;
        !           218: 
        !           219:   if (!noninteractive && NULL (nomessage))
        !           220:     message ("Loading %s...done", XSTRING (str)->data);
        !           221:   return Qt;
        !           222: }
        !           223: 
        !           224: /* exec_only nonzero means don't open the files,
        !           225:    just look for one that is executable;
        !           226:    returns 1 on success, having stored a string into *storeptr  */
        !           227: 
        !           228: int
        !           229: openp (path, str, suffix, storeptr, exec_only)
        !           230:      Lisp_Object path, str;
        !           231:      char *suffix;
        !           232:      Lisp_Object *storeptr;
        !           233:      int exec_only;
        !           234: {
        !           235:   register int fd;
        !           236:   int fn_size = 100;
        !           237:   char buf[100];
        !           238:   register char *fn = buf;
        !           239:   int absolute = 0;
        !           240:   int want_size;
        !           241:   register Lisp_Object filename;
        !           242:   struct stat st;
        !           243: 
        !           244:   if (storeptr)
        !           245:     *storeptr = Qnil;
        !           246: 
        !           247:   if (*XSTRING (str)->data == '~' || *XSTRING (str)->data == '/')
        !           248:     absolute = 1;
        !           249: 
        !           250:   for (; !NULL (path); path = Fcdr (path))
        !           251:     {
        !           252:       filename = Fexpand_file_name (str, Fcar (path));
        !           253: 
        !           254:       want_size = strlen (suffix) + XSTRING (filename)->size + 1;
        !           255:       if (fn_size < want_size)
        !           256:        fn = (char *) alloca (fn_size = 100 + want_size);
        !           257: 
        !           258:       strncpy (fn, XSTRING (filename)->data, XSTRING (filename)->size);
        !           259:       fn[XSTRING (filename)->size] = 0;
        !           260:       strcat (fn, suffix);
        !           261:       if (exec_only)
        !           262:        {
        !           263:          if (!access (fn, X_OK) && stat (fn, &st) >= 0
        !           264:              && (st.st_mode & S_IFMT) != S_IFDIR)
        !           265:            {
        !           266:              if (storeptr)
        !           267:                *storeptr = build_string (fn);
        !           268:              return 1;
        !           269:            }
        !           270:        }
        !           271:       else
        !           272:        {
        !           273:          fd = open (fn, 0, 0);
        !           274:          if (fd >= 0)
        !           275:            {
        !           276:              if (storeptr)
        !           277:                *storeptr = build_string (fn);
        !           278:              return fd;
        !           279:            }
        !           280:        }
        !           281:       if (absolute) return -1;
        !           282:     }
        !           283: 
        !           284:   return -1;
        !           285: }
        !           286: 
        !           287: Lisp_Object
        !           288: load_unwind (stream)  /* used as unwind-protect function in load */
        !           289:      Lisp_Object stream;
        !           290: {
        !           291:   fclose ((FILE *) XSTRING (stream));
        !           292:   load_in_progress = 0;
        !           293:   return Qnil;
        !           294: }
        !           295: 
        !           296: Lisp_Object
        !           297: unreadpure ()  /* Used as unwind-protect function in readevalloop */
        !           298: {
        !           299:   read_pure = 0;
        !           300:   return Qnil;
        !           301: }
        !           302: 
        !           303: void
        !           304: readevalloop (readcharfun, stream, evalfun, printflag)
        !           305:      Lisp_Object readcharfun;
        !           306:      FILE *stream;     
        !           307:      Lisp_Object (*evalfun) ();
        !           308:      int printflag;
        !           309: {
        !           310:   register int c;
        !           311:   register Lisp_Object val;
        !           312:   register int xunrch;
        !           313:   int count = specpdl_ptr - specpdl;
        !           314: 
        !           315:   specbind (Qstandard_input, readcharfun);
        !           316: 
        !           317:   unrch = -1;
        !           318: 
        !           319:   while (1)
        !           320:     {
        !           321:       instream = stream;
        !           322:       c = READCHAR;
        !           323:       if (c == ';')
        !           324:        {
        !           325:          while ((c = READCHAR) != '\n' && c != -1);
        !           326:          continue;
        !           327:        }
        !           328:       if (c < 0) break;
        !           329:       if (c == ' ' || c == '\t' || c == '\n' || c == '\f') continue;
        !           330: 
        !           331:       if (!NULL (Vpurify_flag) && c == '(')
        !           332:        {
        !           333:          record_unwind_protect (unreadpure, Qnil);
        !           334:          val = read_list (-1, readcharfun);
        !           335:          unbind_to (count + 1);
        !           336:        }
        !           337:       else
        !           338:        {
        !           339:          UNREAD (c);
        !           340:          val = read0 (readcharfun);
        !           341:        }
        !           342: 
        !           343:       xunrch = unrch;
        !           344:       unrch = -1;
        !           345:       val = (*evalfun) (val);
        !           346:       if (printflag)
        !           347:        {
        !           348:          Vvalues = Fcons (val, Vvalues);
        !           349:          if (EQ (Vstandard_output, Qt))
        !           350:            Fprin1 (val, Qnil);
        !           351:          else
        !           352:            Fprint (val, Qnil);
        !           353:        }
        !           354:       unrch = xunrch;
        !           355:     }
        !           356: 
        !           357:   unbind_to (count);
        !           358: }
        !           359: 
        !           360: #ifndef standalone
        !           361: 
        !           362: DEFUN ("eval-current-buffer", Feval_current_buffer, Seval_current_buffer, 0, 1, "",
        !           363:   "Execute the current buffer as Lisp code.\n\
        !           364: Programs can pass argument PRINTFLAG which controls printing of output:\n\
        !           365: nil means discard it; anything else is stream for print.")
        !           366:   (printflag)
        !           367:      Lisp_Object printflag;
        !           368: {
        !           369:   int count = specpdl_ptr - specpdl;
        !           370:   Lisp_Object tem;
        !           371:   if (NULL (printflag))
        !           372:     tem = Qsymbolp;
        !           373:   else
        !           374:     tem = printflag;
        !           375:   specbind (Qstandard_output, tem);
        !           376:   record_unwind_protect (save_excursion_restore, save_excursion_save ());
        !           377:   SetPoint (FirstCharacter);
        !           378:   readevalloop (Fcurrent_buffer (), 0, Feval, !NULL (printflag));
        !           379:   unbind_to (count);
        !           380:   return Qnil;
        !           381: }
        !           382: 
        !           383: DEFUN ("eval-region", Feval_region, Seval_region, 2, 3, "r",
        !           384:   "Execute the region as Lisp code.\n\
        !           385: When called from programs, expects two arguments,\n\
        !           386: giving starting and ending indices in the current buffer\n\
        !           387: of the text to be executed.\n\
        !           388: Programs can pass third argument PRINTFLAG which controls printing of output:\n\
        !           389: nil means discard it; anything else is stream for print.")
        !           390:   (b, e, printflag)
        !           391:      Lisp_Object b, e, printflag;
        !           392: {
        !           393:   int count = specpdl_ptr - specpdl;
        !           394:   Lisp_Object tem;
        !           395:   if (NULL (printflag))
        !           396:     tem = Qsymbolp;
        !           397:   else
        !           398:     tem = printflag;
        !           399:   specbind (Qstandard_output, tem);
        !           400:   if (NULL (printflag))
        !           401:     record_unwind_protect (save_excursion_restore, save_excursion_save ());
        !           402:   record_unwind_protect (save_restriction_restore, save_restriction_save ());
        !           403:   SetPoint (XINT (b));
        !           404:   Fnarrow_to_region (make_number (FirstCharacter), e);
        !           405:   readevalloop (Fcurrent_buffer (), 0, Feval, !NULL (printflag));
        !           406:   unbind_to (count);
        !           407:   return Qnil;
        !           408: }
        !           409: 
        !           410: #endif standalone
        !           411: 
        !           412: DEFUN ("read", Fread, Sread, 0, 1, 0,
        !           413:   "Read one Lisp expression as text from STREAM, return as Lisp object.\n\
        !           414: If STREAM is nil, use the value of standard-input (which see).\n\
        !           415: STREAM or standard-input may be:\n\
        !           416:  a buffer (read from point and advance it)\n\
        !           417:  a marker (read from where it points and advance it)\n\
        !           418:  a function (call it with no arguments for each character)\n\
        !           419:  a string (takes text from string, starting at the beginning)\n\
        !           420:  t (read text line using minibuffer and use it).")
        !           421:   (readcharfun)
        !           422:      Lisp_Object readcharfun;
        !           423: {
        !           424:   extern Lisp_Object Fread_minibuffer ();
        !           425: 
        !           426:   unrch = -1;  /* Allow buffering-back only within a read. */
        !           427: 
        !           428:   if (NULL (readcharfun))
        !           429:     readcharfun = Vstandard_input;
        !           430:   if (EQ (readcharfun, Qt))
        !           431:     readcharfun = Qread_char;
        !           432: 
        !           433: #ifndef standalone
        !           434:   if (EQ (readcharfun, Qread_char))
        !           435:     return Fread_minibuffer (build_string ("Lisp expression: "), Qnil);
        !           436: #endif
        !           437: 
        !           438:   if (XTYPE (readcharfun) == Lisp_String)
        !           439:     return Fcar (Fread_from_string (readcharfun, Qnil, Qnil));
        !           440: 
        !           441:   return read0 (readcharfun);
        !           442: }
        !           443: 
        !           444: DEFUN ("read-from-string", Fread_from_string, Sread_from_string, 1, 3, 0,
        !           445:   "Read one Lisp expression which is represented as text by STRING.\n\
        !           446: Returns a cons: (OBJECT-READ . FINAL-STRING-INDEX).\n\
        !           447: START and END optionally delimit a substring of STRING from which to read;\n\
        !           448:  they default to 0 and (length STRING) respectively.")
        !           449:   (string, start, end)
        !           450:      Lisp_Object string, start, end;
        !           451: {
        !           452:   int startval, endval;
        !           453:   Lisp_Object tem;
        !           454: 
        !           455:   CHECK_STRING (string,0);
        !           456: 
        !           457:   if (NULL (end))
        !           458:     endval = XSTRING (string)->size;
        !           459:   else
        !           460:     { CHECK_NUMBER (end,2);
        !           461:       endval = XINT (end);
        !           462:       if (endval < 0 || endval > XSTRING (string)->size)
        !           463:        args_out_of_range (string, end);
        !           464:     }
        !           465: 
        !           466:   if (NULL (start))
        !           467:     startval = 0;
        !           468:   else
        !           469:     { CHECK_NUMBER (start,1);
        !           470:       startval = XINT (start);
        !           471:       if (startval < 0 || startval > endval)
        !           472:        args_out_of_range (string, start);
        !           473:     }
        !           474: 
        !           475:   read_from_string_index = startval;
        !           476:   read_from_string_limit = endval;
        !           477: 
        !           478:   unrch = -1;  /* Allow buffering-back only within a read. */
        !           479: 
        !           480:   tem = read0 (string);
        !           481:   return Fcons (tem, make_number (read_from_string_index));
        !           482: }
        !           483: 
        !           484: /* Use this for recursive reads, in contexts where internal tokens are not allowed. */
        !           485: 
        !           486: static Lisp_Object
        !           487: read0 (readcharfun)
        !           488:      Lisp_Object readcharfun;
        !           489: {
        !           490:   register Lisp_Object val;
        !           491:   char c;
        !           492: 
        !           493:   val = read1 (readcharfun);
        !           494:   if (XTYPE (val) == Lisp_Internal)
        !           495:     {
        !           496:       c = XINT (val);
        !           497:       return Fsignal (Qinvalid_read_syntax, Fcons (make_string (&c, 1), Qnil));
        !           498:     }
        !           499: 
        !           500:   return val;
        !           501: }
        !           502: 
        !           503: static int read_buffer_size;
        !           504: static char *read_buffer;
        !           505: 
        !           506: static Lisp_Object
        !           507: read1 (readcharfun)
        !           508:      register Lisp_Object readcharfun;
        !           509: {
        !           510:   register int c;
        !           511: 
        !           512:  retry:
        !           513: 
        !           514:   c = READCHAR;
        !           515:   if (c < 0) return Fsignal (Qend_of_file, Qnil);
        !           516: 
        !           517:   switch (c)
        !           518:     {
        !           519:     case '(':
        !           520:       return read_list (0, readcharfun);
        !           521: 
        !           522:     case '[':
        !           523:       return read_vector (readcharfun);
        !           524: 
        !           525:     case ')':
        !           526:     case ']':
        !           527:     case '.':
        !           528:       {
        !           529:        register Lisp_Object val;
        !           530:        XSET (val, Lisp_Internal, c);
        !           531:        return val;
        !           532:       }
        !           533: 
        !           534:     case '#':
        !           535:       return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("#", 1), Qnil));
        !           536: 
        !           537:     case ';':
        !           538:       while ((c = READCHAR) >= 0 && c != '\n');
        !           539:       goto retry;
        !           540: 
        !           541:     case '\'':
        !           542:       {
        !           543:        return Fcons (Qquote, Fcons (read0 (readcharfun), Qnil));
        !           544:       }
        !           545: 
        !           546:     case '?':
        !           547:       {
        !           548:        register Lisp_Object val;
        !           549: 
        !           550:        XSET (val, Lisp_Int, READCHAR);
        !           551:        if (XFASTINT (val) == '\\')
        !           552:          XSETINT (val, read_escape (readcharfun));
        !           553: 
        !           554:        return val;
        !           555:       }
        !           556: 
        !           557:     case '\"':
        !           558:       {
        !           559:        register char *p = read_buffer;
        !           560:        register char *end = read_buffer + read_buffer_size;
        !           561:        register int c;
        !           562:        int cancel = 0;
        !           563: 
        !           564:        while ((c = READCHAR) >= 0 &&
        !           565:                (c != '\"' || (c = READCHAR) == '\"'))
        !           566:          {
        !           567:            if (p == end)
        !           568:              {
        !           569:                char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
        !           570:                p += new - read_buffer;
        !           571:                read_buffer += new - read_buffer;
        !           572:                end = read_buffer + read_buffer_size;
        !           573:              }
        !           574:            if (c == '\\')
        !           575:              c = read_escape (readcharfun);
        !           576:            /* c is -1 if \ newline has just been seen */
        !           577:            if (c < 0)
        !           578:              {
        !           579:                if (p == read_buffer)
        !           580:                  cancel = 1;
        !           581:              }
        !           582:            else
        !           583:              *p++ = c;
        !           584:          }
        !           585: 
        !           586:        UNREAD (c);
        !           587:        /* If purifying, and string starts with \ newline,
        !           588:           return zero instead.  This is for doc strings
        !           589:           that we are really going to find in etc/DOC.nn.nn  */
        !           590:        if (!NULL (Vpurify_flag) && NULL (Vdoc_file_name) && cancel)
        !           591:          return make_number (0);
        !           592: 
        !           593:        if (read_pure)
        !           594:          return make_pure_string (read_buffer, p - read_buffer);
        !           595:        else
        !           596:          return make_string (read_buffer, p - read_buffer);
        !           597:       }
        !           598: 
        !           599:     default:
        !           600:       if (c <= 040) goto retry;
        !           601:       {
        !           602:        register char *p = read_buffer;
        !           603: 
        !           604:        {
        !           605:          register char *end = read_buffer + read_buffer_size;
        !           606: 
        !           607:          while (c > 040 && 
        !           608:                 !(c == '\"' || c == '\'' || c == ';' || c == '?'
        !           609:                   || c == '(' || c == ')' || c =='.'
        !           610:                   || c == '[' || c == ']' || c == '#'
        !           611:                   ))
        !           612:            {
        !           613:              if (p == end)
        !           614:                {
        !           615:                  register char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
        !           616:                  p += new - read_buffer;
        !           617:                  read_buffer += new - read_buffer;
        !           618:                  end = read_buffer + read_buffer_size;
        !           619:                }
        !           620:              if (c == '\\')
        !           621:                c = READCHAR;
        !           622:              *p++ = c;
        !           623:              c = READCHAR;
        !           624:            }
        !           625: 
        !           626:          if (p == end)
        !           627:            {
        !           628:              char *new = (char *) xrealloc (read_buffer, read_buffer_size *= 2);
        !           629:              p += new - read_buffer;
        !           630:              read_buffer += new - read_buffer;
        !           631:              end = read_buffer + read_buffer_size;
        !           632:            }
        !           633:          *p = 0;
        !           634:          UNREAD (c);
        !           635:        }
        !           636: 
        !           637:        /* Is it an integer? */
        !           638:        {
        !           639:          register char *p1;
        !           640:          register Lisp_Object val;
        !           641:          p1 = read_buffer;
        !           642:          if (*p1 == '+' || *p1 == '-') p1++;
        !           643:          if (p1 != p)
        !           644:            {
        !           645:              while (p1 != p && (c = *p1) >= '0' && c <= '9') p1++;
        !           646:              if (p1 == p)
        !           647:                /* It is. */
        !           648:                {
        !           649:                  XSET (val, Lisp_Int, atoi (read_buffer));
        !           650:                  return val;
        !           651:                }
        !           652:            }
        !           653:        }
        !           654: 
        !           655:        return intern (read_buffer);
        !           656:       }
        !           657:     }
        !           658: }
        !           659: 
        !           660: static Lisp_Object
        !           661: read_vector (readcharfun)
        !           662:      Lisp_Object readcharfun;
        !           663: {
        !           664:   register int i;
        !           665:   register int size;
        !           666:   register Lisp_Object *ptr;
        !           667:   register Lisp_Object tem, vector;
        !           668:   register struct Lisp_Cons *otem;
        !           669:   Lisp_Object len;
        !           670: 
        !           671:   tem = read_list (1, readcharfun);
        !           672:   len = Flength (tem);
        !           673:   vector = (read_pure ? make_pure_vector (XINT (len)) : Fmake_vector (len, Qnil));
        !           674: 
        !           675: 
        !           676:   size = XVECTOR (vector)->size;
        !           677:   ptr = XVECTOR (vector)->contents;
        !           678:   for (i = 0; i < size; i++)
        !           679:     {
        !           680:       ptr[i] = read_pure ? Fpurecopy (Fcar (tem)) : Fcar (tem);
        !           681:       otem = XCONS (tem);
        !           682:       tem = Fcdr (tem);
        !           683:       free_cons (otem);
        !           684:     }
        !           685:   return vector;
        !           686: }
        !           687:   
        !           688: /* flag = 1 means check for ] to terminate rather than ) and .
        !           689:    flag = -1 means check for starting with defun
        !           690:     and make structure pure.  */
        !           691: 
        !           692: static Lisp_Object
        !           693: read_list (flag, readcharfun)
        !           694:      int flag;
        !           695:      register Lisp_Object readcharfun;
        !           696: {
        !           697:   /* -1 means check next element for defun,
        !           698:      0 means don't check,
        !           699:      1 means already checked and found defun. */
        !           700:   int defunflag = flag < 0 ? -1 : 0;
        !           701:   register Lisp_Object elt, val, tail, tem;
        !           702: 
        !           703:   val = Qnil;
        !           704:   tail = Qnil;
        !           705: 
        !           706:   while (1)
        !           707:     {
        !           708:       elt = read1 (readcharfun);
        !           709:       if (XTYPE (elt) == Lisp_Internal)
        !           710:        {
        !           711:          if (flag > 0)
        !           712:            {
        !           713:              if (XINT (elt) == ']')
        !           714:                return val;
        !           715:              return Fsignal (Qinvalid_read_syntax, Fcons (make_string (") or . in a vector", 18), Qnil));
        !           716:            }
        !           717:          if (XINT (elt) == ')')
        !           718:            return val;
        !           719:          if (XINT (elt) == '.')
        !           720:            {
        !           721:              if (!NULL (tail))
        !           722:                tail = XCONS (tail)->cdr = read0 (readcharfun);
        !           723:              else
        !           724:                val = read0 (readcharfun);
        !           725:              elt = read1 (readcharfun);
        !           726:              if (XTYPE (elt) == Lisp_Internal && XINT (elt) == ')')
        !           727:                return val;
        !           728:              return Fsignal (Qinvalid_read_syntax, Fcons (make_string (". in wrong context", 18), Qnil));
        !           729:            }
        !           730:          return Fsignal (Qinvalid_read_syntax, Fcons (make_string ("] in a vector", 13), Qnil));
        !           731:        }
        !           732:       tem = (read_pure && flag <= 0
        !           733:             ? pure_cons (elt, Qnil)
        !           734:             : Fcons (elt, Qnil));
        !           735:       if (!NULL (tail))
        !           736:        XCONS (tail)->cdr = tem;
        !           737:       else
        !           738:        val = tem;
        !           739:       tail = tem;
        !           740:       if (defunflag < 0)
        !           741:        defunflag = EQ (elt, Qdefun);
        !           742:       else if (defunflag > 0)
        !           743:        read_pure = 1;
        !           744:     }
        !           745: }
        !           746: 
        !           747: static int
        !           748: read_escape (readcharfun)
        !           749:      Lisp_Object readcharfun;
        !           750: {
        !           751:   register int c = READCHAR;
        !           752:   switch (c)
        !           753:     {
        !           754:     case 'a':
        !           755:       return '\a';
        !           756:     case 'b':
        !           757:       return '\b';
        !           758:     case 'e':
        !           759:       return 033;
        !           760:     case 'f':
        !           761:       return '\f';
        !           762:     case 'n':
        !           763:       return '\n';
        !           764:     case 'r':
        !           765:       return '\r';
        !           766:     case 't':
        !           767:       return '\t';
        !           768:     case 'v':
        !           769:       return '\v';
        !           770:     case '\n':
        !           771:       return -1;
        !           772: 
        !           773:     case 'M':
        !           774:       c = READCHAR;
        !           775:       if (c != '-')
        !           776:        error ("Invalid escape character syntax");
        !           777:       c = READCHAR;
        !           778:       if (c == '\\')
        !           779:        c = read_escape (readcharfun);
        !           780:       return c | 0200;
        !           781: 
        !           782:     case 'C':
        !           783:       c = READCHAR;
        !           784:       if (c != '-')
        !           785:        error ("Invalid escape character syntax");
        !           786:     case '^':
        !           787:       c = READCHAR;
        !           788:       if (c == '\\')
        !           789:        c = read_escape (readcharfun);
        !           790:       if (c == '?')
        !           791:        return 0177;
        !           792:       return (c & 0200) | (c & 037);
        !           793:       
        !           794:     case '0':
        !           795:     case '1':
        !           796:     case '2':
        !           797:     case '3':
        !           798:     case '4':
        !           799:     case '5':
        !           800:     case '6':
        !           801:     case '7':
        !           802:       {
        !           803:        register int i = c - '0';
        !           804:        register int count = 0;
        !           805:        while (++count < 3)
        !           806:          {
        !           807:            if ((c = READCHAR) >= '0' && c <= '7')
        !           808:              {
        !           809:                i *= 8;
        !           810:                i += c - '0';
        !           811:              }
        !           812:            else
        !           813:              {
        !           814:                UNREAD (c);
        !           815:                break;
        !           816:              }
        !           817:          }
        !           818:        return i;
        !           819:       }
        !           820:     default:
        !           821:       return c;
        !           822:     }
        !           823: }
        !           824: 
        !           825: Lisp_Object Vobarray;
        !           826: Lisp_Object initial_obarray;
        !           827: 
        !           828: /* CHECK_OBARRAY assumes the variable `tem' is available */
        !           829: #define CHECK_OBARRAY(obarray) \
        !           830:   if (XTYPE (obarray) != Lisp_Vector) \
        !           831:     { tem = obarray; obarray = initial_obarray; \
        !           832:       wrong_type_argument (Qvectorp, tem); }
        !           833: 
        !           834: static int hash_string ();
        !           835: Lisp_Object oblookup ();
        !           836: 
        !           837: Lisp_Object
        !           838: intern (str)
        !           839:      char *str;
        !           840: {
        !           841:   Lisp_Object tem;
        !           842:   int len = strlen (str);
        !           843:   CHECK_OBARRAY (Vobarray);
        !           844:   tem = oblookup (Vobarray, str, len);
        !           845:   if (XTYPE (tem) == Lisp_Symbol)
        !           846:     return tem;
        !           847:   return Fintern ((!NULL (Vpurify_flag)
        !           848:                   ? make_pure_string (str, len)
        !           849:                   : make_string (str, len)),
        !           850:                  Vobarray);
        !           851: }
        !           852: 
        !           853: DEFUN ("intern", Fintern, Sintern, 1, 2, 0,
        !           854:   "Return the symbol whose name is STRING.\n\
        !           855: A second optional argument specifies the obarray to use;\n\
        !           856: it defaults to the value of  obarray.")
        !           857:   (str, obarray)
        !           858:      Lisp_Object str, obarray;
        !           859: {
        !           860:   register Lisp_Object tem, sym, *ptr;
        !           861: 
        !           862:   if (NULL (obarray))
        !           863:     {
        !           864:       CHECK_OBARRAY (Vobarray);
        !           865:       obarray = Vobarray;
        !           866:     }
        !           867:   else
        !           868:     CHECK_VECTOR (obarray, 1);
        !           869: 
        !           870:   CHECK_STRING (str, 0);
        !           871: 
        !           872:   tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
        !           873:   if (XTYPE (tem) != Lisp_Int)
        !           874:     return tem;
        !           875: 
        !           876:   if (!NULL (Vpurify_flag))
        !           877:     str = Fpurecopy (str);
        !           878:   sym = Fmake_symbol (str);
        !           879: 
        !           880:   ptr = &XVECTOR (obarray)->contents[XINT (tem)];
        !           881:   if (XTYPE (*ptr) == Lisp_Symbol)
        !           882:     XSYMBOL (sym)->next = XSYMBOL (*ptr);
        !           883:   else
        !           884:     XSYMBOL (sym)->next = 0;
        !           885:   *ptr = sym;
        !           886:   return sym;
        !           887: }
        !           888: 
        !           889: DEFUN ("intern-soft", Fintern_soft, Sintern_soft, 1, 2, 0,
        !           890:   "Return the symbol whose name is STRING, or nil if none exists yet.\n\
        !           891: A second optional argument specifies the obarray to use;\n\
        !           892: it defaults to the value of  obarray.")
        !           893:   (str, obarray)
        !           894:      Lisp_Object str, obarray;
        !           895: {
        !           896:   register Lisp_Object tem;
        !           897: 
        !           898:   if (NULL (obarray))
        !           899:     {
        !           900:       CHECK_OBARRAY (Vobarray);
        !           901:       obarray = Vobarray;
        !           902:     }
        !           903:   else
        !           904:     CHECK_VECTOR (obarray, 1);
        !           905: 
        !           906:   CHECK_STRING (str, 0);
        !           907: 
        !           908:   tem = oblookup (obarray, XSTRING (str)->data, XSTRING (str)->size);
        !           909:   if (XTYPE (tem) != Lisp_Int)
        !           910:     return tem;
        !           911:   return Qnil;
        !           912: }
        !           913: 
        !           914: Lisp_Object
        !           915: oblookup (obarray, ptr, size)
        !           916:      Lisp_Object obarray;
        !           917:      register char *ptr;
        !           918:      register int size;
        !           919: {
        !           920:   int hash, obsize;
        !           921:   register Lisp_Object tail;
        !           922:   Lisp_Object bucket, tem;
        !           923: 
        !           924:   if (XTYPE (obarray) != Lisp_Vector || !(obsize = XVECTOR (obarray)->size))
        !           925:     error ("Invalid obarray");
        !           926:   hash = hash_string (ptr, size) % obsize;
        !           927:   bucket = XVECTOR (obarray)->contents[hash];
        !           928:   for (tail = bucket; XSYMBOL (tail); XSETSYMBOL (tail, XSYMBOL (tail)->next))
        !           929:     {
        !           930:       if (XSYMBOL (tail)->name->size != size) continue;
        !           931:       if (bcmp (XSYMBOL (tail)->name->data, ptr, size)) continue;
        !           932:       return tail;
        !           933:     }
        !           934: 
        !           935:   XSET (tem, Lisp_Int, hash);
        !           936:   return tem;
        !           937: }
        !           938: 
        !           939: static int
        !           940: hash_string (ptr, len)
        !           941:      unsigned char *ptr;
        !           942:      int len;
        !           943: {
        !           944:   register unsigned char *p = ptr;
        !           945:   register unsigned char *end = p + len;
        !           946:   register unsigned char c;
        !           947:   register int hash = 0;
        !           948: 
        !           949:   while (p != end)
        !           950:     {
        !           951:       c = *p++;
        !           952:       if (c >= 0140) c -= 40;
        !           953:       hash = ((hash<<3) + (hash>>28) + c);
        !           954:     }
        !           955:   return hash & 07777777777;
        !           956: }
        !           957: 
        !           958: void
        !           959: map_obarray (obarray, fn, arg)
        !           960:      Lisp_Object obarray;
        !           961:      int (*fn) ();
        !           962:      Lisp_Object arg;
        !           963: {
        !           964:   register int i;
        !           965:   register Lisp_Object tail;
        !           966:   CHECK_VECTOR (obarray, 1);
        !           967:   for (i = XVECTOR (obarray)->size - 1; i >= 0; i--)
        !           968:     for (tail = XVECTOR (obarray)->contents[i];
        !           969:         XTYPE (tail) == Lisp_Symbol && XSYMBOL (tail);
        !           970:         XSETSYMBOL (tail, XSYMBOL (tail)->next))
        !           971:       (*fn) (tail, arg);
        !           972: }
        !           973: 
        !           974: mapatoms_1 (sym, function)
        !           975:      Lisp_Object sym, function;
        !           976: {
        !           977:   call1 (function, sym);
        !           978: }
        !           979: 
        !           980: DEFUN ("mapatoms", Fmapatoms, Smapatoms, 1, 2, 0,
        !           981:   "Call FUNCTION on every symbol in OBARRAY.\n\
        !           982: OBARRAY defaults to the value of  obarray.")
        !           983:   (function, obarray)
        !           984:      Lisp_Object function, obarray;
        !           985: {
        !           986:   Lisp_Object tem;
        !           987: 
        !           988:   if (NULL (obarray))
        !           989:     {
        !           990:       CHECK_OBARRAY (Vobarray);
        !           991:       obarray = Vobarray;
        !           992:     }
        !           993:   else
        !           994:     CHECK_VECTOR (obarray, 1);
        !           995: 
        !           996:   map_obarray (obarray, mapatoms_1, function);
        !           997:   return Qnil;
        !           998: }
        !           999: 
        !          1000: #define OBARRAY_SIZE 511
        !          1001: 
        !          1002: void
        !          1003: init_obarray ()
        !          1004: {
        !          1005:   Lisp_Object oblength;
        !          1006:   int hash;
        !          1007:   Lisp_Object *tem;
        !          1008: 
        !          1009:   XFASTINT (oblength) = OBARRAY_SIZE;
        !          1010: 
        !          1011:   Qnil = Fmake_symbol (make_pure_string ("nil", 3));
        !          1012:   Vobarray = Fmake_vector (oblength, make_number (0));
        !          1013:   initial_obarray = Vobarray;
        !          1014:   staticpro (&Vobarray);
        !          1015:   staticpro (&initial_obarray);
        !          1016:   /* Intern nil in the obarray */
        !          1017:   /* These locals are to kludge around a pyramid compiler bug. */
        !          1018:   hash = hash_string ("nil", 3) % OBARRAY_SIZE;
        !          1019:   tem = &XVECTOR (Vobarray)->contents[hash];
        !          1020:   *tem = Qnil;
        !          1021: 
        !          1022:   Qunbound = Fmake_symbol (make_pure_string ("unbound", 7));
        !          1023:   XSYMBOL (Qnil)->function = Qunbound;
        !          1024:   XSYMBOL (Qunbound)->value = Qunbound;
        !          1025:   XSYMBOL (Qunbound)->function = Qunbound;
        !          1026: 
        !          1027:   Qt = intern ("t");
        !          1028:   XSYMBOL (Qnil)->value = Qnil;
        !          1029:   XSYMBOL (Qnil)->plist = Qnil;
        !          1030:   XSYMBOL (Qt)->value = Qt;
        !          1031: 
        !          1032:   Qvariable_documentation = intern ("variable-documentation");
        !          1033: 
        !          1034:   read_buffer_size = 100;
        !          1035:   read_buffer = (char *) malloc (read_buffer_size);
        !          1036: }
        !          1037: 
        !          1038: void
        !          1039: defsubr (sname)
        !          1040:      struct Lisp_Subr *sname;
        !          1041: {
        !          1042:   Lisp_Object sym;
        !          1043:   sym = intern (sname->symbol_name);
        !          1044:   XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
        !          1045: }
        !          1046: 
        !          1047: void
        !          1048: defalias (sname, string)
        !          1049:      struct Lisp_Subr *sname;
        !          1050:      char *string;
        !          1051: {
        !          1052:   Lisp_Object sym;
        !          1053:   sym = intern (string);
        !          1054:   XSET (XSYMBOL (sym)->function, Lisp_Subr, sname);
        !          1055: }
        !          1056: 
        !          1057: /* Define an "integer variable"; a symbol whose value is forwarded
        !          1058:  to a C variable of type int.  Sample call is
        !          1059: DefIntVar ("indent-tabs-mode", &indent_tabs_mode, "Documentation");  */
        !          1060: 
        !          1061: void
        !          1062: DefIntVar (namestring, address, doc)
        !          1063:      char *namestring;
        !          1064:      int *address;
        !          1065:      char *doc;
        !          1066: {
        !          1067:   Lisp_Object sym;
        !          1068:   sym = intern (namestring);
        !          1069:   XSET (XSYMBOL (sym)->value, Lisp_Intfwd, address);
        !          1070:   Fput (sym, Qvariable_documentation,
        !          1071:        make_pure_string (doc, strlen (doc)));
        !          1072: }
        !          1073: 
        !          1074: /* Similar but define a variable whose value is T if address contains 1,
        !          1075:  NIL if address contains 0 */
        !          1076: 
        !          1077: void
        !          1078: DefBoolVar (namestring, address, doc)
        !          1079:      char *namestring;
        !          1080:      int *address;
        !          1081:      char *doc;
        !          1082: {
        !          1083:   Lisp_Object sym;
        !          1084:   sym = intern (namestring);
        !          1085:   XSET (XSYMBOL (sym)->value, Lisp_Boolfwd, address);
        !          1086:   Fput (sym, Qvariable_documentation,
        !          1087:        make_pure_string (doc, strlen (doc)));
        !          1088: }
        !          1089: 
        !          1090: /* Similar but define a variable whose value is the Lisp Object stored at address. */
        !          1091: 
        !          1092: void
        !          1093: DefLispVar (namestring, address, doc)
        !          1094:      char *namestring;
        !          1095:      Lisp_Object *address;
        !          1096:      char *doc;
        !          1097: {
        !          1098:   Lisp_Object sym;
        !          1099:   sym = intern (namestring);
        !          1100:   XSET (XSYMBOL (sym)->value, Lisp_Objfwd, address);
        !          1101:   Fput (sym, Qvariable_documentation,
        !          1102:        make_pure_string (doc, strlen (doc)));
        !          1103: }
        !          1104: 
        !          1105: #ifndef standalone
        !          1106: 
        !          1107: /* Similar but define a variable whose value is the Lisp Object stored in
        !          1108:  the current buffer.  address is the address of the slot in the buffer that is current now. */
        !          1109: 
        !          1110: void
        !          1111: DefBufferLispVar (namestring, address, doc)
        !          1112:      char *namestring;
        !          1113:      Lisp_Object *address;
        !          1114:      char *doc;
        !          1115: {
        !          1116:   Lisp_Object sym;
        !          1117:   sym = intern (namestring);
        !          1118:   XSET (XSYMBOL (sym)->value, Lisp_Buffer_Objfwd,
        !          1119:        (Lisp_Object *)((char *)address - (char *)bf_cur));
        !          1120:   Fput (sym, Qvariable_documentation,
        !          1121:        make_pure_string (doc, strlen (doc)));
        !          1122: }
        !          1123: 
        !          1124: #endif standalone
        !          1125: 
        !          1126: init_read ()
        !          1127: {
        !          1128:   Vvalues = Qnil;
        !          1129: 
        !          1130:   Vload_path = decode_env_path ("EMACSLOADPATH", PATH_LOADSEARCH);
        !          1131: #ifndef CANNOT_DUMP
        !          1132:   if (!NULL (Vpurify_flag))
        !          1133:     Vload_path = Fcons (build_string ("../lisp"), Vload_path);
        !          1134: #endif /* not CANNOT_DUMP */
        !          1135: }
        !          1136: 
        !          1137: void
        !          1138: syms_of_read ()
        !          1139: {
        !          1140:   defsubr (&Sread);
        !          1141:   defsubr (&Sread_from_string);
        !          1142:   defsubr (&Sintern);
        !          1143:   defsubr (&Sintern_soft);
        !          1144:   defsubr (&Sload);
        !          1145:   defsubr (&Seval_current_buffer);
        !          1146:   defsubr (&Seval_region);
        !          1147:   defsubr (&Sread_char);
        !          1148:   defsubr (&Sget_file_char);
        !          1149:   defsubr (&Smapatoms);
        !          1150: 
        !          1151:   DefLispVar ("obarray", &Vobarray,
        !          1152:     "Symbol table for use by  intern  and  read.\n\
        !          1153: It is a vector whose length ought to be prime for best results.\n\
        !          1154: Each element is a list of all interned symbols whose names hash in that bucket.");
        !          1155: 
        !          1156:   DefLispVar ("values", &Vvalues,
        !          1157:     "List of values of all expressions which were read, evaluated and printed.\n\
        !          1158: Order is reverse chronological.");
        !          1159: 
        !          1160:   DefLispVar ("standard-input", &Vstandard_input,
        !          1161:     "Stream for read to get input from.\n\
        !          1162: See documentation of read for possible values.");
        !          1163:   Vstandard_input = Qt;
        !          1164: 
        !          1165:   DefLispVar ("load-path", &Vload_path,
        !          1166:     "*List of directories to search for files to load.\n\
        !          1167: Each element is a string (directory name) or nil (try default directory).\n\
        !          1168: Initialized based on EMACSLOADPATH environment variable, if any,\n\
        !          1169: otherwise to default specified in by file paths.h when emacs was built.");
        !          1170: 
        !          1171:   DefBoolVar ("load-in-progress", &load_in_progress,
        !          1172:     "Non-nil iff inside of  load.");
        !          1173: 
        !          1174:   Qstandard_input = intern ("standard-input");
        !          1175:   staticpro (&Qstandard_input);
        !          1176: 
        !          1177:   Qread_char = intern ("read-char");
        !          1178:   staticpro (&Qread_char);
        !          1179: 
        !          1180:   Qget_file_char = intern ("get-file-char");
        !          1181:   staticpro (&Qget_file_char);
        !          1182: 
        !          1183:   unrch = -1;
        !          1184: }

unix.superglobalmegacorp.com

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