diff options
| author | Glenn Morris | 2013-12-17 19:21:48 -0800 |
|---|---|---|
| committer | Glenn Morris | 2013-12-17 19:21:48 -0800 |
| commit | 1f41ee56ace98fe0d5f288c97ddb73870befed45 (patch) | |
| tree | 6bee6711c5e9c8d2cc03d102b8bd5e1b27ba13c7 /src/lread.c | |
| parent | e82134b1e4efb363e21b1f9103af7ee5ec885ce4 (diff) | |
| download | emacs-1f41ee56ace98fe0d5f288c97ddb73870befed45.tar.gz emacs-1f41ee56ace98fe0d5f288c97ddb73870befed45.zip | |
Add load-prefer-newer option, to load .el if newer than .elc
* src/lread.c (Fload): Pass load_prefer_newer to openp.
Don't bother checking mtime if openp already did it.
(openp): Add `newer' argument, to check all suffixes
and find the newest file.
(syms_of_lread) <load_prefer_newer>: New option.
* src/callproc.c (call_process):
* src/charset.c (load_charset_map_from_file):
* src/emacs.c (init_cmdargs):
* src/image.c (x_create_bitmap_from_file, x_find_image_file):
* src/lisp.h (openp):
* lread.c (Flocate_file_internal):
* src/process.c (Fformat_network_address):
* src/sound.c (Fplay_sound_internal):
* src/w32.c (check_windows_init_file):
* src/w32proc.c (sys_spawnve): Update for new arg spec of openp.
* lisp/Makefile.in (BYTE_COMPILE_FLAGS): Set load-prefer-newer to t.
* etc/NEWS: Mention this.
Fixes: debbugs:2061
Diffstat (limited to 'src/lread.c')
| -rw-r--r-- | src/lread.c | 121 |
1 files changed, 84 insertions, 37 deletions
diff --git a/src/lread.c b/src/lread.c index 2bada06f2ad..c24af0cf9cd 100644 --- a/src/lread.c +++ b/src/lread.c | |||
| @@ -1129,7 +1129,7 @@ Return t if the file exists and loads successfully. */) | |||
| 1129 | } | 1129 | } |
| 1130 | } | 1130 | } |
| 1131 | 1131 | ||
| 1132 | fd = openp (Vload_path, file, suffixes, &found, Qnil); | 1132 | fd = openp (Vload_path, file, suffixes, &found, Qnil, load_prefer_newer); |
| 1133 | UNGCPRO; | 1133 | UNGCPRO; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| @@ -1252,29 +1252,36 @@ Return t if the file exists and loads successfully. */) | |||
| 1252 | #ifdef DOS_NT | 1252 | #ifdef DOS_NT |
| 1253 | fmode = "rb"; | 1253 | fmode = "rb"; |
| 1254 | #endif /* DOS_NT */ | 1254 | #endif /* DOS_NT */ |
| 1255 | result = stat (SSDATA (efound), &s1); | ||
| 1256 | if (result == 0) | ||
| 1257 | { | ||
| 1258 | SSET (efound, SBYTES (efound) - 1, 0); | ||
| 1259 | result = stat (SSDATA (efound), &s2); | ||
| 1260 | SSET (efound, SBYTES (efound) - 1, 'c'); | ||
| 1261 | } | ||
| 1262 | 1255 | ||
| 1263 | if (result == 0 | 1256 | /* openp already checked for newness, no point doing it again. |
| 1264 | && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0) | 1257 | FIXME would be nice to get a message when openp |
| 1265 | { | 1258 | ignores suffix order due to load_prefer_newer. */ |
| 1266 | /* Make the progress messages mention that source is newer. */ | 1259 | if (!load_prefer_newer) |
| 1267 | newer = 1; | 1260 | { |
| 1261 | result = stat (SSDATA (efound), &s1); | ||
| 1262 | if (result == 0) | ||
| 1263 | { | ||
| 1264 | SSET (efound, SBYTES (efound) - 1, 0); | ||
| 1265 | result = stat (SSDATA (efound), &s2); | ||
| 1266 | SSET (efound, SBYTES (efound) - 1, 'c'); | ||
| 1267 | } | ||
| 1268 | 1268 | ||
| 1269 | /* If we won't print another message, mention this anyway. */ | 1269 | if (result == 0 |
| 1270 | if (!NILP (nomessage) && !force_load_messages) | 1270 | && timespec_cmp (get_stat_mtime (&s1), get_stat_mtime (&s2)) < 0) |
| 1271 | { | 1271 | { |
| 1272 | Lisp_Object msg_file; | 1272 | /* Make the progress messages mention that source is newer. */ |
| 1273 | msg_file = Fsubstring (found, make_number (0), make_number (-1)); | 1273 | newer = 1; |
| 1274 | message_with_string ("Source file `%s' newer than byte-compiled file", | 1274 | |
| 1275 | msg_file, 1); | 1275 | /* If we won't print another message, mention this anyway. */ |
| 1276 | } | 1276 | if (!NILP (nomessage) && !force_load_messages) |
| 1277 | } | 1277 | { |
| 1278 | Lisp_Object msg_file; | ||
| 1279 | msg_file = Fsubstring (found, make_number (0), make_number (-1)); | ||
| 1280 | message_with_string ("Source file `%s' newer than byte-compiled file", | ||
| 1281 | msg_file, 1); | ||
| 1282 | } | ||
| 1283 | } | ||
| 1284 | } /* !load_prefer_newer */ | ||
| 1278 | UNGCPRO; | 1285 | UNGCPRO; |
| 1279 | } | 1286 | } |
| 1280 | } | 1287 | } |
| @@ -1413,7 +1420,7 @@ directories, make sure the PREDICATE function returns `dir-ok' for them. */) | |||
| 1413 | (Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate) | 1420 | (Lisp_Object filename, Lisp_Object path, Lisp_Object suffixes, Lisp_Object predicate) |
| 1414 | { | 1421 | { |
| 1415 | Lisp_Object file; | 1422 | Lisp_Object file; |
| 1416 | int fd = openp (path, filename, suffixes, &file, predicate); | 1423 | int fd = openp (path, filename, suffixes, &file, predicate, 0); |
| 1417 | if (NILP (predicate) && fd >= 0) | 1424 | if (NILP (predicate) && fd >= 0) |
| 1418 | emacs_close (fd); | 1425 | emacs_close (fd); |
| 1419 | return file; | 1426 | return file; |
| @@ -1440,11 +1447,14 @@ static Lisp_Object Qdir_ok; | |||
| 1440 | nil is stored there on failure. | 1447 | nil is stored there on failure. |
| 1441 | 1448 | ||
| 1442 | If the file we find is remote, return -2 | 1449 | If the file we find is remote, return -2 |
| 1443 | but store the found remote file name in *STOREPTR. */ | 1450 | but store the found remote file name in *STOREPTR. |
| 1451 | |||
| 1452 | If NEWER is true, try all SUFFIXes and return the result for the | ||
| 1453 | newest file that exists. Does not apply to remote files. */ | ||
| 1444 | 1454 | ||
| 1445 | int | 1455 | int |
| 1446 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, | 1456 | openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, |
| 1447 | Lisp_Object *storeptr, Lisp_Object predicate) | 1457 | Lisp_Object *storeptr, Lisp_Object predicate, int newer) |
| 1448 | { | 1458 | { |
| 1449 | ptrdiff_t fn_size = 100; | 1459 | ptrdiff_t fn_size = 100; |
| 1450 | char buf[100]; | 1460 | char buf[100]; |
| @@ -1453,9 +1463,11 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, | |||
| 1453 | ptrdiff_t want_length; | 1463 | ptrdiff_t want_length; |
| 1454 | Lisp_Object filename; | 1464 | Lisp_Object filename; |
| 1455 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; | 1465 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5, gcpro6; |
| 1456 | Lisp_Object string, tail, encoded_fn; | 1466 | Lisp_Object string, tail, encoded_fn, save_string; |
| 1457 | ptrdiff_t max_suffix_len = 0; | 1467 | ptrdiff_t max_suffix_len = 0; |
| 1458 | int last_errno = ENOENT; | 1468 | int last_errno = ENOENT; |
| 1469 | struct timespec save_mtime; | ||
| 1470 | int save_fd = 0; | ||
| 1459 | 1471 | ||
| 1460 | CHECK_STRING (str); | 1472 | CHECK_STRING (str); |
| 1461 | 1473 | ||
| @@ -1556,17 +1568,18 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, | |||
| 1556 | 1568 | ||
| 1557 | if (exists) | 1569 | if (exists) |
| 1558 | { | 1570 | { |
| 1559 | /* We succeeded; return this descriptor and filename. */ | 1571 | /* We succeeded; return this descriptor and filename. */ |
| 1560 | if (storeptr) | 1572 | if (storeptr) |
| 1561 | *storeptr = string; | 1573 | *storeptr = string; |
| 1562 | UNGCPRO; | 1574 | UNGCPRO; |
| 1563 | return -2; | 1575 | return -2; |
| 1564 | } | 1576 | } |
| 1565 | } | 1577 | } |
| 1566 | else | 1578 | else |
| 1567 | { | 1579 | { |
| 1568 | int fd; | 1580 | int fd; |
| 1569 | const char *pfn; | 1581 | const char *pfn; |
| 1582 | struct stat st; | ||
| 1570 | 1583 | ||
| 1571 | encoded_fn = ENCODE_FILE (string); | 1584 | encoded_fn = ENCODE_FILE (string); |
| 1572 | pfn = SSDATA (encoded_fn); | 1585 | pfn = SSDATA (encoded_fn); |
| @@ -1597,7 +1610,6 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, | |||
| 1597 | } | 1610 | } |
| 1598 | else | 1611 | else |
| 1599 | { | 1612 | { |
| 1600 | struct stat st; | ||
| 1601 | int err = (fstat (fd, &st) != 0 ? errno | 1613 | int err = (fstat (fd, &st) != 0 ? errno |
| 1602 | : S_ISDIR (st.st_mode) ? EISDIR : 0); | 1614 | : S_ISDIR (st.st_mode) ? EISDIR : 0); |
| 1603 | if (err) | 1615 | if (err) |
| @@ -1611,12 +1623,36 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes, | |||
| 1611 | 1623 | ||
| 1612 | if (fd >= 0) | 1624 | if (fd >= 0) |
| 1613 | { | 1625 | { |
| 1614 | /* We succeeded; return this descriptor and filename. */ | 1626 | if (newer) |
| 1615 | if (storeptr) | 1627 | { |
| 1616 | *storeptr = string; | 1628 | struct timespec mtime = get_stat_mtime (&st); |
| 1617 | UNGCPRO; | 1629 | |
| 1618 | return fd; | 1630 | if (!save_fd || timespec_cmp (save_mtime, mtime) < 0) |
| 1631 | { | ||
| 1632 | if (save_fd) emacs_close (save_fd); | ||
| 1633 | save_fd = fd; | ||
| 1634 | save_mtime = mtime; | ||
| 1635 | save_string = string; | ||
| 1636 | } | ||
| 1637 | } | ||
| 1638 | else | ||
| 1639 | { | ||
| 1640 | /* We succeeded; return this descriptor and filename. */ | ||
| 1641 | if (storeptr) | ||
| 1642 | *storeptr = string; | ||
| 1643 | UNGCPRO; | ||
| 1644 | return fd; | ||
| 1645 | } | ||
| 1619 | } | 1646 | } |
| 1647 | |||
| 1648 | /* No more suffixes. Return the newest. */ | ||
| 1649 | if (newer && save_fd && ! CONSP (XCDR (tail))) | ||
| 1650 | { | ||
| 1651 | if (storeptr) | ||
| 1652 | *storeptr = save_string; | ||
| 1653 | UNGCPRO; | ||
| 1654 | return save_fd; | ||
| 1655 | } | ||
| 1620 | } | 1656 | } |
| 1621 | } | 1657 | } |
| 1622 | if (absolute) | 1658 | if (absolute) |
| @@ -4632,6 +4668,17 @@ variables, this must be set in the first line of a file. */); | |||
| 4632 | Vold_style_backquotes = Qnil; | 4668 | Vold_style_backquotes = Qnil; |
| 4633 | DEFSYM (Qold_style_backquotes, "old-style-backquotes"); | 4669 | DEFSYM (Qold_style_backquotes, "old-style-backquotes"); |
| 4634 | 4670 | ||
| 4671 | DEFVAR_BOOL ("load-prefer-newer", load_prefer_newer, | ||
| 4672 | doc: /* Non-nil means `load' prefers the newest version of a file. | ||
| 4673 | This applies when a filename suffix is not explicitly specified and | ||
| 4674 | `load' is trying various possible suffixes (see `load-suffixes' and | ||
| 4675 | `load-file-rep-suffixes'). Normally, it stops at the first file | ||
| 4676 | that exists. If this option is non-nil, it checks all suffixes and | ||
| 4677 | uses whichever file is newest. | ||
| 4678 | Note that if you customize this, obviously it will not affect files | ||
| 4679 | that are loaded before your customizations are read! */); | ||
| 4680 | load_prefer_newer = 0; | ||
| 4681 | |||
| 4635 | /* Vsource_directory was initialized in init_lread. */ | 4682 | /* Vsource_directory was initialized in init_lread. */ |
| 4636 | 4683 | ||
| 4637 | DEFSYM (Qcurrent_load_list, "current-load-list"); | 4684 | DEFSYM (Qcurrent_load_list, "current-load-list"); |