1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <config.h>
25: #include <sys/types.h>
26: #include <stdio.h>
27:
28: #ifdef HAVE_PWD_H
29: #include <pwd.h>
30: #endif
31:
32: #ifdef HAVE_UNISTD_H
33: #include <unistd.h>
34: #endif
35:
36: #ifdef HAVE_SYS_UTSNAME_H
37: #include <sys/utsname.h>
38: #endif
39:
40: #include "lisp.h"
41:
42:
43:
44:
45: #include "systime.h"
46:
47: #if defined HAVE_SYS_RESOURCE_H
48: #include <sys/resource.h>
49: #endif
50:
51: #include <ctype.h>
52:
53: #include "intervals.h"
54: #include "buffer.h"
55: #include "charset.h"
56: #include "coding.h"
57: #include "frame.h"
58: #include "window.h"
59: #include "blockinput.h"
60:
61: #ifdef STDC_HEADERS
62: #include <float.h>
63: #define MAX_10_EXP DBL_MAX_10_EXP
64: #else
65: #define MAX_10_EXP 310
66: #endif
67:
68: #ifndef NULL
69: #define NULL 0
70: #endif
71:
72: #ifndef USE_CRT_DLL
73: extern char **environ;
74: #endif
75:
76: #define TM_YEAR_BASE 1900
77:
78:
79:
80: #ifndef TM_YEAR_IN_ASCTIME_RANGE
81: # define TM_YEAR_IN_ASCTIME_RANGE(tm_year) \
82: (1000 - TM_YEAR_BASE <= (tm_year) && (tm_year) <= 9999 - TM_YEAR_BASE)
83: #endif
84:
85: extern size_t emacs_strftimeu P_ ((char *, size_t, const char *,
86: const struct tm *, int));
87: static int tm_diff P_ ((struct tm *, struct tm *));
88: static void find_field P_ ((Lisp_Object, Lisp_Object, Lisp_Object, int *, Lisp_Object, int *));
89: static void update_buffer_properties P_ ((int, int));
90: static Lisp_Object region_limit P_ ((int));
91: int lisp_time_argument P_ ((Lisp_Object, time_t *, int *));
92: static size_t emacs_memftimeu P_ ((char *, size_t, const char *,
93: size_t, const struct tm *, int));
94: static void general_insert_function P_ ((void (*) (const unsigned char *, int),
95: void (*) (Lisp_Object, int, int, int,
96: int, int),
97: int, int, Lisp_Object *));
98: static Lisp_Object subst_char_in_region_unwind P_ ((Lisp_Object));
99: static Lisp_Object subst_char_in_region_unwind_1 P_ ((Lisp_Object));
100: static void transpose_markers P_ ((int, int, int, int, int, int, int, int));
101:
102: #ifdef HAVE_INDEX
103: extern char *index P_ ((const char *, int));
104: #endif
105:
106: Lisp_Object Vbuffer_access_fontify_functions;
107: Lisp_Object Qbuffer_access_fontify_functions;
108: Lisp_Object Vbuffer_access_fontified_property;
109:
110: Lisp_Object Fuser_full_name P_ ((Lisp_Object));
111:
112:
113:
114: Lisp_Object Vinhibit_field_text_motion;
115:
116:
117:
118: Lisp_Object Vsystem_name;
119: Lisp_Object Vuser_real_login_name;
120: Lisp_Object Vuser_full_name;
121: Lisp_Object Vuser_login_name;
122: Lisp_Object Voperating_system_release;
123:
124:
125:
126: Lisp_Object Qfield;
127:
128:
129:
130: Lisp_Object Qboundary;
131:
132:
133: void
134: init_editfns ()
135: {
136: char *user_name;
137: register unsigned char *p;
138: struct passwd *pw;
139: Lisp_Object tem;
140:
141:
142: init_system_name ();
143:
144: #ifndef CANNOT_DUMP
145:
146: if (!initialized)
147: return;
148: #endif
149:
150: pw = (struct passwd *) getpwuid (getuid ());
151: #ifdef MSDOS
152:
153:
154:
155: Vuser_real_login_name = build_string (pw ? pw->pw_name : "root");
156: #else
157: Vuser_real_login_name = build_string (pw ? pw->pw_name : "unknown");
158: #endif
159:
160:
161:
162: user_name = (char *) getenv ("LOGNAME");
163: if (!user_name)
164: #ifdef WINDOWSNT
165: user_name = (char *) getenv ("USERNAME");
166: #else
167: user_name = (char *) getenv ("USER");
168: #endif
169: if (!user_name)
170: {
171: pw = (struct passwd *) getpwuid (geteuid ());
172: user_name = (char *) (pw ? pw->pw_name : "unknown");
173: }
174: Vuser_login_name = build_string (user_name);
175:
176:
177:
178: tem = Fstring_equal (Vuser_login_name, Vuser_real_login_name);
179: Vuser_full_name = Fuser_full_name (NILP (tem)? make_number (geteuid())
180: : Vuser_login_name);
181:
182: p = (unsigned char *) getenv ("NAME");
183: if (p)
184: Vuser_full_name = build_string (p);
185: else if (NILP (Vuser_full_name))
186: Vuser_full_name = build_string ("unknown");
187:
188: #ifdef HAVE_SYS_UTSNAME_H
189: {
190: struct utsname uts;
191: uname (&uts);
192: Voperating_system_release = build_string (uts.release);
193: }
194: #else
195: Voperating_system_release = Qnil;
196: #endif
197: }
198: ^L
199: DEFUN ("char-to-string", Fchar_to_string, Schar_to_string, 1, 1, 0,
200: doc:
201: )
202: (character)
203: Lisp_Object character;
204: {
205: int len;
206: unsigned char str[MAX_MULTIBYTE_LENGTH];
207:
208: CHECK_NUMBER (character);
209:
210: len = (SINGLE_BYTE_CHAR_P (XFASTINT (character))
211: ? (*str = (unsigned char)(XFASTINT (character)), 1)
212: : char_to_string (XFASTINT (character), str));
213: return make_string_from_bytes (str, 1, len);
214: }
215:
216: DEFUN ("string-to-char", Fstring_to_char, Sstring_to_char, 1, 1, 0,
217: doc:
218: )
219: (string)
220: register Lisp_Object string;
221: {
222: register Lisp_Object val;
223: CHECK_STRING (string);
224: if (SCHARS (string))
225: {
226: if (STRING_MULTIBYTE (string))
227: XSETFASTINT (val, STRING_CHAR (SDATA (string), SBYTES (string)));
228: else
229: XSETFASTINT (val, SREF (string, 0));
230: }
231: else
232: XSETFASTINT (val, 0);
233: return val;
234: }
235: ^L
236: static Lisp_Object
237: buildmark (charpos, bytepos)
238: int charpos, bytepos;
239: {
240: register Lisp_Object mark;
241: mark = Fmake_marker ();
242: set_marker_both (mark, Qnil, charpos, bytepos);
243: return mark;
244: }
245:
246: DEFUN ("point", Fpoint, Spoint, 0, 0, 0,
247: doc:
248: )
249: ()
250: {
251: Lisp_Object temp;
252: XSETFASTINT (temp, PT);
253: return temp;
254: }
255:
256: DEFUN ("point-marker", Fpoint_marker, Spoint_marker, 0, 0, 0,
257: doc: )
258: ()
259: {
260: return buildmark (PT, PT_BYTE);
261: }
262:
263: int
264: clip_to_bounds (lower, num, upper)
265: int lower, num, upper;
266: {
267: if (num < lower)
268: return lower;
269: else if (num > upper)
270: return upper;
271: else
272: return num;
273: }
274:
275: DEFUN ("goto-char", Fgoto_char, Sgoto_char, 1, 1, "NGoto char: ",
276: doc:
277:
278:
279: )
280: (position)
281: register Lisp_Object position;
282: {
283: int pos;
284:
285: if (MARKERP (position)
286: && current_buffer == XMARKER (position)->buffer)
287: {
288: pos = marker_position (position);
289: if (pos < BEGV)
290: SET_PT_BOTH (BEGV, BEGV_BYTE);
291: else if (pos > ZV)
292: SET_PT_BOTH (ZV, ZV_BYTE);
293: else
294: SET_PT_BOTH (pos, marker_byte_position (position));
295:
296: return position;
297: }
298:
299: CHECK_NUMBER_COERCE_MARKER (position);
300:
301: pos = clip_to_bounds (BEGV, XINT (position), ZV);
302: SET_PT (pos);
303: return position;
304: }
305:
306:
307:
308:
309:
310:
311: static Lisp_Object
312: region_limit (beginningp)
313: int beginningp;
314: {
315: extern Lisp_Object Vmark_even_if_inactive;
316: Lisp_Object m;
317:
318: if (!NILP (Vtransient_mark_mode)
319: && NILP (Vmark_even_if_inactive)
320: && NILP (current_buffer->mark_active))
321: xsignal0 (Qmark_inactive);
322:
323: m = Fmarker_position (current_buffer->mark);
324: if (NILP (m))
325: error ("The mark is not set now, so there is no region");
326:
327: if ((PT < XFASTINT (m)) == (beginningp != 0))
328: m = make_number (PT);
329: return m;
330: }
331:
332: DEFUN ("region-beginning", Fregion_beginning, Sregion_beginning, 0, 0, 0,
333: doc: )
334: ()
335: {
336: return region_limit (1);
337: }
338:
339: DEFUN ("region-end", Fregion_end, Sregion_end, 0, 0, 0,
340: doc: )
341: ()
342: {
343: return region_limit (0);
344: }
345:
346: DEFUN ("mark-marker", Fmark_marker, Smark_marker, 0, 0, 0,
347: doc:
348:
349: )
350: ()
351: {
352: return current_buffer->mark;
353: }
354:
355: ^L
356:
357:
358:
359:
360: static int
361: overlays_around (pos, vec, len)
362: int pos;
363: Lisp_Object *vec;
364: int len;
365: {
366: Lisp_Object overlay, start, end;
367: struct Lisp_Overlay *tail;
368: int startpos, endpos;
369: int idx = 0;
370:
371: for (tail = current_buffer->overlays_before; tail; tail = tail->next)
372: {
373: XSETMISC (overlay, tail);
374:
375: end = OVERLAY_END (overlay);
376: endpos = OVERLAY_POSITION (end);
377: if (endpos < pos)
378: break;
379: start = OVERLAY_START (overlay);
380: startpos = OVERLAY_POSITION (start);
381: if (startpos <= pos)
382: {
383: if (idx < len)
384: vec[idx] = overlay;
385:
386: idx++;
387: }
388: }
389:
390: for (tail = current_buffer->overlays_after; tail; tail = tail->next)
391: {
392: XSETMISC (overlay, tail);
393:
394: start = OVERLAY_START (overlay);
395: startpos = OVERLAY_POSITION (start);
396: if (pos < startpos)
397: break;
398: end = OVERLAY_END (overlay);
399: endpos = OVERLAY_POSITION (end);
400: if (pos <= endpos)
401: {
402: if (idx < len)
403: vec[idx] = overlay;
404: idx++;
405: }
406: }
407:
408: return idx;
409: }
410:
411:
412:
413:
414:
415:
416:
417:
418:
419: Lisp_Object
420: get_pos_property (position, prop, object)
421: Lisp_Object position, object;
422: register Lisp_Object prop;
423: {
424: CHECK_NUMBER_COERCE_MARKER (position);
425:
426: if (NILP (object))
427: XSETBUFFER (object, current_buffer);
428: else if (WINDOWP (object))
429: object = XWINDOW (object)->buffer;
430:
431: if (!BUFFERP (object))
432:
433:
434:
435: return Fget_text_property (position, prop, object);
436: else
437: {
438: int posn = XINT (position);
439: int noverlays;
440: Lisp_Object *overlay_vec, tem;
441: struct buffer *obuf = current_buffer;
442:
443: set_buffer_temp (XBUFFER (object));
444:
445:
446: noverlays = 40;
447: overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
448: noverlays = overlays_around (posn, overlay_vec, noverlays);
449:
450:
451:
452: if (noverlays > 40)
453: {
454: overlay_vec = (Lisp_Object *) alloca (noverlays * sizeof (Lisp_Object));
455: noverlays = overlays_around (posn, overlay_vec, noverlays);
456: }
457: noverlays = sort_overlays (overlay_vec, noverlays, NULL);
458:
459: set_buffer_temp (obuf);
460:
461:
462: while (--noverlays >= 0)
463: {
464: Lisp_Object ol = overlay_vec[noverlays];
465: tem = Foverlay_get (ol, prop);
466: if (!NILP (tem))
467: {
468:
469: Lisp_Object start = OVERLAY_START (ol), finish = OVERLAY_END (ol);
470: if ((OVERLAY_POSITION (start) == posn
471: && XMARKER (start)->insertion_type == 1)
472: || (OVERLAY_POSITION (finish) == posn
473: && XMARKER (finish)->insertion_type == 0))
474: ;
475: else
476: {
477: return tem;
478: }
479: }
480: }
481:
482: {
483: int stickiness = text_property_stickiness (prop, position, object);
484: if (stickiness > 0)
485: return Fget_text_property (position, prop, object);
486: else if (stickiness < 0
487: && XINT (position) > BUF_BEGV (XBUFFER (object)))
488: return Fget_text_property (make_number (XINT (position) - 1),
489: prop, object);
490: else
491: return Qnil;
492: }
493: }
494: }
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516: static void
517: find_field (pos, merge_at_boundary, beg_limit, beg, end_limit, end)
518: Lisp_Object pos;
519: Lisp_Object merge_at_boundary;
520: Lisp_Object beg_limit, end_limit;
521: int *beg, *end;
522: {
523:
524: Lisp_Object before_field, after_field;
525:
526: int at_field_start = 0;
527:
528: int at_field_end = 0;
529:
530: if (NILP (pos))
531: XSETFASTINT (pos, PT);
532: else
533: CHECK_NUMBER_COERCE_MARKER (pos);
534:
535: after_field
536: = get_char_property_and_overlay (pos, Qfield, Qnil, NULL);
537: before_field
538: = (XFASTINT (pos) > BEGV
539: ? get_char_property_and_overlay (make_number (XINT (pos) - 1),
540: Qfield, Qnil, NULL)
541:
542:
543: : after_field);
544:
545:
546:
547:
548:
549:
550:
551: if (NILP (merge_at_boundary))
552: {
553: Lisp_Object field = get_pos_property (pos, Qfield, Qnil);
554: if (!EQ (field, after_field))
555: at_field_end = 1;
556: if (!EQ (field, before_field))
557: at_field_start = 1;
558: if (NILP (field) && at_field_start && at_field_end)
559:
560:
561:
562:
563: at_field_end = at_field_start = 0;
564: }
565:
566:
567:
568:
569:
570:
571:
572:
573:
574:
575:
576:
577:
578:
579:
580:
581:
582:
583:
584:
585:
586:
587:
588: if (beg)