diff options
| author | Stefan Monnier | 2022-08-03 17:02:25 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2022-08-03 17:02:25 -0400 |
| commit | 9e9b0e13bc8fbf716bb48e68bb642b130ff41fed (patch) | |
| tree | b605248e36d2c48892ee6a4cf363d5eb1d80aa63 /lib-src | |
| parent | eb2f39428935aa6ea42bc12272df8f43da7cde6c (diff) | |
| download | emacs-9e9b0e13bc8fbf716bb48e68bb642b130ff41fed.tar.gz emacs-9e9b0e13bc8fbf716bb48e68bb642b130ff41fed.zip | |
Revert "Revert part of 59732a83c8 to fix bug#52969"
This reverts commit 460f35e96df1c39ce2ba0f424b36365a2f9e9825.
Re-remove the code that scans .el files for docstrings, now
that even `lisp/loaddefs.el` is compiled.
* lib-src/make-docfile.c (scan_file): Don't call `scan_lisp_file`.
(scan_lisp_file, skip_white, read_lisp_symbol, search_lisp_doc_at_eol):
Delete functions.
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/make-docfile.c | 360 |
1 files changed, 3 insertions, 357 deletions
diff --git a/lib-src/make-docfile.c b/lib-src/make-docfile.c index 908d73f5253..b5beffce19a 100644 --- a/lib-src/make-docfile.c +++ b/lib-src/make-docfile.c | |||
| @@ -19,8 +19,8 @@ You should have received a copy of the GNU General Public License | |||
| 19 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | 19 | along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ |
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | /* The arguments given to this program are all the C and some Lisp source files | 22 | /* The arguments given to this program are all the C files |
| 23 | of GNU Emacs. .el and .c files are allowed. | 23 | of GNU Emacs. .c files are allowed. |
| 24 | A .o file can also be specified; the .c file it was made from is used. | 24 | A .o file can also be specified; the .c file it was made from is used. |
| 25 | This helps the makefile pass the correct list of files. | 25 | This helps the makefile pass the correct list of files. |
| 26 | Option -d DIR means change to DIR before looking for files. | 26 | Option -d DIR means change to DIR before looking for files. |
| @@ -66,7 +66,6 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */ | |||
| 66 | #endif /* not DOS_NT */ | 66 | #endif /* not DOS_NT */ |
| 67 | 67 | ||
| 68 | static void scan_file (char *filename); | 68 | static void scan_file (char *filename); |
| 69 | static void scan_lisp_file (const char *filename, const char *mode); | ||
| 70 | static void scan_c_file (char *filename, const char *mode); | 69 | static void scan_c_file (char *filename, const char *mode); |
| 71 | static void scan_c_stream (FILE *infile); | 70 | static void scan_c_stream (FILE *infile); |
| 72 | static void start_globals (void); | 71 | static void start_globals (void); |
| @@ -236,14 +235,9 @@ put_filename (char *filename) | |||
| 236 | static void | 235 | static void |
| 237 | scan_file (char *filename) | 236 | scan_file (char *filename) |
| 238 | { | 237 | { |
| 239 | ptrdiff_t len = strlen (filename); | ||
| 240 | |||
| 241 | if (!generate_globals) | 238 | if (!generate_globals) |
| 242 | put_filename (filename); | 239 | put_filename (filename); |
| 243 | if (len > 3 && !strcmp (filename + len - 3, ".el")) | 240 | scan_c_file (filename, "r"); |
| 244 | scan_lisp_file (filename, "r"); | ||
| 245 | else | ||
| 246 | scan_c_file (filename, "r"); | ||
| 247 | } | 241 | } |
| 248 | 242 | ||
| 249 | static void | 243 | static void |
| @@ -1221,352 +1215,4 @@ scan_c_stream (FILE *infile) | |||
| 1221 | fatal ("read error"); | 1215 | fatal ("read error"); |
| 1222 | } | 1216 | } |
| 1223 | 1217 | ||
| 1224 | /* Read a file of Lisp source code. | ||
| 1225 | Looks for | ||
| 1226 | (defun NAME ARGS DOCSTRING ...) | ||
| 1227 | (defmacro NAME ARGS DOCSTRING ...) | ||
| 1228 | (defsubst NAME ARGS DOCSTRING ...) | ||
| 1229 | (autoload (quote NAME) FILE DOCSTRING ...) | ||
| 1230 | (defvar NAME VALUE DOCSTRING) | ||
| 1231 | (defconst NAME VALUE DOCSTRING) | ||
| 1232 | (fset (quote NAME) (make-byte-code ... DOCSTRING ...)) | ||
| 1233 | (fset (quote NAME) #[... DOCSTRING ...]) | ||
| 1234 | (defalias (quote NAME) #[... DOCSTRING ...]) | ||
| 1235 | (custom-declare-variable (quote NAME) VALUE DOCSTRING ...) | ||
| 1236 | starting in column zero. | ||
| 1237 | (quote NAME) may appear as 'NAME as well. | ||
| 1238 | |||
| 1239 | We also look for #@LENGTH CONTENTS^_ at the beginning of the line. | ||
| 1240 | When we find that, we save it for the following defining-form, | ||
| 1241 | and we use that instead of reading a doc string within that defining-form. | ||
| 1242 | |||
| 1243 | For defvar, defconst, and fset we skip to the docstring with a kludgy | ||
| 1244 | formatting convention: all docstrings must appear on the same line as the | ||
| 1245 | initial open-paren (the one in column zero) and must contain a backslash | ||
| 1246 | and a newline immediately after the initial double-quote. No newlines | ||
| 1247 | must appear between the beginning of the form and the first double-quote. | ||
| 1248 | For defun, defmacro, and autoload, we know how to skip over the | ||
| 1249 | arglist, but the doc string must still have a backslash and newline | ||
| 1250 | immediately after the double quote. | ||
| 1251 | The only source files that follow this convention are autoload-generated | ||
| 1252 | files like loaddefs.el; | ||
| 1253 | The NAME and DOCSTRING are output. | ||
| 1254 | NAME is preceded by `F' for a function or `V' for a variable. | ||
| 1255 | An entry is output only if DOCSTRING has \ newline just after the opening ". | ||
| 1256 | */ | ||
| 1257 | |||
| 1258 | static void | ||
| 1259 | skip_white (FILE *infile) | ||
| 1260 | { | ||
| 1261 | int c; | ||
| 1262 | do | ||
| 1263 | c = getc (infile); | ||
| 1264 | while (c_isspace (c)); | ||
| 1265 | |||
| 1266 | ungetc (c, infile); | ||
| 1267 | } | ||
| 1268 | |||
| 1269 | static void | ||
| 1270 | read_lisp_symbol (FILE *infile, char *buffer) | ||
| 1271 | { | ||
| 1272 | int c; | ||
| 1273 | char *fillp = buffer; | ||
| 1274 | |||
| 1275 | skip_white (infile); | ||
| 1276 | while (true) | ||
| 1277 | { | ||
| 1278 | c = getc (infile); | ||
| 1279 | if (c == '\\') | ||
| 1280 | { | ||
| 1281 | c = getc (infile); | ||
| 1282 | if (c < 0) | ||
| 1283 | return; | ||
| 1284 | *fillp++ = c; | ||
| 1285 | } | ||
| 1286 | else if (c_isspace (c) || c == '(' || c == ')' || c < 0) | ||
| 1287 | { | ||
| 1288 | ungetc (c, infile); | ||
| 1289 | *fillp = 0; | ||
| 1290 | break; | ||
| 1291 | } | ||
| 1292 | else | ||
| 1293 | *fillp++ = c; | ||
| 1294 | } | ||
| 1295 | |||
| 1296 | if (! buffer[0]) | ||
| 1297 | fprintf (stderr, "## expected a symbol, got '%c'\n", c); | ||
| 1298 | |||
| 1299 | skip_white (infile); | ||
| 1300 | } | ||
| 1301 | |||
| 1302 | static bool | ||
| 1303 | search_lisp_doc_at_eol (FILE *infile) | ||
| 1304 | { | ||
| 1305 | int c = 0, c1 = 0, c2 = 0; | ||
| 1306 | |||
| 1307 | /* Skip until the end of line; remember two previous chars. */ | ||
| 1308 | while (c != '\n' && c != '\r' && c != EOF) | ||
| 1309 | { | ||
| 1310 | c2 = c1; | ||
| 1311 | c1 = c; | ||
| 1312 | c = getc (infile); | ||
| 1313 | } | ||
| 1314 | |||
| 1315 | /* If two previous characters were " and \, | ||
| 1316 | this is a doc string. Otherwise, there is none. */ | ||
| 1317 | if (c2 != '"' || c1 != '\\') | ||
| 1318 | { | ||
| 1319 | #ifdef DEBUG | ||
| 1320 | fprintf (stderr, "## non-docstring found\n"); | ||
| 1321 | #endif | ||
| 1322 | ungetc (c, infile); | ||
| 1323 | return false; | ||
| 1324 | } | ||
| 1325 | return true; | ||
| 1326 | } | ||
| 1327 | |||
| 1328 | static void | ||
| 1329 | scan_lisp_file (const char *filename, const char *mode) | ||
| 1330 | { | ||
| 1331 | FILE *infile; | ||
| 1332 | int c; | ||
| 1333 | |||
| 1334 | if (generate_globals) | ||
| 1335 | fatal ("scanning lisp file when -g specified"); | ||
| 1336 | |||
| 1337 | infile = fopen (filename, mode); | ||
| 1338 | if (infile == NULL) | ||
| 1339 | { | ||
| 1340 | perror (filename); | ||
| 1341 | exit (EXIT_FAILURE); | ||
| 1342 | } | ||
| 1343 | |||
| 1344 | c = '\n'; | ||
| 1345 | while (!feof (infile)) | ||
| 1346 | { | ||
| 1347 | char buffer[BUFSIZ]; | ||
| 1348 | char type; | ||
| 1349 | |||
| 1350 | /* If not at end of line, skip till we get to one. */ | ||
| 1351 | if (c != '\n' && c != '\r') | ||
| 1352 | { | ||
| 1353 | c = getc (infile); | ||
| 1354 | continue; | ||
| 1355 | } | ||
| 1356 | /* Skip the line break. */ | ||
| 1357 | while (c == '\n' || c == '\r') | ||
| 1358 | c = getc (infile); | ||
| 1359 | |||
| 1360 | if (c != '(') | ||
| 1361 | continue; | ||
| 1362 | |||
| 1363 | read_lisp_symbol (infile, buffer); | ||
| 1364 | |||
| 1365 | if (! strcmp (buffer, "defun") | ||
| 1366 | || ! strcmp (buffer, "defmacro") | ||
| 1367 | || ! strcmp (buffer, "defsubst")) | ||
| 1368 | { | ||
| 1369 | type = 'F'; | ||
| 1370 | read_lisp_symbol (infile, buffer); | ||
| 1371 | |||
| 1372 | /* Skip the arguments: either "nil" or a list in parens. */ | ||
| 1373 | |||
| 1374 | c = getc (infile); | ||
| 1375 | if (c == 'n') /* nil */ | ||
| 1376 | { | ||
| 1377 | if ((c = getc (infile)) != 'i' | ||
| 1378 | || (c = getc (infile)) != 'l') | ||
| 1379 | { | ||
| 1380 | fprintf (stderr, "## unparsable arglist in %s (%s)\n", | ||
| 1381 | buffer, filename); | ||
| 1382 | continue; | ||
| 1383 | } | ||
| 1384 | } | ||
| 1385 | else if (c != '(') | ||
| 1386 | { | ||
| 1387 | fprintf (stderr, "## unparsable arglist in %s (%s)\n", | ||
| 1388 | buffer, filename); | ||
| 1389 | continue; | ||
| 1390 | } | ||
| 1391 | else | ||
| 1392 | while (! (c == ')' || c < 0)) | ||
| 1393 | c = getc (infile); | ||
| 1394 | skip_white (infile); | ||
| 1395 | |||
| 1396 | /* If the next three characters aren't `dquote bslash newline' | ||
| 1397 | then we're not reading a docstring. | ||
| 1398 | */ | ||
| 1399 | if ((c = getc (infile)) != '"' | ||
| 1400 | || (c = getc (infile)) != '\\' | ||
| 1401 | || ((c = getc (infile)) != '\n' && c != '\r')) | ||
| 1402 | { | ||
| 1403 | #ifdef DEBUG | ||
| 1404 | fprintf (stderr, "## non-docstring in %s (%s)\n", | ||
| 1405 | buffer, filename); | ||
| 1406 | #endif | ||
| 1407 | continue; | ||
| 1408 | } | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | else if (! strcmp (buffer, "defvar") | ||
| 1412 | || ! strcmp (buffer, "defconst") | ||
| 1413 | || ! strcmp (buffer, "defcustom")) | ||
| 1414 | { | ||
| 1415 | type = 'V'; | ||
| 1416 | read_lisp_symbol (infile, buffer); | ||
| 1417 | |||
| 1418 | if (!search_lisp_doc_at_eol (infile)) | ||
| 1419 | continue; | ||
| 1420 | } | ||
| 1421 | |||
| 1422 | else if (! strcmp (buffer, "custom-declare-variable") | ||
| 1423 | || ! strcmp (buffer, "defvaralias") | ||
| 1424 | ) | ||
| 1425 | { | ||
| 1426 | type = 'V'; | ||
| 1427 | |||
| 1428 | c = getc (infile); | ||
| 1429 | if (c == '\'') | ||
| 1430 | read_lisp_symbol (infile, buffer); | ||
| 1431 | else | ||
| 1432 | { | ||
| 1433 | if (c != '(') | ||
| 1434 | { | ||
| 1435 | fprintf (stderr, | ||
| 1436 | "## unparsable name in custom-declare-variable in %s\n", | ||
| 1437 | filename); | ||
| 1438 | continue; | ||
| 1439 | } | ||
| 1440 | read_lisp_symbol (infile, buffer); | ||
| 1441 | if (strcmp (buffer, "quote")) | ||
| 1442 | { | ||
| 1443 | fprintf (stderr, | ||
| 1444 | "## unparsable name in custom-declare-variable in %s\n", | ||
| 1445 | filename); | ||
| 1446 | continue; | ||
| 1447 | } | ||
| 1448 | read_lisp_symbol (infile, buffer); | ||
| 1449 | c = getc (infile); | ||
| 1450 | if (c != ')') | ||
| 1451 | { | ||
| 1452 | fprintf (stderr, | ||
| 1453 | "## unparsable quoted name in custom-declare-variable in %s\n", | ||
| 1454 | filename); | ||
| 1455 | continue; | ||
| 1456 | } | ||
| 1457 | } | ||
| 1458 | |||
| 1459 | if (!search_lisp_doc_at_eol (infile)) | ||
| 1460 | continue; | ||
| 1461 | } | ||
| 1462 | |||
| 1463 | else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias")) | ||
| 1464 | { | ||
| 1465 | type = 'F'; | ||
| 1466 | |||
| 1467 | c = getc (infile); | ||
| 1468 | if (c == '\'') | ||
| 1469 | read_lisp_symbol (infile, buffer); | ||
| 1470 | else | ||
| 1471 | { | ||
| 1472 | if (c != '(') | ||
| 1473 | { | ||
| 1474 | fprintf (stderr, "## unparsable name in fset in %s\n", | ||
| 1475 | filename); | ||
| 1476 | continue; | ||
| 1477 | } | ||
| 1478 | read_lisp_symbol (infile, buffer); | ||
| 1479 | if (strcmp (buffer, "quote")) | ||
| 1480 | { | ||
| 1481 | fprintf (stderr, "## unparsable name in fset in %s\n", | ||
| 1482 | filename); | ||
| 1483 | continue; | ||
| 1484 | } | ||
| 1485 | read_lisp_symbol (infile, buffer); | ||
| 1486 | c = getc (infile); | ||
| 1487 | if (c != ')') | ||
| 1488 | { | ||
| 1489 | fprintf (stderr, | ||
| 1490 | "## unparsable quoted name in fset in %s\n", | ||
| 1491 | filename); | ||
| 1492 | continue; | ||
| 1493 | } | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | if (!search_lisp_doc_at_eol (infile)) | ||
| 1497 | continue; | ||
| 1498 | } | ||
| 1499 | |||
| 1500 | else if (! strcmp (buffer, "autoload")) | ||
| 1501 | { | ||
| 1502 | type = 'F'; | ||
| 1503 | c = getc (infile); | ||
| 1504 | if (c == '\'') | ||
| 1505 | read_lisp_symbol (infile, buffer); | ||
| 1506 | else | ||
| 1507 | { | ||
| 1508 | if (c != '(') | ||
| 1509 | { | ||
| 1510 | fprintf (stderr, "## unparsable name in autoload in %s\n", | ||
| 1511 | filename); | ||
| 1512 | continue; | ||
| 1513 | } | ||
| 1514 | read_lisp_symbol (infile, buffer); | ||
| 1515 | if (strcmp (buffer, "quote")) | ||
| 1516 | { | ||
| 1517 | fprintf (stderr, "## unparsable name in autoload in %s\n", | ||
| 1518 | filename); | ||
| 1519 | continue; | ||
| 1520 | } | ||
| 1521 | read_lisp_symbol (infile, buffer); | ||
| 1522 | c = getc (infile); | ||
| 1523 | if (c != ')') | ||
| 1524 | { | ||
| 1525 | fprintf (stderr, | ||
| 1526 | "## unparsable quoted name in autoload in %s\n", | ||
| 1527 | filename); | ||
| 1528 | continue; | ||
| 1529 | } | ||
| 1530 | } | ||
| 1531 | skip_white (infile); | ||
| 1532 | c = getc (infile); | ||
| 1533 | if (c != '\"') | ||
| 1534 | { | ||
| 1535 | fprintf (stderr, "## autoload of %s unparsable (%s)\n", | ||
| 1536 | buffer, filename); | ||
| 1537 | continue; | ||
| 1538 | } | ||
| 1539 | read_c_string_or_comment (infile, 0, false, 0); | ||
| 1540 | |||
| 1541 | if (!search_lisp_doc_at_eol (infile)) | ||
| 1542 | continue; | ||
| 1543 | } | ||
| 1544 | |||
| 1545 | #ifdef DEBUG | ||
| 1546 | else if (! strcmp (buffer, "if") | ||
| 1547 | || ! strcmp (buffer, "byte-code")) | ||
| 1548 | continue; | ||
| 1549 | #endif | ||
| 1550 | |||
| 1551 | else | ||
| 1552 | { | ||
| 1553 | #ifdef DEBUG | ||
| 1554 | fprintf (stderr, "## unrecognized top-level form, %s (%s)\n", | ||
| 1555 | buffer, filename); | ||
| 1556 | #endif | ||
| 1557 | continue; | ||
| 1558 | } | ||
| 1559 | |||
| 1560 | /* At this point, we should gobble a doc string from the input file. | ||
| 1561 | The opening quote (and leading backslash-newline) | ||
| 1562 | have already been read. */ | ||
| 1563 | |||
| 1564 | printf ("\037%c%s\n", type, buffer); | ||
| 1565 | read_c_string_or_comment (infile, 1, false, 0); | ||
| 1566 | } | ||
| 1567 | if (ferror (infile) || fclose (infile) != 0) | ||
| 1568 | fatal ("%s: read error", filename); | ||
| 1569 | } | ||
| 1570 | |||
| 1571 | |||
| 1572 | /* make-docfile.c ends here */ | 1218 | /* make-docfile.c ends here */ |