Annotation of GNUtools/emacs/src/editfns.c, revision 1.1

1.1     ! root        1: /* Lisp functions pertaining to editing.
        !             2:    Copyright (C) 1985, 1986, 1987, 1990 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU Emacs.
        !             5: 
        !             6: GNU Emacs is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 1, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU Emacs is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU Emacs; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: 
        !            21: #include "config.h"
        !            22: #ifdef hpux
        !            23: /* needed by <pwd.h> */
        !            24: #include <stdio.h>
        !            25: #undef NULL
        !            26: #endif
        !            27: 
        !            28: #ifdef VMS
        !            29: #include "vms-pwd.h"
        !            30: #else
        !            31: #include <pwd.h>
        !            32: #endif
        !            33: 
        !            34: #include "lisp.h"
        !            35: #include "buffer.h"
        !            36: #include "window.h"
        !            37: 
        !            38: #define min(a, b) ((a) < (b) ? (a) : (b))
        !            39: #define max(a, b) ((a) > (b) ? (a) : (b))
        !            40: 
        !            41: /* Some static data, and a function to initialize it for each run */
        !            42: 
        !            43: static Lisp_Object Vsystem_name;
        !            44: static Lisp_Object Vuser_real_name;  /* login name of current user ID */
        !            45: static Lisp_Object Vuser_full_name;  /* full name of current user */
        !            46: static Lisp_Object Vuser_name; /* user name from USER or LOGNAME.  */
        !            47: 
        !            48: void
        !            49: init_editfns ()
        !            50: {
        !            51:   char *user_name;
        !            52:   register unsigned char *p, *q;
        !            53:   struct passwd *pw;           /* password entry for the current user */
        !            54:   Lisp_Object tem;
        !            55:   extern char *index ();
        !            56: 
        !            57:   /* Turn off polling so the SIGALRM won't bother getpwuid.  */
        !            58:   stop_polling ();
        !            59: 
        !            60:   /* Set up system_name even when dumping.  */
        !            61: 
        !            62:   Vsystem_name = build_string (get_system_name ());
        !            63:   p = XSTRING (Vsystem_name)->data;
        !            64:   while (*p)
        !            65:     {
        !            66:       if (*p == ' ' || *p == '\t')
        !            67:        *p = '-';
        !            68:       p++;
        !            69:     }
        !            70: 
        !            71: #ifndef CANNOT_DUMP
        !            72:   /* Don't bother with this on initial start when just dumping out */
        !            73:   if (!initialized)
        !            74:     return;
        !            75: #endif                         /* not CANNOT_DUMP */
        !            76: 
        !            77:   pw = (struct passwd *) getpwuid (getuid ());
        !            78:   Vuser_real_name = build_string (pw ? pw->pw_name : "unknown");
        !            79: 
        !            80:   /* Get the effective user name, by consulting environment variables,
        !            81:      or the effective uid if those are unset.  */
        !            82:   user_name = (char *) getenv ("USER");
        !            83:   if (!user_name)
        !            84:     user_name = (char *) getenv ("LOGNAME"); /* USG equivalent */
        !            85:   if (!user_name)
        !            86:     {
        !            87:       pw = (struct passwd *) getpwuid (geteuid ());
        !            88:       user_name = pw ? pw->pw_name : "unknown";
        !            89:     }
        !            90:   Vuser_name = build_string (user_name);
        !            91: 
        !            92:   /* If the user name claimed in the environment vars differs from
        !            93:      the real uid, use the claimed name to find the full name.  */
        !            94:   tem = Fstring_equal (Vuser_name, Vuser_real_name);
        !            95:   if (NULL (tem))
        !            96:     pw = (struct passwd *) getpwnam (XSTRING (Vuser_name)->data);
        !            97:   
        !            98:   p = (unsigned char *) (pw ? USER_FULL_NAME : "unknown");
        !            99:   q = (unsigned char *) index (p, ',');
        !           100:   Vuser_full_name = make_string (p, q ? q - p : strlen (p));
        !           101: 
        !           102: #ifdef AMPERSAND_FULL_NAME
        !           103:   p = XSTRING (Vuser_full_name)->data;
        !           104:   q = (unsigned char *) index (p, '&');
        !           105:   /* Substitute the login name for the &, upcasing the first character.  */
        !           106:   if (q)
        !           107:     {
        !           108:       char *r
        !           109:        = (char *) alloca (strlen (p) + XSTRING (Vuser_name)->size + 1);
        !           110:       bcopy (p, r, q - p);
        !           111:       r[q - p] = 0;
        !           112:       strcat (r, XSTRING (Vuser_real_name)->data);
        !           113:       r[q - p] = UPCASE (r[q - p]);
        !           114:       strcat (r, q + 1);
        !           115:       Vuser_full_name = build_string (r);
        !           116:     }
        !           117: #endif                         /* AMPERSAND_FULL_NAME */
        !           118: 
        !           119:   start_polling ();
        !           120: }
        !           121: 
        !           122: DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
        !           123:   "Convert arg CHAR to a string containing that character.")
        !           124:   (n)
        !           125:      Lisp_Object n;
        !           126: {
        !           127:   char c;
        !           128:   CHECK_NUMBER (n, 0);
        !           129: 
        !           130:   c = XINT (n);
        !           131:   return make_string (&c, 1);
        !           132: }
        !           133: 
        !           134: DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
        !           135:   "Convert arg STRING to a character, the first character of that string.")
        !           136:   (str)
        !           137:      register Lisp_Object str;
        !           138: {
        !           139:   register Lisp_Object val;
        !           140:   register struct Lisp_String *p;
        !           141:   CHECK_STRING (str, 0);
        !           142: 
        !           143:   p = XSTRING (str);
        !           144:   if (p->size)
        !           145:     XFASTINT (val) = ((unsigned char *) p->data)[0];
        !           146:   else
        !           147:     XFASTINT (val) = 0;
        !           148:   return val;
        !           149: }
        !           150: 
        !           151: static Lisp_Object
        !           152: buildmark (val)
        !           153:      int val;
        !           154: {
        !           155:   register Lisp_Object mark;
        !           156:   mark = Fmake_marker ();
        !           157:   Fset_marker (mark, make_number (val), Qnil);
        !           158:   return mark;
        !           159: }
        !           160: 
        !           161: DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
        !           162:   "Return value of point, as an integer.\n\
        !           163: Beginning of buffer is position (point-min)")
        !           164:   ()
        !           165: {
        !           166:   Lisp_Object temp;
        !           167:   XFASTINT (temp) = point;
        !           168:   return temp;
        !           169: }
        !           170: 
        !           171: DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
        !           172:    "Return value of point, as a marker object.")
        !           173:   ()
        !           174: {
        !           175:   return buildmark (point);
        !           176: }
        !           177: 
        !           178: int
        !           179: clip_to_bounds (lower, num, upper)
        !           180:      int lower, num, upper;
        !           181: {
        !           182:   if (num < lower)
        !           183:     return lower;
        !           184:   else if (num > upper)
        !           185:     return upper;
        !           186:   else
        !           187:     return num;
        !           188: }
        !           189: 
        !           190: DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ",
        !           191:   "One arg, a number.  Set point to that number.\n\
        !           192: Beginning of buffer is position (point-min), end is (point-max).")
        !           193:   (n)
        !           194:      register Lisp_Object n;
        !           195: {
        !           196:   register int charno;
        !           197:   CHECK_NUMBER_COERCE_MARKER (n, 0);
        !           198:   charno = XINT (n);
        !           199:   SET_PT (clip_to_bounds (BEGV, charno, ZV));
        !           200:   return n;
        !           201: }
        !           202: 
        !           203: static Lisp_Object
        !           204: region_limit (beginningp)
        !           205:      int beginningp;
        !           206: {
        !           207:   register Lisp_Object m;
        !           208:   m = Fmarker_position (current_buffer->mark);
        !           209:   if (NULL (m)) error ("There is no region now");
        !           210:   if ((point < XFASTINT (m)) == beginningp)
        !           211:     return (make_number (point));
        !           212:   else
        !           213:     return (m);
        !           214: }
        !           215: 
        !           216: DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
        !           217:   "Return position of beginning of region, as an integer.")
        !           218:   ()
        !           219: {
        !           220:   return (region_limit (1));
        !           221: }
        !           222: 
        !           223: DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
        !           224:   "Return position of end of region, as an integer.")
        !           225:   ()
        !           226: {
        !           227:   return (region_limit (0));
        !           228: }
        !           229: 
        !           230: #if 0 /* now in lisp code */
        !           231: DEFUN ("mark", Fmark, Smark, 0, 0, 0,
        !           232:   "Return this buffer's mark value as integer, or nil if no mark.\n\
        !           233: If you are using this in an editing command, you are most likely making\n\
        !           234: a mistake; see the documentation of `set-mark'.")
        !           235:   ()
        !           236: {
        !           237:   return Fmarker_position (current_buffer->mark);
        !           238: }
        !           239: #endif /* commented out code */
        !           240: 
        !           241: DEFUN ("mark-marker", Fmark_marker, Smark_marker, 0, 0, 0,
        !           242:   "Return this buffer's mark, as a marker object.\n\
        !           243: Watch out!  Moving this marker changes the mark position.\n\
        !           244: The marker will not point anywhere if mark is not set.")
        !           245:   ()
        !           246: {
        !           247:   return current_buffer->mark;
        !           248: }
        !           249: 
        !           250: #if 0 /* this is now in lisp code */
        !           251: DEFUN ("set-mark", Fset_mark, Sset_mark, 1, 1, 0,
        !           252:   "Set this buffer's mark to POS.  Don't use this function!\n\
        !           253: That is to say, don't use this function unless you want\n\
        !           254: the user to see that the mark has moved, and you want the previous\n\
        !           255: mark position to be lost.\n\
        !           256: \n\
        !           257: Normally, when a new mark is set, the old one should go on the stack.\n\
        !           258: This is why most applications should use push-mark, not set-mark.\n\
        !           259: \n\
        !           260: Novice programmers often try to use the mark for the wrong purposes.\n\
        !           261: The mark saves a location for the user's convenience.\n\
        !           262: Most editing commands should not alter the mark.\n\
        !           263: To remember a location for internal use in the Lisp program,\n\
        !           264: store it in a Lisp variable.  Example:\n\
        !           265: \n\
        !           266:    (let ((beg (point))) (forward-line 1) (delete-region beg (point))).")
        !           267:   (pos)
        !           268:      Lisp_Object pos;
        !           269: {
        !           270:   if (NULL (pos))
        !           271:     {
        !           272:       current_buffer->mark = Qnil;
        !           273:       return Qnil;
        !           274:     }
        !           275:   CHECK_NUMBER_COERCE_MARKER (pos, 0);
        !           276: 
        !           277:   if (NULL (current_buffer->mark))
        !           278:     current_buffer->mark = Fmake_marker ();
        !           279: 
        !           280:   Fset_marker (current_buffer->mark, pos, Qnil);
        !           281:   return pos;
        !           282: }
        !           283: #endif /* commented-out code */
        !           284: 
        !           285: Lisp_Object
        !           286: save_excursion_save ()
        !           287: {
        !           288:   register int visible = XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer;
        !           289: 
        !           290:   return Fcons (Fpoint_marker (),
        !           291:                Fcons (Fcopy_marker (current_buffer->mark), visible ? Qt : Qnil));
        !           292: }
        !           293: 
        !           294: Lisp_Object
        !           295: save_excursion_restore (info)
        !           296:      register Lisp_Object info;
        !           297: {
        !           298:   register Lisp_Object tem;
        !           299: 
        !           300:   tem = Fmarker_buffer (Fcar (info));
        !           301:   /* If buffer being returned to is now deleted, avoid error */
        !           302:   /* Otherwise could get error here while unwinding to top level
        !           303:      and crash */
        !           304:   /* In that case, Fmarker_buffer returns nil now.  */
        !           305:   if (NULL (tem))
        !           306:     return Qnil;
        !           307:   Fset_buffer (tem);
        !           308:   tem = Fcar (info);
        !           309:   Fgoto_char (tem);
        !           310:   unchain_marker (tem);
        !           311:   tem = Fcar (Fcdr (info));
        !           312:   Fset_marker (current_buffer->mark, tem, Fcurrent_buffer ());
        !           313:   if (XMARKER (tem)->buffer)
        !           314:     unchain_marker (tem);
        !           315:   tem = Fcdr (Fcdr (info));
        !           316:   if (!NULL (tem) && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
        !           317:     Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
        !           318:   return Qnil;
        !           319: }
        !           320: 
        !           321: DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
        !           322:   "Save point (and mark), execute BODY, then restore point and mark.\n\
        !           323: Executes BODY just like PROGN.  Point and mark values are restored\n\
        !           324: even in case of abnormal exit (throw or error).")
        !           325:   (args)
        !           326:      Lisp_Object args;
        !           327: {
        !           328:   register Lisp_Object val;
        !           329:   int count = specpdl_ptr - specpdl;
        !           330: 
        !           331:   record_unwind_protect (save_excursion_restore, save_excursion_save ());
        !           332:                         
        !           333:   val = Fprogn (args);
        !           334:   unbind_to (count);
        !           335:   return val;
        !           336: }
        !           337: 
        !           338: DEFUN ("buffer-size", Fbufsize, Sbufsize, 0, 0, 0,
        !           339:   "Return the number of characters in the current buffer.")
        !           340:   ()
        !           341: {
        !           342:   Lisp_Object temp;
        !           343:   XFASTINT (temp) = Z - BEG;
        !           344:   return temp;
        !           345: }
        !           346: 
        !           347: DEFUN ("point-min", Fpoint_min, Spoint_min, 0, 0, 0,
        !           348:   "Return the minimum permissible value of point in the current buffer.\n\
        !           349: This is 1, unless a clipping restriction is in effect.")
        !           350:   ()
        !           351: {
        !           352:   Lisp_Object temp;
        !           353:   XFASTINT (temp) = BEGV;
        !           354:   return temp;
        !           355: }
        !           356: 
        !           357: DEFUN ("point-min-marker", Fpoint_min_marker, Spoint_min_marker, 0, 0, 0,
        !           358:   "Return a marker to the beginning of the currently visible part of the buffer.\n\
        !           359: This is the beginning, unless a clipping restriction is in effect.")
        !           360:   ()
        !           361: {
        !           362:   return buildmark (BEGV);
        !           363: }
        !           364: 
        !           365: DEFUN ("point-max", Fpoint_max, Spoint_max, 0, 0, 0,
        !           366:   "Return the maximum permissible value of point in the current buffer.\n\
        !           367: This is (1+ (buffer-size)), unless a clipping restriction is in effect,\n\
        !           368: in which case it is less.")
        !           369:   ()
        !           370: {
        !           371:   Lisp_Object temp;
        !           372:   XFASTINT (temp) = ZV;
        !           373:   return temp;
        !           374: }
        !           375: 
        !           376: DEFUN ("point-max-marker", Fpoint_max_marker, Spoint_max_marker, 0, 0, 0,
        !           377:   "Return a marker to the end of the currently visible part of the buffer.\n\
        !           378: This is the actual end, unless a clipping restriction is in effect.")
        !           379:   ()
        !           380: {
        !           381:   return buildmark (ZV);
        !           382: }
        !           383: 
        !           384: DEFUN ("following-char", Ffollchar, Sfollchar, 0, 0, 0,
        !           385:   "Return the character following point, as a number.")
        !           386:   ()
        !           387: {
        !           388:   Lisp_Object temp;
        !           389:   if (point >= ZV)
        !           390:     XFASTINT (temp) = 0;
        !           391:   else
        !           392:     XFASTINT (temp) = FETCH_CHAR (point);
        !           393:   return temp;
        !           394: }
        !           395: 
        !           396: DEFUN ("preceding-char", Fprevchar, Sprevchar, 0, 0, 0,
        !           397:   "Return the character preceding point, as a number.")
        !           398:   ()
        !           399: {
        !           400:   Lisp_Object temp;
        !           401:   if (point <= BEGV)
        !           402:     XFASTINT (temp) = 0;
        !           403:   else
        !           404:     XFASTINT (temp) = FETCH_CHAR (point - 1);
        !           405:   return temp;
        !           406: }
        !           407: 
        !           408: DEFUN ("bobp", Fbobp, Sbobp, 0, 0, 0,
        !           409:   "Return T if point is at the beginning of the buffer.\n\
        !           410: If the buffer is narrowed, this means the beginning of the narrowed part.")
        !           411:   ()
        !           412: {
        !           413:   if (point == BEGV)
        !           414:     return Qt;
        !           415:   return Qnil;
        !           416: }
        !           417: 
        !           418: DEFUN ("eobp", Feobp, Seobp, 0, 0, 0,
        !           419:   "Return T if point is at the end of the buffer.\n\
        !           420: If the buffer is narrowed, this means the end of the narrowed part.")
        !           421:   ()
        !           422: {
        !           423:   if (point == ZV)
        !           424:     return Qt;
        !           425:   return Qnil;
        !           426: }
        !           427: 
        !           428: DEFUN ("bolp", Fbolp, Sbolp, 0, 0, 0,
        !           429:   "Return T if point is at the beginning of a line.")
        !           430:   ()
        !           431: {
        !           432:   if (point == BEGV || FETCH_CHAR (point - 1) == '\n')
        !           433:     return Qt;
        !           434:   return Qnil;
        !           435: }
        !           436: 
        !           437: DEFUN ("eolp", Feolp, Seolp, 0, 0, 0,
        !           438:   "Return T if point is at the end of a line.\n\
        !           439: `End of a line' includes point being at the end of the buffer.")
        !           440:   ()
        !           441: {
        !           442:   if (point == ZV || FETCH_CHAR (point) == '\n')
        !           443:     return Qt;
        !           444:   return Qnil;
        !           445: }
        !           446: 
        !           447: DEFUN ("char-after", Fchar_after, Schar_after, 1, 1, 0,
        !           448:   "One arg, POS, a number.  Return the character in the current buffer\n\
        !           449: at position POS.\n\
        !           450: If POS is out of range, the value is NIL.")
        !           451:   (pos)
        !           452:      Lisp_Object pos;
        !           453: {
        !           454:   register Lisp_Object val;
        !           455:   register int n;
        !           456: 
        !           457:   CHECK_NUMBER_COERCE_MARKER (pos, 0);
        !           458: 
        !           459:   n = XINT (pos);
        !           460:   if (n < BEGV || n >= ZV) return Qnil;
        !           461: 
        !           462:   XFASTINT (val) = FETCH_CHAR (n);
        !           463:   return val;
        !           464: }
        !           465: 
        !           466: DEFUN ("user-login-name", Fuser_login_name, Suser_login_name, 0, 0, 0,
        !           467:   "Return the name under which user logged in, as a string.\n\
        !           468: This is based on the effective uid, not the real uid.")
        !           469:   ()
        !           470: {
        !           471:   return Vuser_name;
        !           472: }
        !           473: 
        !           474: DEFUN ("user-real-login-name", Fuser_real_login_name, Suser_real_login_name,
        !           475:   0, 0, 0,
        !           476:   "Return the name of the user's real uid, as a string.\n\
        !           477: Differs from user-login-name when running under su.")
        !           478:   ()
        !           479: {
        !           480:   return Vuser_real_name;
        !           481: }
        !           482: 
        !           483: DEFUN ("user-uid", Fuser_uid, Suser_uid, 0, 0, 0,
        !           484:   "Return the effective uid of Emacs, as an integer.")
        !           485:   ()
        !           486: {
        !           487:   return make_number (geteuid ());
        !           488: }
        !           489: 
        !           490: DEFUN ("user-real-uid", Fuser_real_uid, Suser_real_uid, 0, 0, 0,
        !           491:   "Return the real uid of Emacs, as an integer.")
        !           492:   ()
        !           493: {
        !           494:   return make_number (getuid ());
        !           495: }
        !           496: 
        !           497: DEFUN ("user-full-name", Fuser_full_name, Suser_full_name, 0, 0, 0,
        !           498:   "Return the full name of the user logged in, as a string.")
        !           499:   ()
        !           500: {
        !           501:   return Vuser_full_name;
        !           502: }
        !           503: 
        !           504: DEFUN ("system-name", Fsystem_name, Ssystem_name, 0, 0, 0,
        !           505:   "Return the name of the machine you are running on, as a string.")
        !           506:   ()
        !           507: {
        !           508:   return Vsystem_name;
        !           509: }
        !           510: 
        !           511: DEFUN ("current-time-string", Fcurrent_time_string, Scurrent_time_string, 0, 0, 0,
        !           512:   "Return the current time, as a human-readable string.")
        !           513:   ()
        !           514: {
        !           515:   long current_time = time (0);
        !           516:   register char *tem = (char *) ctime (&current_time);
        !           517:   tem [24] = 0;
        !           518:   return build_string (tem);
        !           519: }
        !           520: 
        !           521: insert1 (arg)
        !           522:      Lisp_Object arg;
        !           523: {
        !           524:   Finsert (1, &arg);
        !           525: }
        !           526: 
        !           527: DEFUN ("insert", Finsert, Sinsert, 0, MANY, 0,
        !           528:   "Any number of args, strings or chars.  Insert them after point, moving point forward.")
        !           529:   (nargs, args)
        !           530:      int nargs;
        !           531:      register Lisp_Object *args;
        !           532: {
        !           533:   register int argnum;
        !           534:   register Lisp_Object tem;
        !           535:   char str[1];
        !           536: 
        !           537:   for (argnum = 0; argnum < nargs; argnum++)
        !           538:     {
        !           539:       tem = args[argnum];
        !           540:     retry:
        !           541:       if (XTYPE (tem) == Lisp_Int)
        !           542:        {
        !           543:          str[0] = XINT (tem);
        !           544:          insert (str, 1);
        !           545:        }
        !           546:       else if (XTYPE (tem) == Lisp_String)
        !           547:        {
        !           548:          insert_from_string (tem, 0, XSTRING (tem)->size);
        !           549:        }
        !           550:       else
        !           551:        {
        !           552:          tem = wrong_type_argument (Qchar_or_string_p, tem);
        !           553:          goto retry;
        !           554:        }
        !           555:     }
        !           556:   return Qnil;
        !           557: }
        !           558: 
        !           559: DEFUN ("insert-before-markers", Finsert_before_markers, Sinsert_before_markers, 0, MANY, 0,
        !           560:   "Any number of args, strings or chars.  Insert them after point,\n\
        !           561: moving point forward.  Also, any markers pointing at the insertion point\n\
        !           562: get relocated to point after the newly inserted text.")
        !           563:   (nargs, args)
        !           564:      int nargs;
        !           565:      register Lisp_Object *args;
        !           566: {
        !           567:   register int argnum;
        !           568:   register Lisp_Object tem;
        !           569:   char str[1];
        !           570: 
        !           571:   for (argnum = 0; argnum < nargs; argnum++)
        !           572:     {
        !           573:       tem = args[argnum];
        !           574:     retry:
        !           575:       if (XTYPE (tem) == Lisp_Int)
        !           576:        {
        !           577:          str[0] = XINT (tem);
        !           578:          insert_before_markers (str, 1);
        !           579:        }
        !           580:       else if (XTYPE (tem) == Lisp_String)
        !           581:        {
        !           582:          insert_from_string_before_markers (tem, 0, XSTRING (tem)->size);
        !           583:        }
        !           584:       else
        !           585:        {
        !           586:          tem = wrong_type_argument (Qchar_or_string_p, tem);
        !           587:          goto retry;
        !           588:        }
        !           589:     }
        !           590:   return Qnil;
        !           591: }
        !           592: 
        !           593: DEFUN ("insert-char", Finsert_char, Sinsert_char, 2, 2, 0,
        !           594:   "Insert COUNT (second arg) copies of CHAR (first arg).\n\
        !           595: Both arguments are required.")
        !           596:   (chr, count)
        !           597:        Lisp_Object chr, count;
        !           598: {
        !           599:   register unsigned char *string;
        !           600:   register int strlen;
        !           601:   register int i, n;
        !           602: 
        !           603:   CHECK_NUMBER (chr, 0);
        !           604:   CHECK_NUMBER (count, 1);
        !           605: 
        !           606:   n = XINT (count);
        !           607:   if (n <= 0)
        !           608:     return Qnil;
        !           609:   strlen = max (n, 256);
        !           610:   string = (unsigned char *) alloca (strlen);
        !           611:   for (i = 0; i < strlen; i++)
        !           612:     string[i] = XFASTINT (chr);
        !           613:   while (n >= strlen)
        !           614:     {
        !           615:       insert (string, strlen);
        !           616:       n -= strlen;
        !           617:     }
        !           618:   if (n > 0)
        !           619:     insert (string, n);
        !           620:   return Qnil;
        !           621: }
        !           622: 
        !           623: 
        !           624: /* Return a string with the contents of the current region */
        !           625: 
        !           626: DEFUN ("buffer-substring", Fbuffer_substring, Sbuffer_substring, 2, 2, 0,
        !           627:   "Return the contents of part of the current buffer as a string.\n\
        !           628: The two arguments specify the start and end, as character numbers.")
        !           629:   (b, e)
        !           630:      Lisp_Object b, e;
        !           631: {
        !           632:   register int beg, end;
        !           633: 
        !           634:   validate_region (&b, &e);
        !           635:   beg = XINT (b);
        !           636:   end = XINT (e);
        !           637: 
        !           638:   if (beg < GPT && end > GPT)
        !           639:     move_gap (beg);
        !           640:   return make_string (&FETCH_CHAR (beg), end - beg);
        !           641: }
        !           642: 
        !           643: DEFUN ("buffer-string", Fbuffer_string, Sbuffer_string, 0, 0, 0,
        !           644:   "Return the contents of the current buffer as a string.")
        !           645:   ()
        !           646: {
        !           647:   if (BEGV < GPT && ZV > GPT)
        !           648:     move_gap (BEGV);
        !           649:   return make_string (BEGV_ADDR, ZV - BEGV);
        !           650: }
        !           651: 
        !           652: DEFUN ("insert-buffer-substring", Finsert_buffer_substring, Sinsert_buffer_substring,
        !           653:   1, 3, 0,
        !           654:   "Insert before point a substring of the contents buffer BUFFER.\n\
        !           655: BUFFER may be a buffer or a buffer name.\n\
        !           656: Arguments START and END are character numbers specifying the substring.\n\
        !           657: They default to the beginning and the end of BUFFER.")
        !           658:   (buf, b, e)
        !           659:      Lisp_Object buf, b, e;
        !           660: {
        !           661:   register int beg, end, exch;
        !           662:   register struct buffer *bp;
        !           663: 
        !           664:   buf = Fget_buffer (buf);
        !           665:   bp = XBUFFER (buf);
        !           666: 
        !           667:   if (NULL (b))
        !           668:     beg = BUF_BEGV (bp);
        !           669:   else
        !           670:     {
        !           671:       CHECK_NUMBER_COERCE_MARKER (b, 0);
        !           672:       beg = XINT (b);
        !           673:     }
        !           674:   if (NULL (e))
        !           675:     end = BUF_ZV (bp);
        !           676:   else
        !           677:     {
        !           678:       CHECK_NUMBER_COERCE_MARKER (e, 1);
        !           679:       end = XINT (e);
        !           680:     }
        !           681: 
        !           682:   if (beg > end)
        !           683:     exch = beg, beg = end, end = exch;
        !           684: 
        !           685:   /* Move the gap or create enough gap in the current buffer.  */
        !           686: 
        !           687:   if (point != GPT)
        !           688:     move_gap (point);
        !           689:   if (GAP_SIZE < end - beg)
        !           690:     make_gap (end - beg - GAP_SIZE);
        !           691: 
        !           692:   if (!(BUF_BEGV (bp) <= beg
        !           693:        && beg <= end
        !           694:         && end <= BUF_ZV (bp)))
        !           695:     args_out_of_range (b, e);
        !           696: 
        !           697:   /* Now the actual insertion will not do any gap motion,
        !           698:      so it matters not if BUF is the current buffer.  */
        !           699: 
        !           700:   if (beg < BUF_GPT (bp))
        !           701:     {
        !           702:       insert (BUF_CHAR_ADDRESS (bp, beg), min (end, BUF_GPT (bp)) - beg);
        !           703:       beg = min (end, BUF_GPT (bp));
        !           704:     }
        !           705:   if (beg < end)
        !           706:     insert (BUF_CHAR_ADDRESS (bp, beg), end - beg);
        !           707: 
        !           708:   return Qnil;
        !           709: }
        !           710: 
        !           711: DEFUN ("subst-char-in-region", Fsubst_char_in_region,
        !           712:   Ssubst_char_in_region, 4, 5, 0,
        !           713:   "From START to END, replace FROMCHAR with TOCHAR each time it occurs.\n\
        !           714: If optional arg NOUNDO is non-nil, don't record this change for undo\n\
        !           715: and don't mark the buffer as really changed.")
        !           716:   (start, end, fromchar, tochar, noundo)
        !           717:      Lisp_Object start, end, fromchar, tochar, noundo;
        !           718: {
        !           719:   register int pos, stop, look;
        !           720: 
        !           721:   validate_region (&start, &end);
        !           722:   CHECK_NUMBER (fromchar, 2);
        !           723:   CHECK_NUMBER (tochar, 3);
        !           724: 
        !           725:   pos = XINT (start);
        !           726:   stop = XINT (end);
        !           727:   look = XINT (fromchar);
        !           728: 
        !           729:   modify_region (pos, stop);
        !           730:   if (! NULL (noundo))
        !           731:     {
        !           732:       if (MODIFF - 1 == current_buffer->save_modified)
        !           733:        current_buffer->save_modified++;
        !           734:       if (MODIFF - 1 == current_buffer->auto_save_modified)
        !           735:        current_buffer->auto_save_modified++;
        !           736:     }
        !           737: 
        !           738:   while (pos < stop)
        !           739:     {
        !           740:       if (FETCH_CHAR (pos) == look)
        !           741:        {
        !           742:          if (NULL (noundo))
        !           743:            record_change (pos, 1);
        !           744:          FETCH_CHAR (pos) = XINT (tochar);
        !           745:        }
        !           746:       pos++;
        !           747:     }
        !           748: 
        !           749:   return Qnil;
        !           750: }
        !           751: 
        !           752: DEFUN ("delete-region", Fdelete_region, Sdelete_region, 2, 2, "r",
        !           753:   "Delete the text between point and mark.\n\
        !           754: When called from a program, expects two arguments,\n\
        !           755: character numbers specifying the stretch to be deleted.")
        !           756:   (b, e)
        !           757:      Lisp_Object b, e;
        !           758: {
        !           759:   validate_region (&b, &e);
        !           760:   del_range (XINT (b), XINT (e));
        !           761:   return Qnil;
        !           762: }
        !           763: 
        !           764: DEFUN ("widen", Fwiden, Swiden, 0, 0, "",
        !           765:   "Remove restrictions from current buffer, allowing full text to be seen and edited.")
        !           766:   ()
        !           767: {
        !           768:   BEGV = BEG;
        !           769:   SET_BUF_ZV (current_buffer, Z);
        !           770:   clip_changed = 1;
        !           771:   /* Changing the buffer bounds invalidates any recorded current column.  */
        !           772:   invalidate_current_column ();
        !           773:   return Qnil;
        !           774: }
        !           775: 
        !           776: DEFUN ("narrow-to-region", Fnarrow_to_region, Snarrow_to_region, 2, 2, "r",
        !           777:   "Restrict editing in this buffer to the current region.\n\
        !           778: The rest of the text becomes temporarily invisible and untouchable\n\
        !           779: but is not deleted; if you save the buffer in a file, the invisible\n\
        !           780: text is included in the file.  \\[widen] makes all visible again.\n\
        !           781: \n\
        !           782: When calling from a program, pass two arguments; character numbers\n\
        !           783: bounding the text that should remain visible.")
        !           784:   (b, e)
        !           785:      register Lisp_Object b, e;
        !           786: {
        !           787:   register int i;
        !           788: 
        !           789:   CHECK_NUMBER_COERCE_MARKER (b, 0);
        !           790:   CHECK_NUMBER_COERCE_MARKER (e, 1);
        !           791: 
        !           792:   if (XINT (b) > XINT (e))
        !           793:     {
        !           794:       i = XFASTINT (b);
        !           795:       b = e;
        !           796:       XFASTINT (e) = i;
        !           797:     }
        !           798: 
        !           799:   if (!(BEG <= XINT (b) && XINT (b) <= XINT (e) && XINT (e) <= Z))
        !           800:     args_out_of_range (b, e);
        !           801: 
        !           802:   BEGV = XFASTINT (b);
        !           803:   SET_BUF_ZV (current_buffer, XFASTINT (e));
        !           804:   if (point < XFASTINT (b))
        !           805:     SET_PT (XFASTINT (b));
        !           806:   if (point > XFASTINT (e))
        !           807:     SET_PT (XFASTINT (e));
        !           808:   clip_changed = 1;
        !           809:   /* Changing the buffer bounds invalidates any recorded current column.  */
        !           810:   invalidate_current_column ();
        !           811:   return Qnil;
        !           812: }
        !           813: 
        !           814: Lisp_Object
        !           815: save_restriction_save ()
        !           816: {
        !           817:   register Lisp_Object bottom, top;
        !           818:   /* Note: I tried using markers here, but it does not win
        !           819:      because insertion at the end of the saved region
        !           820:      does not advance top and is considered "outside" the saved region. */
        !           821:   XFASTINT (bottom) = BEGV - BEG;
        !           822:   XFASTINT (top) = Z - ZV;
        !           823: 
        !           824:   return Fcons (Fcurrent_buffer (), Fcons (bottom, top));
        !           825: }
        !           826: 
        !           827: Lisp_Object
        !           828: save_restriction_restore (data)
        !           829:      Lisp_Object data;
        !           830: {
        !           831:   register struct buffer *buf;
        !           832:   register int newhead, newtail;
        !           833:   register Lisp_Object tem;
        !           834: 
        !           835:   buf = XBUFFER (XCONS (data)->car);
        !           836: 
        !           837:   data = XCONS (data)->cdr;
        !           838: 
        !           839:   tem = XCONS (data)->car;
        !           840:   newhead = XINT (tem);
        !           841:   tem = XCONS (data)->cdr;
        !           842:   newtail = XINT (tem);
        !           843:   if (newhead + newtail > BUF_Z (buf) - BUF_BEG (buf))
        !           844:     {
        !           845:       newhead = 0;
        !           846:       newtail = 0;
        !           847:     }
        !           848:   BUF_BEGV (buf) = BUF_BEG (buf) + newhead;
        !           849:   SET_BUF_ZV (buf, BUF_Z (buf) - newtail);
        !           850:   clip_changed = 1;
        !           851: 
        !           852:   /* If point is outside the new visible range, move it inside. */
        !           853:   SET_BUF_PT (buf,
        !           854:              clip_to_bounds (BUF_BEGV (buf), BUF_PT (buf), BUF_ZV (buf)));
        !           855: 
        !           856:   return Qnil;
        !           857: }
        !           858: 
        !           859: DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0,
        !           860:   "Execute the body, undoing at the end any changes to current buffer's restrictions.\n\
        !           861: Changes to restrictions are made by narrow-to-region or by widen.\n\
        !           862: Thus, the restrictions are the same after this function as they were before it.\n\
        !           863: The value returned is that returned by the last form in the body.\n\
        !           864: \n\
        !           865: This function can be confused if, within the body, you widen\n\
        !           866: and then make changes outside the area within the saved restrictions.\n\
        !           867: \n\
        !           868: Note: if you are using both save-excursion and save-restriction,\n\
        !           869: use save-excursion outermost.")
        !           870:   (body)
        !           871:      Lisp_Object body;
        !           872: {
        !           873:   register Lisp_Object val;
        !           874:   int count = specpdl_ptr - specpdl;
        !           875: 
        !           876:   record_unwind_protect (save_restriction_restore, save_restriction_save ());
        !           877:   val = Fprogn (body);
        !           878:   unbind_to (count);
        !           879:   return val;
        !           880: }
        !           881: 
        !           882: DEFUN ("message", Fmessage, Smessage, 1, MANY, 0,
        !           883:   "Print a one-line message at the bottom of the screen.\n\
        !           884: The first argument is a control string.\n\
        !           885: It may contain %s or %d or %c to print successive following arguments.\n\
        !           886: %s means print an argument as a string, %d means print as number in decimal,\n\
        !           887: %c means print a number as a single character.\n\
        !           888: The argument used by %s must be a string or a symbol;\n\
        !           889: the argument used by %d or %c must be a number.")
        !           890:   (nargs, args)
        !           891:      int nargs;
        !           892:      Lisp_Object *args;
        !           893: {
        !           894:   register Lisp_Object val;
        !           895: 
        !           896:   val = Fformat (nargs, args);
        !           897:   message ("%s", XSTRING (val)->data);
        !           898:   return val;
        !           899: }
        !           900: 
        !           901: DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
        !           902:   "Format a string out of a control-string and arguments.\n\
        !           903: The first argument is a control string.\n\
        !           904: It, and subsequent arguments substituted into it, become the value, which is a string.\n\
        !           905: It may contain %s or %d or %c to substitute successive following arguments.\n\
        !           906: %s means print an argument as a string, %d means print as number in decimal,\n\
        !           907: %c means print a number as a single character.\n\
        !           908: The argument used by %s must be a string or a symbol;\n\
        !           909: the argument used by %d, %b, %o, %x or %c must be a number.")
        !           910:   (nargs, args)
        !           911:      int nargs;
        !           912:      register Lisp_Object *args;
        !           913: {
        !           914:   register int n;
        !           915:   register int total = 5;
        !           916:   char *buf;
        !           917:   register unsigned char *format;
        !           918:   register unsigned char **strings;
        !           919:   extern char *index ();
        !           920:   /* It should not be necessary to GCPRO ARGS, because
        !           921:      the caller in the interpreter should take care of that.  */
        !           922: 
        !           923:   CHECK_STRING (args[0], 0);
        !           924:   format = XSTRING (args[0])->data;
        !           925: 
        !           926:   /* We have to do so much work in order to prepare to call doprnt
        !           927:      that we might as well do all of it ourself...  (Which would also
        !           928:      circumvent C asciz cretinism by allowing ascii 000 chars to appear)
        !           929:    */
        !           930:   n = 0;
        !           931:   while (format = (unsigned char *) index (format, '%'))
        !           932:     {
        !           933:       format++;
        !           934:       while ((*format >= '0' && *format <= '9')
        !           935:             || *format == '-' || *format == ' ')
        !           936:        format++;
        !           937:       if (*format == '%')
        !           938:        format++;
        !           939:       else if (++n >= nargs)
        !           940:        ;
        !           941:       else if (XTYPE (args[n]) == Lisp_Symbol)
        !           942:        {
        !           943:          XSET (args[n], Lisp_String, XSYMBOL (args[n])->name);
        !           944:          goto string;
        !           945:        }
        !           946:       else if (XTYPE (args[n]) == Lisp_String)
        !           947:        {
        !           948:        string:
        !           949:          total += XSTRING (args[n])->size;
        !           950:        }
        !           951:       /* would get MPV otherwise, since Lisp_Int's `point' to low memory */
        !           952:       else if (XTYPE (args[n]) == Lisp_Int && *format != 's')
        !           953:        total += 10;
        !           954:       else
        !           955:        {
        !           956:          register Lisp_Object tem;
        !           957:          tem = Fprin1_to_string (args[n]);
        !           958:          args[n] = tem;
        !           959:          goto string;
        !           960:        }
        !           961:     }
        !           962: 
        !           963:   strings = (unsigned char **) alloca ((n + 1) * sizeof (unsigned char *));
        !           964:   for (; n >= 0; n--)
        !           965:     {
        !           966:       if (n >= nargs)
        !           967:        strings[n] = (unsigned char *) "";
        !           968:       else if (XTYPE (args[n]) == Lisp_Int)
        !           969:        /* We checked above that the correspondiong format effector
        !           970:           isn't %s, which would cause MPV */
        !           971:        strings[n] = (unsigned char *) XINT (args[n]);
        !           972:       else
        !           973:        strings[n] = XSTRING (args[n])->data;
        !           974:     }
        !           975: 
        !           976:   /* Format it in bigger and bigger buf's until it all fits. */
        !           977:   while (1)
        !           978:     {
        !           979:       buf = (char *) alloca (total + 1);
        !           980:       buf[total - 1] = 0;
        !           981: 
        !           982:       doprnt (buf, total + 1, strings[0], nargs, strings + 1);
        !           983:       if (buf[total - 1] == 0)
        !           984:        break;
        !           985: 
        !           986:       total *= 2;
        !           987:     }
        !           988: 
        !           989: /*   UNGCPRO;  */
        !           990:   return build_string (buf);
        !           991: }
        !           992: 
        !           993: /* VARARGS 1 */
        !           994: Lisp_Object
        !           995: #ifdef NO_ARG_ARRAY
        !           996: format1 (string1, arg0, arg1, arg2, arg3, arg4)
        !           997:      int arg0, arg1, arg2, arg3, arg4;
        !           998: #else
        !           999: format1 (string1)
        !          1000: #endif
        !          1001:      char *string1;
        !          1002: {
        !          1003:   char buf[100];
        !          1004: #ifdef NO_ARG_ARRAY
        !          1005:   int args[5];
        !          1006:   args[0] = arg0;
        !          1007:   args[1] = arg1;
        !          1008:   args[2] = arg2;
        !          1009:   args[3] = arg3;
        !          1010:   args[4] = arg4;
        !          1011:   doprnt (buf, sizeof buf, string1, 5, args);
        !          1012: #else
        !          1013:   doprnt (buf, sizeof buf, string1, 5, &string1 + 1);
        !          1014: #endif
        !          1015:   return build_string (buf);
        !          1016: }
        !          1017: 
        !          1018: DEFUN ("char-equal", Fchar_equal, Schar_equal, 2, 2, 0,
        !          1019:   "T if args (both characters (numbers)) match.  May ignore case.\n\
        !          1020: Case is ignored if the current buffer specifies to do so.")
        !          1021:   (c1, c2)
        !          1022:      register Lisp_Object c1, c2;
        !          1023: {
        !          1024:   CHECK_NUMBER (c1, 0);
        !          1025:   CHECK_NUMBER (c2, 1);
        !          1026: 
        !          1027:   if (!NULL (current_buffer->case_fold_search)
        !          1028:       ? downcase_table[0xff & XFASTINT (c1)] == downcase_table[0xff & XFASTINT (c2)]
        !          1029:       : XINT (c1) == XINT (c2))
        !          1030:     return Qt;
        !          1031:   return Qnil;
        !          1032: }
        !          1033: 
        !          1034: #ifndef MAINTAIN_ENVIRONMENT /* it is done in environ.c in that case */
        !          1035: DEFUN ("getenv", Fgetenv, Sgetenv, 1, 2, 0,
        !          1036:   "Return the value of environment variable VAR, as a string.\n\
        !          1037: VAR should be a string.  If the environment variable VAR is not defined,\n\
        !          1038: the value is nil.")
        !          1039:   (str)
        !          1040:      Lisp_Object str;
        !          1041: {
        !          1042:   register char *val;
        !          1043:   CHECK_STRING (str, 0);
        !          1044:   val = (char *) egetenv (XSTRING (str)->data);
        !          1045:   if (!val)
        !          1046:     return Qnil;
        !          1047:   return build_string (val);
        !          1048: }
        !          1049: #endif MAINTAIN_ENVIRONMENT
        !          1050: 
        !          1051: void
        !          1052: syms_of_editfns ()
        !          1053: {
        !          1054:   staticpro (&Vsystem_name);
        !          1055:   staticpro (&Vuser_name);
        !          1056:   staticpro (&Vuser_full_name);
        !          1057:   staticpro (&Vuser_real_name);
        !          1058: 
        !          1059:   defsubr (&Schar_equal);
        !          1060:   defsubr (&Sgoto_char);
        !          1061:   defsubr (&Sstring_to_char);
        !          1062:   defsubr (&Schar_to_string);
        !          1063:   defsubr (&Sbuffer_substring);
        !          1064:   defsubr (&Sbuffer_string);
        !          1065: 
        !          1066:   defsubr (&Spoint_marker);
        !          1067:   defsubr (&Smark_marker);
        !          1068:   defsubr (&Spoint);
        !          1069:   defsubr (&Sregion_beginning);
        !          1070:   defsubr (&Sregion_end);
        !          1071: /*  defsubr (&Smark); */
        !          1072: /*  defsubr (&Sset_mark); */
        !          1073:   defsubr (&Ssave_excursion);
        !          1074: 
        !          1075:   defsubr (&Sbufsize);
        !          1076:   defsubr (&Spoint_max);
        !          1077:   defsubr (&Spoint_min);
        !          1078:   defsubr (&Spoint_min_marker);
        !          1079:   defsubr (&Spoint_max_marker);
        !          1080: 
        !          1081:   defsubr (&Sbobp);
        !          1082:   defsubr (&Seobp);
        !          1083:   defsubr (&Sbolp);
        !          1084:   defsubr (&Seolp);
        !          1085:   defsubr (&Sfollchar);
        !          1086:   defsubr (&Sprevchar);
        !          1087:   defsubr (&Schar_after);
        !          1088:   defsubr (&Sinsert);
        !          1089:   defsubr (&Sinsert_before_markers);
        !          1090:   defsubr (&Sinsert_char);
        !          1091: 
        !          1092:   defsubr (&Suser_login_name);
        !          1093:   defsubr (&Suser_real_login_name);
        !          1094:   defsubr (&Suser_uid);
        !          1095:   defsubr (&Suser_real_uid);
        !          1096:   defsubr (&Suser_full_name);
        !          1097:   defsubr (&Scurrent_time_string);
        !          1098:   defsubr (&Ssystem_name);
        !          1099:   defsubr (&Smessage);
        !          1100:   defsubr (&Sformat);
        !          1101: #ifndef MAINTAIN_ENVIRONMENT /* in environ.c */
        !          1102:   defsubr (&Sgetenv);
        !          1103: #endif
        !          1104: 
        !          1105:   defsubr (&Sinsert_buffer_substring);
        !          1106:   defsubr (&Ssubst_char_in_region);
        !          1107:   defsubr (&Sdelete_region);
        !          1108:   defsubr (&Swiden);
        !          1109:   defsubr (&Snarrow_to_region);
        !          1110:   defsubr (&Ssave_restriction);
        !          1111: }

unix.superglobalmegacorp.com

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