Mercurial > vim
comparison src/spellfile.c @ 18814:7e7ec935e7c8 v8.1.2395
patch 8.1.2395: using old C style comments
Commit: https://github.com/vim/vim/commit/0d6f5d9740dbad1b0207f3ab257de806169dd905
Author: Bram Moolenaar <Bram@vim.org>
Date: Thu Dec 5 21:33:15 2019 +0100
patch 8.1.2395: using old C style comments
Problem: Using old C style comments.
Solution: Use // comments where appropriate.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 05 Dec 2019 21:45:04 +0100 |
parents | 4fbfecbb968c |
children | 847cc7932c42 |
comparison
equal
deleted
inserted
replaced
18813:89d78230790e | 18814:7e7ec935e7c8 |
---|---|
239 | 239 |
240 #include "vim.h" | 240 #include "vim.h" |
241 | 241 |
242 #if defined(FEAT_SPELL) || defined(PROTO) | 242 #if defined(FEAT_SPELL) || defined(PROTO) |
243 | 243 |
244 #ifndef UNIX /* it's in os_unix.h for Unix */ | 244 #ifndef UNIX // it's in os_unix.h for Unix |
245 # include <time.h> /* for time_t */ | 245 # include <time.h> // for time_t |
246 #endif | 246 #endif |
247 | 247 |
248 #ifndef UNIX /* it's in os_unix.h for Unix */ | 248 #ifndef UNIX // it's in os_unix.h for Unix |
249 # include <time.h> /* for time_t */ | 249 # include <time.h> // for time_t |
250 #endif | 250 #endif |
251 | 251 |
252 /* Special byte values for <byte>. Some are only used in the tree for | 252 // Special byte values for <byte>. Some are only used in the tree for |
253 * postponed prefixes, some only in the other trees. This is a bit messy... */ | 253 // postponed prefixes, some only in the other trees. This is a bit messy... |
254 #define BY_NOFLAGS 0 /* end of word without flags or region; for | 254 #define BY_NOFLAGS 0 // end of word without flags or region; for |
255 * postponed prefix: no <pflags> */ | 255 // postponed prefix: no <pflags> |
256 #define BY_INDEX 1 /* child is shared, index follows */ | 256 #define BY_INDEX 1 // child is shared, index follows |
257 #define BY_FLAGS 2 /* end of word, <flags> byte follows; for | 257 #define BY_FLAGS 2 // end of word, <flags> byte follows; for |
258 * postponed prefix: <pflags> follows */ | 258 // postponed prefix: <pflags> follows |
259 #define BY_FLAGS2 3 /* end of word, <flags> and <flags2> bytes | 259 #define BY_FLAGS2 3 // end of word, <flags> and <flags2> bytes |
260 * follow; never used in prefix tree */ | 260 // follow; never used in prefix tree |
261 #define BY_SPECIAL BY_FLAGS2 /* highest special byte value */ | 261 #define BY_SPECIAL BY_FLAGS2 // highest special byte value |
262 | 262 |
263 #define ZERO_FLAG 65009 // used when flag is zero: "0" | 263 #define ZERO_FLAG 65009 // used when flag is zero: "0" |
264 | 264 |
265 /* Flags used in .spl file for soundsalike flags. */ | 265 // Flags used in .spl file for soundsalike flags. |
266 #define SAL_F0LLOWUP 1 | 266 #define SAL_F0LLOWUP 1 |
267 #define SAL_COLLAPSE 2 | 267 #define SAL_COLLAPSE 2 |
268 #define SAL_REM_ACCENTS 4 | 268 #define SAL_REM_ACCENTS 4 |
269 | 269 |
270 #define VIMSPELLMAGIC "VIMspell" /* string at start of Vim spell file */ | 270 #define VIMSPELLMAGIC "VIMspell" // string at start of Vim spell file |
271 #define VIMSPELLMAGICL 8 | 271 #define VIMSPELLMAGICL 8 |
272 #define VIMSPELLVERSION 50 | 272 #define VIMSPELLVERSION 50 |
273 | 273 |
274 /* Section IDs. Only renumber them when VIMSPELLVERSION changes! */ | 274 // Section IDs. Only renumber them when VIMSPELLVERSION changes! |
275 #define SN_REGION 0 /* <regionname> section */ | 275 #define SN_REGION 0 // <regionname> section |
276 #define SN_CHARFLAGS 1 /* charflags section */ | 276 #define SN_CHARFLAGS 1 // charflags section |
277 #define SN_MIDWORD 2 /* <midword> section */ | 277 #define SN_MIDWORD 2 // <midword> section |
278 #define SN_PREFCOND 3 /* <prefcond> section */ | 278 #define SN_PREFCOND 3 // <prefcond> section |
279 #define SN_REP 4 /* REP items section */ | 279 #define SN_REP 4 // REP items section |
280 #define SN_SAL 5 /* SAL items section */ | 280 #define SN_SAL 5 // SAL items section |
281 #define SN_SOFO 6 /* soundfolding section */ | 281 #define SN_SOFO 6 // soundfolding section |
282 #define SN_MAP 7 /* MAP items section */ | 282 #define SN_MAP 7 // MAP items section |
283 #define SN_COMPOUND 8 /* compound words section */ | 283 #define SN_COMPOUND 8 // compound words section |
284 #define SN_SYLLABLE 9 /* syllable section */ | 284 #define SN_SYLLABLE 9 // syllable section |
285 #define SN_NOBREAK 10 /* NOBREAK section */ | 285 #define SN_NOBREAK 10 // NOBREAK section |
286 #define SN_SUGFILE 11 /* timestamp for .sug file */ | 286 #define SN_SUGFILE 11 // timestamp for .sug file |
287 #define SN_REPSAL 12 /* REPSAL items section */ | 287 #define SN_REPSAL 12 // REPSAL items section |
288 #define SN_WORDS 13 /* common words */ | 288 #define SN_WORDS 13 // common words |
289 #define SN_NOSPLITSUGS 14 /* don't split word for suggestions */ | 289 #define SN_NOSPLITSUGS 14 // don't split word for suggestions |
290 #define SN_INFO 15 /* info section */ | 290 #define SN_INFO 15 // info section |
291 #define SN_NOCOMPOUNDSUGS 16 /* don't compound for suggestions */ | 291 #define SN_NOCOMPOUNDSUGS 16 // don't compound for suggestions |
292 #define SN_END 255 /* end of sections */ | 292 #define SN_END 255 // end of sections |
293 | 293 |
294 #define SNF_REQUIRED 1 /* <sectionflags>: required section */ | 294 #define SNF_REQUIRED 1 // <sectionflags>: required section |
295 | 295 |
296 #define CF_WORD 0x01 | 296 #define CF_WORD 0x01 |
297 #define CF_UPPER 0x02 | 297 #define CF_UPPER 0x02 |
298 | 298 |
299 static int set_spell_finish(spelltab_T *new_st); | 299 static int set_spell_finish(spelltab_T *new_st); |
339 slang_T * | 339 slang_T * |
340 spell_load_file( | 340 spell_load_file( |
341 char_u *fname, | 341 char_u *fname, |
342 char_u *lang, | 342 char_u *lang, |
343 slang_T *old_lp, | 343 slang_T *old_lp, |
344 int silent) /* no error if file doesn't exist */ | 344 int silent) // no error if file doesn't exist |
345 { | 345 { |
346 FILE *fd; | 346 FILE *fd; |
347 char_u buf[VIMSPELLMAGICL]; | 347 char_u buf[VIMSPELLMAGICL]; |
348 char_u *p; | 348 char_u *p; |
349 int i; | 349 int i; |
379 { | 379 { |
380 lp = slang_alloc(lang); | 380 lp = slang_alloc(lang); |
381 if (lp == NULL) | 381 if (lp == NULL) |
382 goto endFAIL; | 382 goto endFAIL; |
383 | 383 |
384 /* Remember the file name, used to reload the file when it's updated. */ | 384 // Remember the file name, used to reload the file when it's updated. |
385 lp->sl_fname = vim_strsave(fname); | 385 lp->sl_fname = vim_strsave(fname); |
386 if (lp->sl_fname == NULL) | 386 if (lp->sl_fname == NULL) |
387 goto endFAIL; | 387 goto endFAIL; |
388 | 388 |
389 /* Check for .add.spl (_add.spl for VMS). */ | 389 // Check for .add.spl (_add.spl for VMS). |
390 lp->sl_add = strstr((char *)gettail(fname), SPL_FNAME_ADD) != NULL; | 390 lp->sl_add = strstr((char *)gettail(fname), SPL_FNAME_ADD) != NULL; |
391 } | 391 } |
392 else | 392 else |
393 lp = old_lp; | 393 lp = old_lp; |
394 | 394 |
395 /* Set sourcing_name, so that error messages mention the file name. */ | 395 // Set sourcing_name, so that error messages mention the file name. |
396 sourcing_name = fname; | 396 sourcing_name = fname; |
397 sourcing_lnum = 0; | 397 sourcing_lnum = 0; |
398 | 398 |
399 /* | 399 /* |
400 * <HEADER>: <fileID> | 400 * <HEADER>: <fileID> |
401 */ | 401 */ |
402 for (i = 0; i < VIMSPELLMAGICL; ++i) | 402 for (i = 0; i < VIMSPELLMAGICL; ++i) |
403 buf[i] = getc(fd); /* <fileID> */ | 403 buf[i] = getc(fd); // <fileID> |
404 if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) | 404 if (STRNCMP(buf, VIMSPELLMAGIC, VIMSPELLMAGICL) != 0) |
405 { | 405 { |
406 emsg(_("E757: This does not look like a spell file")); | 406 emsg(_("E757: This does not look like a spell file")); |
407 goto endFAIL; | 407 goto endFAIL; |
408 } | 408 } |
409 c = getc(fd); /* <versionnr> */ | 409 c = getc(fd); // <versionnr> |
410 if (c < VIMSPELLVERSION) | 410 if (c < VIMSPELLVERSION) |
411 { | 411 { |
412 emsg(_("E771: Old spell file, needs to be updated")); | 412 emsg(_("E771: Old spell file, needs to be updated")); |
413 goto endFAIL; | 413 goto endFAIL; |
414 } | 414 } |
423 * <SECTIONS>: <section> ... <sectionend> | 423 * <SECTIONS>: <section> ... <sectionend> |
424 * <section>: <sectionID> <sectionflags> <sectionlen> (section contents) | 424 * <section>: <sectionID> <sectionflags> <sectionlen> (section contents) |
425 */ | 425 */ |
426 for (;;) | 426 for (;;) |
427 { | 427 { |
428 n = getc(fd); /* <sectionID> or <sectionend> */ | 428 n = getc(fd); // <sectionID> or <sectionend> |
429 if (n == SN_END) | 429 if (n == SN_END) |
430 break; | 430 break; |
431 c = getc(fd); /* <sectionflags> */ | 431 c = getc(fd); // <sectionflags> |
432 len = get4c(fd); /* <sectionlen> */ | 432 len = get4c(fd); // <sectionlen> |
433 if (len < 0) | 433 if (len < 0) |
434 goto truncerr; | 434 goto truncerr; |
435 | 435 |
436 res = 0; | 436 res = 0; |
437 switch (n) | 437 switch (n) |
438 { | 438 { |
439 case SN_INFO: | 439 case SN_INFO: |
440 lp->sl_info = read_string(fd, len); /* <infotext> */ | 440 lp->sl_info = read_string(fd, len); // <infotext> |
441 if (lp->sl_info == NULL) | 441 if (lp->sl_info == NULL) |
442 goto endFAIL; | 442 goto endFAIL; |
443 break; | 443 break; |
444 | 444 |
445 case SN_REGION: | 445 case SN_REGION: |
449 case SN_CHARFLAGS: | 449 case SN_CHARFLAGS: |
450 res = read_charflags_section(fd); | 450 res = read_charflags_section(fd); |
451 break; | 451 break; |
452 | 452 |
453 case SN_MIDWORD: | 453 case SN_MIDWORD: |
454 lp->sl_midword = read_string(fd, len); /* <midword> */ | 454 lp->sl_midword = read_string(fd, len); // <midword> |
455 if (lp->sl_midword == NULL) | 455 if (lp->sl_midword == NULL) |
456 goto endFAIL; | 456 goto endFAIL; |
457 break; | 457 break; |
458 | 458 |
459 case SN_PREFCOND: | 459 case SN_PREFCOND: |
475 case SN_SOFO: | 475 case SN_SOFO: |
476 res = read_sofo_section(fd, lp); | 476 res = read_sofo_section(fd, lp); |
477 break; | 477 break; |
478 | 478 |
479 case SN_MAP: | 479 case SN_MAP: |
480 p = read_string(fd, len); /* <mapstr> */ | 480 p = read_string(fd, len); // <mapstr> |
481 if (p == NULL) | 481 if (p == NULL) |
482 goto endFAIL; | 482 goto endFAIL; |
483 set_map_str(lp, p); | 483 set_map_str(lp, p); |
484 vim_free(p); | 484 vim_free(p); |
485 break; | 485 break; |
487 case SN_WORDS: | 487 case SN_WORDS: |
488 res = read_words_section(fd, lp, len); | 488 res = read_words_section(fd, lp, len); |
489 break; | 489 break; |
490 | 490 |
491 case SN_SUGFILE: | 491 case SN_SUGFILE: |
492 lp->sl_sugtime = get8ctime(fd); /* <timestamp> */ | 492 lp->sl_sugtime = get8ctime(fd); // <timestamp> |
493 break; | 493 break; |
494 | 494 |
495 case SN_NOSPLITSUGS: | 495 case SN_NOSPLITSUGS: |
496 lp->sl_nosplitsugs = TRUE; | 496 lp->sl_nosplitsugs = TRUE; |
497 break; | 497 break; |
507 case SN_NOBREAK: | 507 case SN_NOBREAK: |
508 lp->sl_nobreak = TRUE; | 508 lp->sl_nobreak = TRUE; |
509 break; | 509 break; |
510 | 510 |
511 case SN_SYLLABLE: | 511 case SN_SYLLABLE: |
512 lp->sl_syllable = read_string(fd, len); /* <syllable> */ | 512 lp->sl_syllable = read_string(fd, len); // <syllable> |
513 if (lp->sl_syllable == NULL) | 513 if (lp->sl_syllable == NULL) |
514 goto endFAIL; | 514 goto endFAIL; |
515 if (init_syl_tab(lp) == FAIL) | 515 if (init_syl_tab(lp) == FAIL) |
516 goto endFAIL; | 516 goto endFAIL; |
517 break; | 517 break; |
518 | 518 |
519 default: | 519 default: |
520 /* Unsupported section. When it's required give an error | 520 // Unsupported section. When it's required give an error |
521 * message. When it's not required skip the contents. */ | 521 // message. When it's not required skip the contents. |
522 if (c & SNF_REQUIRED) | 522 if (c & SNF_REQUIRED) |
523 { | 523 { |
524 emsg(_("E770: Unsupported section in spell file")); | 524 emsg(_("E770: Unsupported section in spell file")); |
525 goto endFAIL; | 525 goto endFAIL; |
526 } | 526 } |
543 } | 543 } |
544 if (res == SP_OTHERERROR) | 544 if (res == SP_OTHERERROR) |
545 goto endFAIL; | 545 goto endFAIL; |
546 } | 546 } |
547 | 547 |
548 /* <LWORDTREE> */ | 548 // <LWORDTREE> |
549 res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, FALSE, 0); | 549 res = spell_read_tree(fd, &lp->sl_fbyts, &lp->sl_fidxs, FALSE, 0); |
550 if (res != 0) | 550 if (res != 0) |
551 goto someerror; | 551 goto someerror; |
552 | 552 |
553 /* <KWORDTREE> */ | 553 // <KWORDTREE> |
554 res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, FALSE, 0); | 554 res = spell_read_tree(fd, &lp->sl_kbyts, &lp->sl_kidxs, FALSE, 0); |
555 if (res != 0) | 555 if (res != 0) |
556 goto someerror; | 556 goto someerror; |
557 | 557 |
558 /* <PREFIXTREE> */ | 558 // <PREFIXTREE> |
559 res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, TRUE, | 559 res = spell_read_tree(fd, &lp->sl_pbyts, &lp->sl_pidxs, TRUE, |
560 lp->sl_prefixcnt); | 560 lp->sl_prefixcnt); |
561 if (res != 0) | 561 if (res != 0) |
562 goto someerror; | 562 goto someerror; |
563 | 563 |
564 /* For a new file link it in the list of spell files. */ | 564 // For a new file link it in the list of spell files. |
565 if (old_lp == NULL && lang != NULL) | 565 if (old_lp == NULL && lang != NULL) |
566 { | 566 { |
567 lp->sl_next = first_lang; | 567 lp->sl_next = first_lang; |
568 first_lang = lp; | 568 first_lang = lp; |
569 } | 569 } |
570 | 570 |
571 goto endOK; | 571 goto endOK; |
572 | 572 |
573 endFAIL: | 573 endFAIL: |
574 if (lang != NULL) | 574 if (lang != NULL) |
575 /* truncating the name signals the error to spell_load_lang() */ | 575 // truncating the name signals the error to spell_load_lang() |
576 *lang = NUL; | 576 *lang = NUL; |
577 if (lp != NULL && old_lp == NULL) | 577 if (lp != NULL && old_lp == NULL) |
578 slang_free(lp); | 578 slang_free(lp); |
579 lp = NULL; | 579 lp = NULL; |
580 | 580 |
607 depth = 0; | 607 depth = 0; |
608 while (depth >= 0 && !got_int) | 608 while (depth >= 0 && !got_int) |
609 { | 609 { |
610 if (curi[depth] > byts[arridx[depth]]) | 610 if (curi[depth] > byts[arridx[depth]]) |
611 { | 611 { |
612 /* Done all bytes at this node, go up one level. */ | 612 // Done all bytes at this node, go up one level. |
613 idxs[arridx[depth]] = wordcount[depth]; | 613 idxs[arridx[depth]] = wordcount[depth]; |
614 if (depth > 0) | 614 if (depth > 0) |
615 wordcount[depth - 1] += wordcount[depth]; | 615 wordcount[depth - 1] += wordcount[depth]; |
616 | 616 |
617 --depth; | 617 --depth; |
618 fast_breakcheck(); | 618 fast_breakcheck(); |
619 } | 619 } |
620 else | 620 else |
621 { | 621 { |
622 /* Do one more byte at this node. */ | 622 // Do one more byte at this node. |
623 n = arridx[depth] + curi[depth]; | 623 n = arridx[depth] + curi[depth]; |
624 ++curi[depth]; | 624 ++curi[depth]; |
625 | 625 |
626 c = byts[n]; | 626 c = byts[n]; |
627 if (c == 0) | 627 if (c == 0) |
628 { | 628 { |
629 /* End of word, count it. */ | 629 // End of word, count it. |
630 ++wordcount[depth]; | 630 ++wordcount[depth]; |
631 | 631 |
632 /* Skip over any other NUL bytes (same word with different | 632 // Skip over any other NUL bytes (same word with different |
633 * flags). */ | 633 // flags). |
634 while (byts[n + 1] == 0) | 634 while (byts[n + 1] == 0) |
635 { | 635 { |
636 ++n; | 636 ++n; |
637 ++curi[depth]; | 637 ++curi[depth]; |
638 } | 638 } |
639 } | 639 } |
640 else | 640 else |
641 { | 641 { |
642 /* Normal char, go one level deeper to count the words. */ | 642 // Normal char, go one level deeper to count the words. |
643 ++depth; | 643 ++depth; |
644 arridx[depth] = idxs[n]; | 644 arridx[depth] = idxs[n]; |
645 curi[depth] = 1; | 645 curi[depth] = 1; |
646 wordcount[depth] = 0; | 646 wordcount[depth] = 0; |
647 } | 647 } |
666 int wcount; | 666 int wcount; |
667 int wordnr; | 667 int wordnr; |
668 garray_T ga; | 668 garray_T ga; |
669 int c; | 669 int c; |
670 | 670 |
671 /* Do this for all languages that support sound folding. */ | 671 // Do this for all languages that support sound folding. |
672 for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) | 672 for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi) |
673 { | 673 { |
674 lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); | 674 lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi); |
675 slang = lp->lp_slang; | 675 slang = lp->lp_slang; |
676 if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) | 676 if (slang->sl_sugtime != 0 && !slang->sl_sugloaded) |
677 { | 677 { |
678 /* Change ".spl" to ".sug" and open the file. When the file isn't | 678 // Change ".spl" to ".sug" and open the file. When the file isn't |
679 * found silently skip it. Do set "sl_sugloaded" so that we | 679 // found silently skip it. Do set "sl_sugloaded" so that we |
680 * don't try again and again. */ | 680 // don't try again and again. |
681 slang->sl_sugloaded = TRUE; | 681 slang->sl_sugloaded = TRUE; |
682 | 682 |
683 dotp = vim_strrchr(slang->sl_fname, '.'); | 683 dotp = vim_strrchr(slang->sl_fname, '.'); |
684 if (dotp == NULL || fnamecmp(dotp, ".spl") != 0) | 684 if (dotp == NULL || fnamecmp(dotp, ".spl") != 0) |
685 continue; | 685 continue; |
690 | 690 |
691 /* | 691 /* |
692 * <SUGHEADER>: <fileID> <versionnr> <timestamp> | 692 * <SUGHEADER>: <fileID> <versionnr> <timestamp> |
693 */ | 693 */ |
694 for (i = 0; i < VIMSUGMAGICL; ++i) | 694 for (i = 0; i < VIMSUGMAGICL; ++i) |
695 buf[i] = getc(fd); /* <fileID> */ | 695 buf[i] = getc(fd); // <fileID> |
696 if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) | 696 if (STRNCMP(buf, VIMSUGMAGIC, VIMSUGMAGICL) != 0) |
697 { | 697 { |
698 semsg(_("E778: This does not look like a .sug file: %s"), | 698 semsg(_("E778: This does not look like a .sug file: %s"), |
699 slang->sl_fname); | 699 slang->sl_fname); |
700 goto nextone; | 700 goto nextone; |
701 } | 701 } |
702 c = getc(fd); /* <versionnr> */ | 702 c = getc(fd); // <versionnr> |
703 if (c < VIMSUGVERSION) | 703 if (c < VIMSUGVERSION) |
704 { | 704 { |
705 semsg(_("E779: Old .sug file, needs to be updated: %s"), | 705 semsg(_("E779: Old .sug file, needs to be updated: %s"), |
706 slang->sl_fname); | 706 slang->sl_fname); |
707 goto nextone; | 707 goto nextone; |
711 semsg(_("E780: .sug file is for newer version of Vim: %s"), | 711 semsg(_("E780: .sug file is for newer version of Vim: %s"), |
712 slang->sl_fname); | 712 slang->sl_fname); |
713 goto nextone; | 713 goto nextone; |
714 } | 714 } |
715 | 715 |
716 /* Check the timestamp, it must be exactly the same as the one in | 716 // Check the timestamp, it must be exactly the same as the one in |
717 * the .spl file. Otherwise the word numbers won't match. */ | 717 // the .spl file. Otherwise the word numbers won't match. |
718 timestamp = get8ctime(fd); /* <timestamp> */ | 718 timestamp = get8ctime(fd); // <timestamp> |
719 if (timestamp != slang->sl_sugtime) | 719 if (timestamp != slang->sl_sugtime) |
720 { | 720 { |
721 semsg(_("E781: .sug file doesn't match .spl file: %s"), | 721 semsg(_("E781: .sug file doesn't match .spl file: %s"), |
722 slang->sl_fname); | 722 slang->sl_fname); |
723 goto nextone; | 723 goto nextone; |
745 * possible to swap the info and save on memory use. | 745 * possible to swap the info and save on memory use. |
746 */ | 746 */ |
747 slang->sl_sugbuf = open_spellbuf(); | 747 slang->sl_sugbuf = open_spellbuf(); |
748 if (slang->sl_sugbuf == NULL) | 748 if (slang->sl_sugbuf == NULL) |
749 goto someerror; | 749 goto someerror; |
750 /* <sugwcount> */ | 750 // <sugwcount> |
751 wcount = get4c(fd); | 751 wcount = get4c(fd); |
752 if (wcount < 0) | 752 if (wcount < 0) |
753 goto someerror; | 753 goto someerror; |
754 | 754 |
755 /* Read all the wordnr lists into the buffer, one NUL terminated | 755 // Read all the wordnr lists into the buffer, one NUL terminated |
756 * list per line. */ | 756 // list per line. |
757 ga_init2(&ga, 1, 100); | 757 ga_init2(&ga, 1, 100); |
758 for (wordnr = 0; wordnr < wcount; ++wordnr) | 758 for (wordnr = 0; wordnr < wcount; ++wordnr) |
759 { | 759 { |
760 ga.ga_len = 0; | 760 ga.ga_len = 0; |
761 for (;;) | 761 for (;;) |
762 { | 762 { |
763 c = getc(fd); /* <sugline> */ | 763 c = getc(fd); // <sugline> |
764 if (c < 0 || ga_grow(&ga, 1) == FAIL) | 764 if (c < 0 || ga_grow(&ga, 1) == FAIL) |
765 goto someerror; | 765 goto someerror; |
766 ((char_u *)ga.ga_data)[ga.ga_len++] = c; | 766 ((char_u *)ga.ga_data)[ga.ga_len++] = c; |
767 if (c == NUL) | 767 if (c == NUL) |
768 break; | 768 break; |
801 { | 801 { |
802 int cnt = 0; | 802 int cnt = 0; |
803 int i; | 803 int i; |
804 char_u *str; | 804 char_u *str; |
805 | 805 |
806 /* read the length bytes, MSB first */ | 806 // read the length bytes, MSB first |
807 for (i = 0; i < cnt_bytes; ++i) | 807 for (i = 0; i < cnt_bytes; ++i) |
808 cnt = (cnt << 8) + getc(fd); | 808 cnt = (cnt << 8) + getc(fd); |
809 if (cnt < 0) | 809 if (cnt < 0) |
810 { | 810 { |
811 *cntp = SP_TRUNCERROR; | 811 *cntp = SP_TRUNCERROR; |
812 return NULL; | 812 return NULL; |
813 } | 813 } |
814 *cntp = cnt; | 814 *cntp = cnt; |
815 if (cnt == 0) | 815 if (cnt == 0) |
816 return NULL; /* nothing to read, return NULL */ | 816 return NULL; // nothing to read, return NULL |
817 | 817 |
818 str = read_string(fd, cnt); | 818 str = read_string(fd, cnt); |
819 if (str == NULL) | 819 if (str == NULL) |
820 *cntp = SP_OTHERERROR; | 820 *cntp = SP_OTHERERROR; |
821 return str; | 821 return str; |
831 int i; | 831 int i; |
832 | 832 |
833 if (len > MAXREGIONS * 2) | 833 if (len > MAXREGIONS * 2) |
834 return SP_FORMERROR; | 834 return SP_FORMERROR; |
835 for (i = 0; i < len; ++i) | 835 for (i = 0; i < len; ++i) |
836 lp->sl_regions[i] = getc(fd); /* <regionname> */ | 836 lp->sl_regions[i] = getc(fd); // <regionname> |
837 lp->sl_regions[len] = NUL; | 837 lp->sl_regions[len] = NUL; |
838 return 0; | 838 return 0; |
839 } | 839 } |
840 | 840 |
841 /* | 841 /* |
848 { | 848 { |
849 char_u *flags; | 849 char_u *flags; |
850 char_u *fol; | 850 char_u *fol; |
851 int flagslen, follen; | 851 int flagslen, follen; |
852 | 852 |
853 /* <charflagslen> <charflags> */ | 853 // <charflagslen> <charflags> |
854 flags = read_cnt_string(fd, 1, &flagslen); | 854 flags = read_cnt_string(fd, 1, &flagslen); |
855 if (flagslen < 0) | 855 if (flagslen < 0) |
856 return flagslen; | 856 return flagslen; |
857 | 857 |
858 /* <folcharslen> <folchars> */ | 858 // <folcharslen> <folchars> |
859 fol = read_cnt_string(fd, 2, &follen); | 859 fol = read_cnt_string(fd, 2, &follen); |
860 if (follen < 0) | 860 if (follen < 0) |
861 { | 861 { |
862 vim_free(flags); | 862 vim_free(flags); |
863 return follen; | 863 return follen; |
864 } | 864 } |
865 | 865 |
866 /* Set the word-char flags and fill SPELL_ISUPPER() table. */ | 866 // Set the word-char flags and fill SPELL_ISUPPER() table. |
867 if (flags != NULL && fol != NULL) | 867 if (flags != NULL && fol != NULL) |
868 set_spell_charflags(flags, flagslen, fol); | 868 set_spell_charflags(flags, flagslen, fol); |
869 | 869 |
870 vim_free(flags); | 870 vim_free(flags); |
871 vim_free(fol); | 871 vim_free(fol); |
872 | 872 |
873 /* When <charflagslen> is zero then <fcharlen> must also be zero. */ | 873 // When <charflagslen> is zero then <fcharlen> must also be zero. |
874 if ((flags == NULL) != (fol == NULL)) | 874 if ((flags == NULL) != (fol == NULL)) |
875 return SP_FORMERROR; | 875 return SP_FORMERROR; |
876 return 0; | 876 return 0; |
877 } | 877 } |
878 | 878 |
887 int i; | 887 int i; |
888 int n; | 888 int n; |
889 char_u *p; | 889 char_u *p; |
890 char_u buf[MAXWLEN + 1]; | 890 char_u buf[MAXWLEN + 1]; |
891 | 891 |
892 /* <prefcondcnt> <prefcond> ... */ | 892 // <prefcondcnt> <prefcond> ... |
893 cnt = get2c(fd); /* <prefcondcnt> */ | 893 cnt = get2c(fd); // <prefcondcnt> |
894 if (cnt <= 0) | 894 if (cnt <= 0) |
895 return SP_FORMERROR; | 895 return SP_FORMERROR; |
896 | 896 |
897 lp->sl_prefprog = ALLOC_CLEAR_MULT(regprog_T *, cnt); | 897 lp->sl_prefprog = ALLOC_CLEAR_MULT(regprog_T *, cnt); |
898 if (lp->sl_prefprog == NULL) | 898 if (lp->sl_prefprog == NULL) |
899 return SP_OTHERERROR; | 899 return SP_OTHERERROR; |
900 lp->sl_prefixcnt = cnt; | 900 lp->sl_prefixcnt = cnt; |
901 | 901 |
902 for (i = 0; i < cnt; ++i) | 902 for (i = 0; i < cnt; ++i) |
903 { | 903 { |
904 /* <prefcond> : <condlen> <condstr> */ | 904 // <prefcond> : <condlen> <condstr> |
905 n = getc(fd); /* <condlen> */ | 905 n = getc(fd); // <condlen> |
906 if (n < 0 || n >= MAXWLEN) | 906 if (n < 0 || n >= MAXWLEN) |
907 return SP_FORMERROR; | 907 return SP_FORMERROR; |
908 | 908 |
909 /* When <condlen> is zero we have an empty condition. Otherwise | 909 // When <condlen> is zero we have an empty condition. Otherwise |
910 * compile the regexp program used to check for the condition. */ | 910 // compile the regexp program used to check for the condition. |
911 if (n > 0) | 911 if (n > 0) |
912 { | 912 { |
913 buf[0] = '^'; /* always match at one position only */ | 913 buf[0] = '^'; // always match at one position only |
914 p = buf + 1; | 914 p = buf + 1; |
915 while (n-- > 0) | 915 while (n-- > 0) |
916 *p++ = getc(fd); /* <condstr> */ | 916 *p++ = getc(fd); // <condstr> |
917 *p = NUL; | 917 *p = NUL; |
918 lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); | 918 lp->sl_prefprog[i] = vim_regcomp(buf, RE_MAGIC + RE_STRING); |
919 } | 919 } |
920 } | 920 } |
921 return 0; | 921 return 0; |
930 { | 930 { |
931 int cnt; | 931 int cnt; |
932 fromto_T *ftp; | 932 fromto_T *ftp; |
933 int i; | 933 int i; |
934 | 934 |
935 cnt = get2c(fd); /* <repcount> */ | 935 cnt = get2c(fd); // <repcount> |
936 if (cnt < 0) | 936 if (cnt < 0) |
937 return SP_TRUNCERROR; | 937 return SP_TRUNCERROR; |
938 | 938 |
939 if (ga_grow(gap, cnt) == FAIL) | 939 if (ga_grow(gap, cnt) == FAIL) |
940 return SP_OTHERERROR; | 940 return SP_OTHERERROR; |
941 | 941 |
942 /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */ | 942 // <rep> : <repfromlen> <repfrom> <reptolen> <repto> |
943 for (; gap->ga_len < cnt; ++gap->ga_len) | 943 for (; gap->ga_len < cnt; ++gap->ga_len) |
944 { | 944 { |
945 ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; | 945 ftp = &((fromto_T *)gap->ga_data)[gap->ga_len]; |
946 ftp->ft_from = read_cnt_string(fd, 1, &i); | 946 ftp->ft_from = read_cnt_string(fd, 1, &i); |
947 if (i < 0) | 947 if (i < 0) |
956 return i; | 956 return i; |
957 return SP_FORMERROR; | 957 return SP_FORMERROR; |
958 } | 958 } |
959 } | 959 } |
960 | 960 |
961 /* Fill the first-index table. */ | 961 // Fill the first-index table. |
962 for (i = 0; i < 256; ++i) | 962 for (i = 0; i < 256; ++i) |
963 first[i] = -1; | 963 first[i] = -1; |
964 for (i = 0; i < gap->ga_len; ++i) | 964 for (i = 0; i < gap->ga_len; ++i) |
965 { | 965 { |
966 ftp = &((fromto_T *)gap->ga_data)[i]; | 966 ftp = &((fromto_T *)gap->ga_data)[i]; |
985 char_u *p; | 985 char_u *p; |
986 int c = NUL; | 986 int c = NUL; |
987 | 987 |
988 slang->sl_sofo = FALSE; | 988 slang->sl_sofo = FALSE; |
989 | 989 |
990 i = getc(fd); /* <salflags> */ | 990 i = getc(fd); // <salflags> |
991 if (i & SAL_F0LLOWUP) | 991 if (i & SAL_F0LLOWUP) |
992 slang->sl_followup = TRUE; | 992 slang->sl_followup = TRUE; |
993 if (i & SAL_COLLAPSE) | 993 if (i & SAL_COLLAPSE) |
994 slang->sl_collapse = TRUE; | 994 slang->sl_collapse = TRUE; |
995 if (i & SAL_REM_ACCENTS) | 995 if (i & SAL_REM_ACCENTS) |
996 slang->sl_rem_accents = TRUE; | 996 slang->sl_rem_accents = TRUE; |
997 | 997 |
998 cnt = get2c(fd); /* <salcount> */ | 998 cnt = get2c(fd); // <salcount> |
999 if (cnt < 0) | 999 if (cnt < 0) |
1000 return SP_TRUNCERROR; | 1000 return SP_TRUNCERROR; |
1001 | 1001 |
1002 gap = &slang->sl_sal; | 1002 gap = &slang->sl_sal; |
1003 ga_init2(gap, sizeof(salitem_T), 10); | 1003 ga_init2(gap, sizeof(salitem_T), 10); |
1004 if (ga_grow(gap, cnt + 1) == FAIL) | 1004 if (ga_grow(gap, cnt + 1) == FAIL) |
1005 return SP_OTHERERROR; | 1005 return SP_OTHERERROR; |
1006 | 1006 |
1007 /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */ | 1007 // <sal> : <salfromlen> <salfrom> <saltolen> <salto> |
1008 for (; gap->ga_len < cnt; ++gap->ga_len) | 1008 for (; gap->ga_len < cnt; ++gap->ga_len) |
1009 { | 1009 { |
1010 smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; | 1010 smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; |
1011 ccnt = getc(fd); /* <salfromlen> */ | 1011 ccnt = getc(fd); // <salfromlen> |
1012 if (ccnt < 0) | 1012 if (ccnt < 0) |
1013 return SP_TRUNCERROR; | 1013 return SP_TRUNCERROR; |
1014 if ((p = alloc(ccnt + 2)) == NULL) | 1014 if ((p = alloc(ccnt + 2)) == NULL) |
1015 return SP_OTHERERROR; | 1015 return SP_OTHERERROR; |
1016 smp->sm_lead = p; | 1016 smp->sm_lead = p; |
1017 | 1017 |
1018 /* Read up to the first special char into sm_lead. */ | 1018 // Read up to the first special char into sm_lead. |
1019 for (i = 0; i < ccnt; ++i) | 1019 for (i = 0; i < ccnt; ++i) |
1020 { | 1020 { |
1021 c = getc(fd); /* <salfrom> */ | 1021 c = getc(fd); // <salfrom> |
1022 if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) | 1022 if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL) |
1023 break; | 1023 break; |
1024 *p++ = c; | 1024 *p++ = c; |
1025 } | 1025 } |
1026 smp->sm_leadlen = (int)(p - smp->sm_lead); | 1026 smp->sm_leadlen = (int)(p - smp->sm_lead); |
1027 *p++ = NUL; | 1027 *p++ = NUL; |
1028 | 1028 |
1029 /* Put (abc) chars in sm_oneof, if any. */ | 1029 // Put (abc) chars in sm_oneof, if any. |
1030 if (c == '(') | 1030 if (c == '(') |
1031 { | 1031 { |
1032 smp->sm_oneof = p; | 1032 smp->sm_oneof = p; |
1033 for (++i; i < ccnt; ++i) | 1033 for (++i; i < ccnt; ++i) |
1034 { | 1034 { |
1035 c = getc(fd); /* <salfrom> */ | 1035 c = getc(fd); // <salfrom> |
1036 if (c == ')') | 1036 if (c == ')') |
1037 break; | 1037 break; |
1038 *p++ = c; | 1038 *p++ = c; |
1039 } | 1039 } |
1040 *p++ = NUL; | 1040 *p++ = NUL; |
1042 c = getc(fd); | 1042 c = getc(fd); |
1043 } | 1043 } |
1044 else | 1044 else |
1045 smp->sm_oneof = NULL; | 1045 smp->sm_oneof = NULL; |
1046 | 1046 |
1047 /* Any following chars go in sm_rules. */ | 1047 // Any following chars go in sm_rules. |
1048 smp->sm_rules = p; | 1048 smp->sm_rules = p; |
1049 if (i < ccnt) | 1049 if (i < ccnt) |
1050 /* store the char we got while checking for end of sm_lead */ | 1050 // store the char we got while checking for end of sm_lead |
1051 *p++ = c; | 1051 *p++ = c; |
1052 for (++i; i < ccnt; ++i) | 1052 for (++i; i < ccnt; ++i) |
1053 *p++ = getc(fd); /* <salfrom> */ | 1053 *p++ = getc(fd); // <salfrom> |
1054 *p++ = NUL; | 1054 *p++ = NUL; |
1055 | 1055 |
1056 /* <saltolen> <salto> */ | 1056 // <saltolen> <salto> |
1057 smp->sm_to = read_cnt_string(fd, 1, &ccnt); | 1057 smp->sm_to = read_cnt_string(fd, 1, &ccnt); |
1058 if (ccnt < 0) | 1058 if (ccnt < 0) |
1059 { | 1059 { |
1060 vim_free(smp->sm_lead); | 1060 vim_free(smp->sm_lead); |
1061 return ccnt; | 1061 return ccnt; |
1062 } | 1062 } |
1063 | 1063 |
1064 if (has_mbyte) | 1064 if (has_mbyte) |
1065 { | 1065 { |
1066 /* convert the multi-byte strings to wide char strings */ | 1066 // convert the multi-byte strings to wide char strings |
1067 smp->sm_lead_w = mb_str2wide(smp->sm_lead); | 1067 smp->sm_lead_w = mb_str2wide(smp->sm_lead); |
1068 smp->sm_leadlen = mb_charlen(smp->sm_lead); | 1068 smp->sm_leadlen = mb_charlen(smp->sm_lead); |
1069 if (smp->sm_oneof == NULL) | 1069 if (smp->sm_oneof == NULL) |
1070 smp->sm_oneof_w = NULL; | 1070 smp->sm_oneof_w = NULL; |
1071 else | 1071 else |
1088 } | 1088 } |
1089 } | 1089 } |
1090 | 1090 |
1091 if (gap->ga_len > 0) | 1091 if (gap->ga_len > 0) |
1092 { | 1092 { |
1093 /* Add one extra entry to mark the end with an empty sm_lead. Avoids | 1093 // Add one extra entry to mark the end with an empty sm_lead. Avoids |
1094 * that we need to check the index every time. */ | 1094 // that we need to check the index every time. |
1095 smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; | 1095 smp = &((salitem_T *)gap->ga_data)[gap->ga_len]; |
1096 if ((p = alloc(1)) == NULL) | 1096 if ((p = alloc(1)) == NULL) |
1097 return SP_OTHERERROR; | 1097 return SP_OTHERERROR; |
1098 p[0] = NUL; | 1098 p[0] = NUL; |
1099 smp->sm_lead = p; | 1099 smp->sm_lead = p; |
1109 smp->sm_to_w = NULL; | 1109 smp->sm_to_w = NULL; |
1110 } | 1110 } |
1111 ++gap->ga_len; | 1111 ++gap->ga_len; |
1112 } | 1112 } |
1113 | 1113 |
1114 /* Fill the first-index table. */ | 1114 // Fill the first-index table. |
1115 set_sal_first(slang); | 1115 set_sal_first(slang); |
1116 | 1116 |
1117 return 0; | 1117 return 0; |
1118 } | 1118 } |
1119 | 1119 |
1129 int c; | 1129 int c; |
1130 char_u word[MAXWLEN]; | 1130 char_u word[MAXWLEN]; |
1131 | 1131 |
1132 while (done < len) | 1132 while (done < len) |
1133 { | 1133 { |
1134 /* Read one word at a time. */ | 1134 // Read one word at a time. |
1135 for (i = 0; ; ++i) | 1135 for (i = 0; ; ++i) |
1136 { | 1136 { |
1137 c = getc(fd); | 1137 c = getc(fd); |
1138 if (c == EOF) | 1138 if (c == EOF) |
1139 return SP_TRUNCERROR; | 1139 return SP_TRUNCERROR; |
1142 break; | 1142 break; |
1143 if (i == MAXWLEN - 1) | 1143 if (i == MAXWLEN - 1) |
1144 return SP_FORMERROR; | 1144 return SP_FORMERROR; |
1145 } | 1145 } |
1146 | 1146 |
1147 /* Init the count to 10. */ | 1147 // Init the count to 10. |
1148 count_common_word(lp, word, -1, 10); | 1148 count_common_word(lp, word, -1, 10); |
1149 done += i + 1; | 1149 done += i + 1; |
1150 } | 1150 } |
1151 return 0; | 1151 return 0; |
1152 } | 1152 } |
1162 char_u *from, *to; | 1162 char_u *from, *to; |
1163 int res; | 1163 int res; |
1164 | 1164 |
1165 slang->sl_sofo = TRUE; | 1165 slang->sl_sofo = TRUE; |
1166 | 1166 |
1167 /* <sofofromlen> <sofofrom> */ | 1167 // <sofofromlen> <sofofrom> |
1168 from = read_cnt_string(fd, 2, &cnt); | 1168 from = read_cnt_string(fd, 2, &cnt); |
1169 if (cnt < 0) | 1169 if (cnt < 0) |
1170 return cnt; | 1170 return cnt; |
1171 | 1171 |
1172 /* <sofotolen> <sofoto> */ | 1172 // <sofotolen> <sofoto> |
1173 to = read_cnt_string(fd, 2, &cnt); | 1173 to = read_cnt_string(fd, 2, &cnt); |
1174 if (cnt < 0) | 1174 if (cnt < 0) |
1175 { | 1175 { |
1176 vim_free(from); | 1176 vim_free(from); |
1177 return cnt; | 1177 return cnt; |
1178 } | 1178 } |
1179 | 1179 |
1180 /* Store the info in slang->sl_sal and/or slang->sl_sal_first. */ | 1180 // Store the info in slang->sl_sal and/or slang->sl_sal_first. |
1181 if (from != NULL && to != NULL) | 1181 if (from != NULL && to != NULL) |
1182 res = set_sofo(slang, from, to); | 1182 res = set_sofo(slang, from, to); |
1183 else if (from != NULL || to != NULL) | 1183 else if (from != NULL || to != NULL) |
1184 res = SP_FORMERROR; /* only one of two strings is an error */ | 1184 res = SP_FORMERROR; // only one of two strings is an error |
1185 else | 1185 else |
1186 res = 0; | 1186 res = 0; |
1187 | 1187 |
1188 vim_free(from); | 1188 vim_free(from); |
1189 vim_free(to); | 1189 vim_free(to); |
1208 char_u *crp; | 1208 char_u *crp; |
1209 int cnt; | 1209 int cnt; |
1210 garray_T *gap; | 1210 garray_T *gap; |
1211 | 1211 |
1212 if (todo < 2) | 1212 if (todo < 2) |
1213 return SP_FORMERROR; /* need at least two bytes */ | 1213 return SP_FORMERROR; // need at least two bytes |
1214 | 1214 |
1215 --todo; | 1215 --todo; |
1216 c = getc(fd); /* <compmax> */ | 1216 c = getc(fd); // <compmax> |
1217 if (c < 2) | 1217 if (c < 2) |
1218 c = MAXWLEN; | 1218 c = MAXWLEN; |
1219 slang->sl_compmax = c; | 1219 slang->sl_compmax = c; |
1220 | 1220 |
1221 --todo; | 1221 --todo; |
1222 c = getc(fd); /* <compminlen> */ | 1222 c = getc(fd); // <compminlen> |
1223 if (c < 1) | 1223 if (c < 1) |
1224 c = 0; | 1224 c = 0; |
1225 slang->sl_compminlen = c; | 1225 slang->sl_compminlen = c; |
1226 | 1226 |
1227 --todo; | 1227 --todo; |
1228 c = getc(fd); /* <compsylmax> */ | 1228 c = getc(fd); // <compsylmax> |
1229 if (c < 1) | 1229 if (c < 1) |
1230 c = MAXWLEN; | 1230 c = MAXWLEN; |
1231 slang->sl_compsylmax = c; | 1231 slang->sl_compsylmax = c; |
1232 | 1232 |
1233 c = getc(fd); /* <compoptions> */ | 1233 c = getc(fd); // <compoptions> |
1234 if (c != 0) | 1234 if (c != 0) |
1235 ungetc(c, fd); /* be backwards compatible with Vim 7.0b */ | 1235 ungetc(c, fd); // be backwards compatible with Vim 7.0b |
1236 else | 1236 else |
1237 { | 1237 { |
1238 --todo; | 1238 --todo; |
1239 c = getc(fd); /* only use the lower byte for now */ | 1239 c = getc(fd); // only use the lower byte for now |
1240 --todo; | 1240 --todo; |
1241 slang->sl_compoptions = c; | 1241 slang->sl_compoptions = c; |
1242 | 1242 |
1243 gap = &slang->sl_comppat; | 1243 gap = &slang->sl_comppat; |
1244 c = get2c(fd); /* <comppatcount> */ | 1244 c = get2c(fd); // <comppatcount> |
1245 todo -= 2; | 1245 todo -= 2; |
1246 ga_init2(gap, sizeof(char_u *), c); | 1246 ga_init2(gap, sizeof(char_u *), c); |
1247 if (ga_grow(gap, c) == OK) | 1247 if (ga_grow(gap, c) == OK) |
1248 while (--c >= 0) | 1248 while (--c >= 0) |
1249 { | 1249 { |
1250 ((char_u **)(gap->ga_data))[gap->ga_len++] = | 1250 ((char_u **)(gap->ga_data))[gap->ga_len++] = |
1251 read_cnt_string(fd, 1, &cnt); | 1251 read_cnt_string(fd, 1, &cnt); |
1252 /* <comppatlen> <comppattext> */ | 1252 // <comppatlen> <comppattext> |
1253 if (cnt < 0) | 1253 if (cnt < 0) |
1254 return cnt; | 1254 return cnt; |
1255 todo -= cnt + 1; | 1255 todo -= cnt + 1; |
1256 } | 1256 } |
1257 } | 1257 } |
1258 if (todo < 0) | 1258 if (todo < 0) |
1259 return SP_FORMERROR; | 1259 return SP_FORMERROR; |
1260 | 1260 |
1261 /* Turn the COMPOUNDRULE items into a regexp pattern: | 1261 // Turn the COMPOUNDRULE items into a regexp pattern: |
1262 * "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". | 1262 // "a[bc]/a*b+" -> "^\(a[bc]\|a*b\+\)$". |
1263 * Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes. | 1263 // Inserting backslashes may double the length, "^\(\)$<Nul>" is 7 bytes. |
1264 * Conversion to utf-8 may double the size. */ | 1264 // Conversion to utf-8 may double the size. |
1265 c = todo * 2 + 7; | 1265 c = todo * 2 + 7; |
1266 if (enc_utf8) | 1266 if (enc_utf8) |
1267 c += todo * 2; | 1267 c += todo * 2; |
1268 pat = alloc(c); | 1268 pat = alloc(c); |
1269 if (pat == NULL) | 1269 if (pat == NULL) |
1270 return SP_OTHERERROR; | 1270 return SP_OTHERERROR; |
1271 | 1271 |
1272 /* We also need a list of all flags that can appear at the start and one | 1272 // We also need a list of all flags that can appear at the start and one |
1273 * for all flags. */ | 1273 // for all flags. |
1274 cp = alloc(todo + 1); | 1274 cp = alloc(todo + 1); |
1275 if (cp == NULL) | 1275 if (cp == NULL) |
1276 { | 1276 { |
1277 vim_free(pat); | 1277 vim_free(pat); |
1278 return SP_OTHERERROR; | 1278 return SP_OTHERERROR; |
1287 return SP_OTHERERROR; | 1287 return SP_OTHERERROR; |
1288 } | 1288 } |
1289 slang->sl_compallflags = ap; | 1289 slang->sl_compallflags = ap; |
1290 *ap = NUL; | 1290 *ap = NUL; |
1291 | 1291 |
1292 /* And a list of all patterns in their original form, for checking whether | 1292 // And a list of all patterns in their original form, for checking whether |
1293 * compounding may work in match_compoundrule(). This is freed when we | 1293 // compounding may work in match_compoundrule(). This is freed when we |
1294 * encounter a wildcard, the check doesn't work then. */ | 1294 // encounter a wildcard, the check doesn't work then. |
1295 crp = alloc(todo + 1); | 1295 crp = alloc(todo + 1); |
1296 slang->sl_comprules = crp; | 1296 slang->sl_comprules = crp; |
1297 | 1297 |
1298 pp = pat; | 1298 pp = pat; |
1299 *pp++ = '^'; | 1299 *pp++ = '^'; |
1301 *pp++ = '('; | 1301 *pp++ = '('; |
1302 | 1302 |
1303 atstart = 1; | 1303 atstart = 1; |
1304 while (todo-- > 0) | 1304 while (todo-- > 0) |
1305 { | 1305 { |
1306 c = getc(fd); /* <compflags> */ | 1306 c = getc(fd); // <compflags> |
1307 if (c == EOF) | 1307 if (c == EOF) |
1308 { | 1308 { |
1309 vim_free(pat); | 1309 vim_free(pat); |
1310 return SP_TRUNCERROR; | 1310 return SP_TRUNCERROR; |
1311 } | 1311 } |
1312 | 1312 |
1313 /* Add all flags to "sl_compallflags". */ | 1313 // Add all flags to "sl_compallflags". |
1314 if (vim_strchr((char_u *)"?*+[]/", c) == NULL | 1314 if (vim_strchr((char_u *)"?*+[]/", c) == NULL |
1315 && !byte_in_str(slang->sl_compallflags, c)) | 1315 && !byte_in_str(slang->sl_compallflags, c)) |
1316 { | 1316 { |
1317 *ap++ = c; | 1317 *ap++ = c; |
1318 *ap = NUL; | 1318 *ap = NUL; |
1319 } | 1319 } |
1320 | 1320 |
1321 if (atstart != 0) | 1321 if (atstart != 0) |
1322 { | 1322 { |
1323 /* At start of item: copy flags to "sl_compstartflags". For a | 1323 // At start of item: copy flags to "sl_compstartflags". For a |
1324 * [abc] item set "atstart" to 2 and copy up to the ']'. */ | 1324 // [abc] item set "atstart" to 2 and copy up to the ']'. |
1325 if (c == '[') | 1325 if (c == '[') |
1326 atstart = 2; | 1326 atstart = 2; |
1327 else if (c == ']') | 1327 else if (c == ']') |
1328 atstart = 0; | 1328 atstart = 0; |
1329 else | 1329 else |
1336 if (atstart == 1) | 1336 if (atstart == 1) |
1337 atstart = 0; | 1337 atstart = 0; |
1338 } | 1338 } |
1339 } | 1339 } |
1340 | 1340 |
1341 /* Copy flag to "sl_comprules", unless we run into a wildcard. */ | 1341 // Copy flag to "sl_comprules", unless we run into a wildcard. |
1342 if (crp != NULL) | 1342 if (crp != NULL) |
1343 { | 1343 { |
1344 if (c == '?' || c == '+' || c == '*') | 1344 if (c == '?' || c == '+' || c == '*') |
1345 { | 1345 { |
1346 VIM_CLEAR(slang->sl_comprules); | 1346 VIM_CLEAR(slang->sl_comprules); |
1348 } | 1348 } |
1349 else | 1349 else |
1350 *crp++ = c; | 1350 *crp++ = c; |
1351 } | 1351 } |
1352 | 1352 |
1353 if (c == '/') /* slash separates two items */ | 1353 if (c == '/') // slash separates two items |
1354 { | 1354 { |
1355 *pp++ = '\\'; | 1355 *pp++ = '\\'; |
1356 *pp++ = '|'; | 1356 *pp++ = '|'; |
1357 atstart = 1; | 1357 atstart = 1; |
1358 } | 1358 } |
1359 else /* normal char, "[abc]" and '*' are copied as-is */ | 1359 else // normal char, "[abc]" and '*' are copied as-is |
1360 { | 1360 { |
1361 if (c == '?' || c == '+' || c == '~') | 1361 if (c == '?' || c == '+' || c == '~') |
1362 *pp++ = '\\'; /* "a?" becomes "a\?", "a+" becomes "a\+" */ | 1362 *pp++ = '\\'; // "a?" becomes "a\?", "a+" becomes "a\+" |
1363 if (enc_utf8) | 1363 if (enc_utf8) |
1364 pp += mb_char2bytes(c, pp); | 1364 pp += mb_char2bytes(c, pp); |
1365 else | 1365 else |
1366 *pp++ = c; | 1366 *pp++ = c; |
1367 } | 1367 } |
1398 int c; | 1398 int c; |
1399 int *inp; | 1399 int *inp; |
1400 | 1400 |
1401 if (has_mbyte) | 1401 if (has_mbyte) |
1402 { | 1402 { |
1403 /* Use "sl_sal" as an array with 256 pointers to a list of wide | 1403 // Use "sl_sal" as an array with 256 pointers to a list of wide |
1404 * characters. The index is the low byte of the character. | 1404 // characters. The index is the low byte of the character. |
1405 * The list contains from-to pairs with a terminating NUL. | 1405 // The list contains from-to pairs with a terminating NUL. |
1406 * sl_sal_first[] is used for latin1 "from" characters. */ | 1406 // sl_sal_first[] is used for latin1 "from" characters. |
1407 gap = &lp->sl_sal; | 1407 gap = &lp->sl_sal; |
1408 ga_init2(gap, sizeof(int *), 1); | 1408 ga_init2(gap, sizeof(int *), 1); |
1409 if (ga_grow(gap, 256) == FAIL) | 1409 if (ga_grow(gap, 256) == FAIL) |
1410 return SP_OTHERERROR; | 1410 return SP_OTHERERROR; |
1411 vim_memset(gap->ga_data, 0, sizeof(int *) * 256); | 1411 vim_memset(gap->ga_data, 0, sizeof(int *) * 256); |
1412 gap->ga_len = 256; | 1412 gap->ga_len = 256; |
1413 | 1413 |
1414 /* First count the number of items for each list. Temporarily use | 1414 // First count the number of items for each list. Temporarily use |
1415 * sl_sal_first[] for this. */ | 1415 // sl_sal_first[] for this. |
1416 for (p = from, s = to; *p != NUL && *s != NUL; ) | 1416 for (p = from, s = to; *p != NUL && *s != NUL; ) |
1417 { | 1417 { |
1418 c = mb_cptr2char_adv(&p); | 1418 c = mb_cptr2char_adv(&p); |
1419 MB_CPTR_ADV(s); | 1419 MB_CPTR_ADV(s); |
1420 if (c >= 256) | 1420 if (c >= 256) |
1421 ++lp->sl_sal_first[c & 0xff]; | 1421 ++lp->sl_sal_first[c & 0xff]; |
1422 } | 1422 } |
1423 if (*p != NUL || *s != NUL) /* lengths differ */ | 1423 if (*p != NUL || *s != NUL) // lengths differ |
1424 return SP_FORMERROR; | 1424 return SP_FORMERROR; |
1425 | 1425 |
1426 /* Allocate the lists. */ | 1426 // Allocate the lists. |
1427 for (i = 0; i < 256; ++i) | 1427 for (i = 0; i < 256; ++i) |
1428 if (lp->sl_sal_first[i] > 0) | 1428 if (lp->sl_sal_first[i] > 0) |
1429 { | 1429 { |
1430 p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1)); | 1430 p = alloc(sizeof(int) * (lp->sl_sal_first[i] * 2 + 1)); |
1431 if (p == NULL) | 1431 if (p == NULL) |
1432 return SP_OTHERERROR; | 1432 return SP_OTHERERROR; |
1433 ((int **)gap->ga_data)[i] = (int *)p; | 1433 ((int **)gap->ga_data)[i] = (int *)p; |
1434 *(int *)p = 0; | 1434 *(int *)p = 0; |
1435 } | 1435 } |
1436 | 1436 |
1437 /* Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal | 1437 // Put the characters up to 255 in sl_sal_first[] the rest in a sl_sal |
1438 * list. */ | 1438 // list. |
1439 vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); | 1439 vim_memset(lp->sl_sal_first, 0, sizeof(salfirst_T) * 256); |
1440 for (p = from, s = to; *p != NUL && *s != NUL; ) | 1440 for (p = from, s = to; *p != NUL && *s != NUL; ) |
1441 { | 1441 { |
1442 c = mb_cptr2char_adv(&p); | 1442 c = mb_cptr2char_adv(&p); |
1443 i = mb_cptr2char_adv(&s); | 1443 i = mb_cptr2char_adv(&s); |
1444 if (c >= 256) | 1444 if (c >= 256) |
1445 { | 1445 { |
1446 /* Append the from-to chars at the end of the list with | 1446 // Append the from-to chars at the end of the list with |
1447 * the low byte. */ | 1447 // the low byte. |
1448 inp = ((int **)gap->ga_data)[c & 0xff]; | 1448 inp = ((int **)gap->ga_data)[c & 0xff]; |
1449 while (*inp != 0) | 1449 while (*inp != 0) |
1450 ++inp; | 1450 ++inp; |
1451 *inp++ = c; /* from char */ | 1451 *inp++ = c; // from char |
1452 *inp++ = i; /* to char */ | 1452 *inp++ = i; // to char |
1453 *inp++ = NUL; /* NUL at the end */ | 1453 *inp++ = NUL; // NUL at the end |
1454 } | 1454 } |
1455 else | 1455 else |
1456 /* mapping byte to char is done in sl_sal_first[] */ | 1456 // mapping byte to char is done in sl_sal_first[] |
1457 lp->sl_sal_first[c] = i; | 1457 lp->sl_sal_first[c] = i; |
1458 } | 1458 } |
1459 } | 1459 } |
1460 else | 1460 else |
1461 { | 1461 { |
1462 /* mapping bytes to bytes is done in sl_sal_first[] */ | 1462 // mapping bytes to bytes is done in sl_sal_first[] |
1463 if (STRLEN(from) != STRLEN(to)) | 1463 if (STRLEN(from) != STRLEN(to)) |
1464 return SP_FORMERROR; | 1464 return SP_FORMERROR; |
1465 | 1465 |
1466 for (i = 0; to[i] != NUL; ++i) | 1466 for (i = 0; to[i] != NUL; ++i) |
1467 lp->sl_sal_first[from[i]] = to[i]; | 1467 lp->sl_sal_first[from[i]] = to[i]; |
1468 lp->sl_sal.ga_len = 1; /* indicates we have soundfolding */ | 1468 lp->sl_sal.ga_len = 1; // indicates we have soundfolding |
1469 } | 1469 } |
1470 | 1470 |
1471 return 0; | 1471 return 0; |
1472 } | 1472 } |
1473 | 1473 |
1488 sfirst[i] = -1; | 1488 sfirst[i] = -1; |
1489 smp = (salitem_T *)gap->ga_data; | 1489 smp = (salitem_T *)gap->ga_data; |
1490 for (i = 0; i < gap->ga_len; ++i) | 1490 for (i = 0; i < gap->ga_len; ++i) |
1491 { | 1491 { |
1492 if (has_mbyte) | 1492 if (has_mbyte) |
1493 /* Use the lowest byte of the first character. For latin1 it's | 1493 // Use the lowest byte of the first character. For latin1 it's |
1494 * the character, for other encodings it should differ for most | 1494 // the character, for other encodings it should differ for most |
1495 * characters. */ | 1495 // characters. |
1496 c = *smp[i].sm_lead_w & 0xff; | 1496 c = *smp[i].sm_lead_w & 0xff; |
1497 else | 1497 else |
1498 c = *smp[i].sm_lead; | 1498 c = *smp[i].sm_lead; |
1499 if (sfirst[c] == -1) | 1499 if (sfirst[c] == -1) |
1500 { | 1500 { |
1501 sfirst[c] = i; | 1501 sfirst[c] = i; |
1502 if (has_mbyte) | 1502 if (has_mbyte) |
1503 { | 1503 { |
1504 int n; | 1504 int n; |
1505 | 1505 |
1506 /* Make sure all entries with this byte are following each | 1506 // Make sure all entries with this byte are following each |
1507 * other. Move the ones that are in the wrong position. Do | 1507 // other. Move the ones that are in the wrong position. Do |
1508 * keep the same ordering! */ | 1508 // keep the same ordering! |
1509 while (i + 1 < gap->ga_len | 1509 while (i + 1 < gap->ga_len |
1510 && (*smp[i + 1].sm_lead_w & 0xff) == c) | 1510 && (*smp[i + 1].sm_lead_w & 0xff) == c) |
1511 /* Skip over entry with same index byte. */ | 1511 // Skip over entry with same index byte. |
1512 ++i; | 1512 ++i; |
1513 | 1513 |
1514 for (n = 1; i + n < gap->ga_len; ++n) | 1514 for (n = 1; i + n < gap->ga_len; ++n) |
1515 if ((*smp[i + n].sm_lead_w & 0xff) == c) | 1515 if ((*smp[i + n].sm_lead_w & 0xff) == c) |
1516 { | 1516 { |
1517 salitem_T tsal; | 1517 salitem_T tsal; |
1518 | 1518 |
1519 /* Move entry with same index byte after the entries | 1519 // Move entry with same index byte after the entries |
1520 * we already found. */ | 1520 // we already found. |
1521 ++i; | 1521 ++i; |
1522 --n; | 1522 --n; |
1523 tsal = smp[i + n]; | 1523 tsal = smp[i + n]; |
1524 mch_memmove(smp + i + 1, smp + i, | 1524 mch_memmove(smp + i + 1, smp + i, |
1525 sizeof(salitem_T) * n); | 1525 sizeof(salitem_T) * n); |
1560 static int | 1560 static int |
1561 spell_read_tree( | 1561 spell_read_tree( |
1562 FILE *fd, | 1562 FILE *fd, |
1563 char_u **bytsp, | 1563 char_u **bytsp, |
1564 idx_T **idxsp, | 1564 idx_T **idxsp, |
1565 int prefixtree, /* TRUE for the prefix tree */ | 1565 int prefixtree, // TRUE for the prefix tree |
1566 int prefixcnt) /* when "prefixtree" is TRUE: prefix count */ | 1566 int prefixcnt) // when "prefixtree" is TRUE: prefix count |
1567 { | 1567 { |
1568 long len; | 1568 long len; |
1569 int idx; | 1569 int idx; |
1570 char_u *bp; | 1570 char_u *bp; |
1571 idx_T *ip; | 1571 idx_T *ip; |
1572 | 1572 |
1573 /* The tree size was computed when writing the file, so that we can | 1573 // The tree size was computed when writing the file, so that we can |
1574 * allocate it as one long block. <nodecount> */ | 1574 // allocate it as one long block. <nodecount> |
1575 len = get4c(fd); | 1575 len = get4c(fd); |
1576 if (len < 0) | 1576 if (len < 0) |
1577 return SP_TRUNCERROR; | 1577 return SP_TRUNCERROR; |
1578 if (len >= LONG_MAX / (long)sizeof(int)) | 1578 if (len >= LONG_MAX / (long)sizeof(int)) |
1579 /* Invalid length, multiply with sizeof(int) would overflow. */ | 1579 // Invalid length, multiply with sizeof(int) would overflow. |
1580 return SP_FORMERROR; | 1580 return SP_FORMERROR; |
1581 if (len > 0) | 1581 if (len > 0) |
1582 { | 1582 { |
1583 /* Allocate the byte array. */ | 1583 // Allocate the byte array. |
1584 bp = alloc(len); | 1584 bp = alloc(len); |
1585 if (bp == NULL) | 1585 if (bp == NULL) |
1586 return SP_OTHERERROR; | 1586 return SP_OTHERERROR; |
1587 *bytsp = bp; | 1587 *bytsp = bp; |
1588 | 1588 |
1589 /* Allocate the index array. */ | 1589 // Allocate the index array. |
1590 ip = lalloc_clear(len * sizeof(int), TRUE); | 1590 ip = lalloc_clear(len * sizeof(int), TRUE); |
1591 if (ip == NULL) | 1591 if (ip == NULL) |
1592 return SP_OTHERERROR; | 1592 return SP_OTHERERROR; |
1593 *idxsp = ip; | 1593 *idxsp = ip; |
1594 | 1594 |
1595 /* Recursively read the tree and store it in the array. */ | 1595 // Recursively read the tree and store it in the array. |
1596 idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); | 1596 idx = read_tree_node(fd, bp, ip, len, 0, prefixtree, prefixcnt); |
1597 if (idx < 0) | 1597 if (idx < 0) |
1598 return idx; | 1598 return idx; |
1599 } | 1599 } |
1600 return 0; | 1600 return 0; |
1613 static idx_T | 1613 static idx_T |
1614 read_tree_node( | 1614 read_tree_node( |
1615 FILE *fd, | 1615 FILE *fd, |
1616 char_u *byts, | 1616 char_u *byts, |
1617 idx_T *idxs, | 1617 idx_T *idxs, |
1618 int maxidx, /* size of arrays */ | 1618 int maxidx, // size of arrays |
1619 idx_T startidx, /* current index in "byts" and "idxs" */ | 1619 idx_T startidx, // current index in "byts" and "idxs" |
1620 int prefixtree, /* TRUE for reading PREFIXTREE */ | 1620 int prefixtree, // TRUE for reading PREFIXTREE |
1621 int maxprefcondnr) /* maximum for <prefcondnr> */ | 1621 int maxprefcondnr) // maximum for <prefcondnr> |
1622 { | 1622 { |
1623 int len; | 1623 int len; |
1624 int i; | 1624 int i; |
1625 int n; | 1625 int n; |
1626 idx_T idx = startidx; | 1626 idx_T idx = startidx; |
1627 int c; | 1627 int c; |
1628 int c2; | 1628 int c2; |
1629 #define SHARED_MASK 0x8000000 | 1629 #define SHARED_MASK 0x8000000 |
1630 | 1630 |
1631 len = getc(fd); /* <siblingcount> */ | 1631 len = getc(fd); // <siblingcount> |
1632 if (len <= 0) | 1632 if (len <= 0) |
1633 return SP_TRUNCERROR; | 1633 return SP_TRUNCERROR; |
1634 | 1634 |
1635 if (startidx + len >= maxidx) | 1635 if (startidx + len >= maxidx) |
1636 return SP_FORMERROR; | 1636 return SP_FORMERROR; |
1637 byts[idx++] = len; | 1637 byts[idx++] = len; |
1638 | 1638 |
1639 /* Read the byte values, flag/region bytes and shared indexes. */ | 1639 // Read the byte values, flag/region bytes and shared indexes. |
1640 for (i = 1; i <= len; ++i) | 1640 for (i = 1; i <= len; ++i) |
1641 { | 1641 { |
1642 c = getc(fd); /* <byte> */ | 1642 c = getc(fd); // <byte> |
1643 if (c < 0) | 1643 if (c < 0) |
1644 return SP_TRUNCERROR; | 1644 return SP_TRUNCERROR; |
1645 if (c <= BY_SPECIAL) | 1645 if (c <= BY_SPECIAL) |
1646 { | 1646 { |
1647 if (c == BY_NOFLAGS && !prefixtree) | 1647 if (c == BY_NOFLAGS && !prefixtree) |
1648 { | 1648 { |
1649 /* No flags, all regions. */ | 1649 // No flags, all regions. |
1650 idxs[idx] = 0; | 1650 idxs[idx] = 0; |
1651 c = 0; | 1651 c = 0; |
1652 } | 1652 } |
1653 else if (c != BY_INDEX) | 1653 else if (c != BY_INDEX) |
1654 { | 1654 { |
1655 if (prefixtree) | 1655 if (prefixtree) |
1656 { | 1656 { |
1657 /* Read the optional pflags byte, the prefix ID and the | 1657 // Read the optional pflags byte, the prefix ID and the |
1658 * condition nr. In idxs[] store the prefix ID in the low | 1658 // condition nr. In idxs[] store the prefix ID in the low |
1659 * byte, the condition index shifted up 8 bits, the flags | 1659 // byte, the condition index shifted up 8 bits, the flags |
1660 * shifted up 24 bits. */ | 1660 // shifted up 24 bits. |
1661 if (c == BY_FLAGS) | 1661 if (c == BY_FLAGS) |
1662 c = getc(fd) << 24; /* <pflags> */ | 1662 c = getc(fd) << 24; // <pflags> |
1663 else | 1663 else |
1664 c = 0; | 1664 c = 0; |
1665 | 1665 |
1666 c |= getc(fd); /* <affixID> */ | 1666 c |= getc(fd); // <affixID> |
1667 | 1667 |
1668 n = get2c(fd); /* <prefcondnr> */ | 1668 n = get2c(fd); // <prefcondnr> |
1669 if (n >= maxprefcondnr) | 1669 if (n >= maxprefcondnr) |
1670 return SP_FORMERROR; | 1670 return SP_FORMERROR; |
1671 c |= (n << 8); | 1671 c |= (n << 8); |
1672 } | 1672 } |
1673 else /* c must be BY_FLAGS or BY_FLAGS2 */ | 1673 else // c must be BY_FLAGS or BY_FLAGS2 |
1674 { | 1674 { |
1675 /* Read flags and optional region and prefix ID. In | 1675 // Read flags and optional region and prefix ID. In |
1676 * idxs[] the flags go in the low two bytes, region above | 1676 // idxs[] the flags go in the low two bytes, region above |
1677 * that and prefix ID above the region. */ | 1677 // that and prefix ID above the region. |
1678 c2 = c; | 1678 c2 = c; |
1679 c = getc(fd); /* <flags> */ | 1679 c = getc(fd); // <flags> |
1680 if (c2 == BY_FLAGS2) | 1680 if (c2 == BY_FLAGS2) |
1681 c = (getc(fd) << 8) + c; /* <flags2> */ | 1681 c = (getc(fd) << 8) + c; // <flags2> |
1682 if (c & WF_REGION) | 1682 if (c & WF_REGION) |
1683 c = (getc(fd) << 16) + c; /* <region> */ | 1683 c = (getc(fd) << 16) + c; // <region> |
1684 if (c & WF_AFX) | 1684 if (c & WF_AFX) |
1685 c = (getc(fd) << 24) + c; /* <affixID> */ | 1685 c = (getc(fd) << 24) + c; // <affixID> |
1686 } | 1686 } |
1687 | 1687 |
1688 idxs[idx] = c; | 1688 idxs[idx] = c; |
1689 c = 0; | 1689 c = 0; |
1690 } | 1690 } |
1691 else /* c == BY_INDEX */ | 1691 else // c == BY_INDEX |
1692 { | 1692 { |
1693 /* <nodeidx> */ | 1693 // <nodeidx> |
1694 n = get3c(fd); | 1694 n = get3c(fd); |
1695 if (n < 0 || n >= maxidx) | 1695 if (n < 0 || n >= maxidx) |
1696 return SP_FORMERROR; | 1696 return SP_FORMERROR; |
1697 idxs[idx] = n + SHARED_MASK; | 1697 idxs[idx] = n + SHARED_MASK; |
1698 c = getc(fd); /* <xbyte> */ | 1698 c = getc(fd); // <xbyte> |
1699 } | 1699 } |
1700 } | 1700 } |
1701 byts[idx++] = c; | 1701 byts[idx++] = c; |
1702 } | 1702 } |
1703 | 1703 |
1704 /* Recursively read the children for non-shared siblings. | 1704 // Recursively read the children for non-shared siblings. |
1705 * Skip the end-of-word ones (zero byte value) and the shared ones (and | 1705 // Skip the end-of-word ones (zero byte value) and the shared ones (and |
1706 * remove SHARED_MASK) */ | 1706 // remove SHARED_MASK) |
1707 for (i = 1; i <= len; ++i) | 1707 for (i = 1; i <= len; ++i) |
1708 if (byts[startidx + i] != 0) | 1708 if (byts[startidx + i] != 0) |
1709 { | 1709 { |
1710 if (idxs[startidx + i] & SHARED_MASK) | 1710 if (idxs[startidx + i] & SHARED_MASK) |
1711 idxs[startidx + i] &= ~SHARED_MASK; | 1711 idxs[startidx + i] &= ~SHARED_MASK; |
1726 * Reload the spell file "fname" if it's loaded. | 1726 * Reload the spell file "fname" if it's loaded. |
1727 */ | 1727 */ |
1728 static void | 1728 static void |
1729 spell_reload_one( | 1729 spell_reload_one( |
1730 char_u *fname, | 1730 char_u *fname, |
1731 int added_word) /* invoked through "zg" */ | 1731 int added_word) // invoked through "zg" |
1732 { | 1732 { |
1733 slang_T *slang; | 1733 slang_T *slang; |
1734 int didit = FALSE; | 1734 int didit = FALSE; |
1735 | 1735 |
1736 for (slang = first_lang; slang != NULL; slang = slang->sl_next) | 1736 for (slang = first_lang; slang != NULL; slang = slang->sl_next) |
1737 { | 1737 { |
1738 if (fullpathcmp(fname, slang->sl_fname, FALSE, TRUE) == FPC_SAME) | 1738 if (fullpathcmp(fname, slang->sl_fname, FALSE, TRUE) == FPC_SAME) |
1739 { | 1739 { |
1740 slang_clear(slang); | 1740 slang_clear(slang); |
1741 if (spell_load_file(fname, NULL, slang, FALSE) == NULL) | 1741 if (spell_load_file(fname, NULL, slang, FALSE) == NULL) |
1742 /* reloading failed, clear the language */ | 1742 // reloading failed, clear the language |
1743 slang_clear(slang); | 1743 slang_clear(slang); |
1744 redraw_all_later(SOME_VALID); | 1744 redraw_all_later(SOME_VALID); |
1745 didit = TRUE; | 1745 didit = TRUE; |
1746 } | 1746 } |
1747 } | 1747 } |
1748 | 1748 |
1749 /* When "zg" was used and the file wasn't loaded yet, should redo | 1749 // When "zg" was used and the file wasn't loaded yet, should redo |
1750 * 'spelllang' to load it now. */ | 1750 // 'spelllang' to load it now. |
1751 if (added_word && !didit) | 1751 if (added_word && !didit) |
1752 did_set_spelllang(curwin); | 1752 did_set_spelllang(curwin); |
1753 } | 1753 } |
1754 | 1754 |
1755 | 1755 |
1756 /* | 1756 /* |
1757 * Functions for ":mkspell". | 1757 * Functions for ":mkspell". |
1758 */ | 1758 */ |
1759 | 1759 |
1760 #define MAXLINELEN 500 /* Maximum length in bytes of a line in a .aff | 1760 #define MAXLINELEN 500 // Maximum length in bytes of a line in a .aff |
1761 and .dic file. */ | 1761 // and .dic file. |
1762 /* | 1762 /* |
1763 * Main structure to store the contents of a ".aff" file. | 1763 * Main structure to store the contents of a ".aff" file. |
1764 */ | 1764 */ |
1765 typedef struct afffile_S | 1765 typedef struct afffile_S |
1766 { | 1766 { |
1767 char_u *af_enc; /* "SET", normalized, alloc'ed string or NULL */ | 1767 char_u *af_enc; // "SET", normalized, alloc'ed string or NULL |
1768 int af_flagtype; /* AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG */ | 1768 int af_flagtype; // AFT_CHAR, AFT_LONG, AFT_NUM or AFT_CAPLONG |
1769 unsigned af_rare; /* RARE ID for rare word */ | 1769 unsigned af_rare; // RARE ID for rare word |
1770 unsigned af_keepcase; /* KEEPCASE ID for keep-case word */ | 1770 unsigned af_keepcase; // KEEPCASE ID for keep-case word |
1771 unsigned af_bad; /* BAD ID for banned word */ | 1771 unsigned af_bad; // BAD ID for banned word |
1772 unsigned af_needaffix; /* NEEDAFFIX ID */ | 1772 unsigned af_needaffix; // NEEDAFFIX ID |
1773 unsigned af_circumfix; /* CIRCUMFIX ID */ | 1773 unsigned af_circumfix; // CIRCUMFIX ID |
1774 unsigned af_needcomp; /* NEEDCOMPOUND ID */ | 1774 unsigned af_needcomp; // NEEDCOMPOUND ID |
1775 unsigned af_comproot; /* COMPOUNDROOT ID */ | 1775 unsigned af_comproot; // COMPOUNDROOT ID |
1776 unsigned af_compforbid; /* COMPOUNDFORBIDFLAG ID */ | 1776 unsigned af_compforbid; // COMPOUNDFORBIDFLAG ID |
1777 unsigned af_comppermit; /* COMPOUNDPERMITFLAG ID */ | 1777 unsigned af_comppermit; // COMPOUNDPERMITFLAG ID |
1778 unsigned af_nosuggest; /* NOSUGGEST ID */ | 1778 unsigned af_nosuggest; // NOSUGGEST ID |
1779 int af_pfxpostpone; /* postpone prefixes without chop string and | 1779 int af_pfxpostpone; // postpone prefixes without chop string and |
1780 without flags */ | 1780 // without flags |
1781 int af_ignoreextra; /* IGNOREEXTRA present */ | 1781 int af_ignoreextra; // IGNOREEXTRA present |
1782 hashtab_T af_pref; /* hashtable for prefixes, affheader_T */ | 1782 hashtab_T af_pref; // hashtable for prefixes, affheader_T |
1783 hashtab_T af_suff; /* hashtable for suffixes, affheader_T */ | 1783 hashtab_T af_suff; // hashtable for suffixes, affheader_T |
1784 hashtab_T af_comp; /* hashtable for compound flags, compitem_T */ | 1784 hashtab_T af_comp; // hashtable for compound flags, compitem_T |
1785 } afffile_T; | 1785 } afffile_T; |
1786 | 1786 |
1787 #define AFT_CHAR 0 /* flags are one character */ | 1787 #define AFT_CHAR 0 // flags are one character |
1788 #define AFT_LONG 1 /* flags are two characters */ | 1788 #define AFT_LONG 1 // flags are two characters |
1789 #define AFT_CAPLONG 2 /* flags are one or two characters */ | 1789 #define AFT_CAPLONG 2 // flags are one or two characters |
1790 #define AFT_NUM 3 /* flags are numbers, comma separated */ | 1790 #define AFT_NUM 3 // flags are numbers, comma separated |
1791 | 1791 |
1792 typedef struct affentry_S affentry_T; | 1792 typedef struct affentry_S affentry_T; |
1793 /* Affix entry from ".aff" file. Used for prefixes and suffixes. */ | 1793 // Affix entry from ".aff" file. Used for prefixes and suffixes. |
1794 struct affentry_S | 1794 struct affentry_S |
1795 { | 1795 { |
1796 affentry_T *ae_next; /* next affix with same name/number */ | 1796 affentry_T *ae_next; // next affix with same name/number |
1797 char_u *ae_chop; /* text to chop off basic word (can be NULL) */ | 1797 char_u *ae_chop; // text to chop off basic word (can be NULL) |
1798 char_u *ae_add; /* text to add to basic word (can be NULL) */ | 1798 char_u *ae_add; // text to add to basic word (can be NULL) |
1799 char_u *ae_flags; /* flags on the affix (can be NULL) */ | 1799 char_u *ae_flags; // flags on the affix (can be NULL) |
1800 char_u *ae_cond; /* condition (NULL for ".") */ | 1800 char_u *ae_cond; // condition (NULL for ".") |
1801 regprog_T *ae_prog; /* regexp program for ae_cond or NULL */ | 1801 regprog_T *ae_prog; // regexp program for ae_cond or NULL |
1802 char ae_compforbid; /* COMPOUNDFORBIDFLAG found */ | 1802 char ae_compforbid; // COMPOUNDFORBIDFLAG found |
1803 char ae_comppermit; /* COMPOUNDPERMITFLAG found */ | 1803 char ae_comppermit; // COMPOUNDPERMITFLAG found |
1804 }; | 1804 }; |
1805 | 1805 |
1806 #define AH_KEY_LEN 17 /* 2 x 8 bytes + NUL */ | 1806 #define AH_KEY_LEN 17 // 2 x 8 bytes + NUL |
1807 | 1807 |
1808 /* Affix header from ".aff" file. Used for af_pref and af_suff. */ | 1808 // Affix header from ".aff" file. Used for af_pref and af_suff. |
1809 typedef struct affheader_S | 1809 typedef struct affheader_S |
1810 { | 1810 { |
1811 char_u ah_key[AH_KEY_LEN]; /* key for hashtab == name of affix */ | 1811 char_u ah_key[AH_KEY_LEN]; // key for hashtab == name of affix |
1812 unsigned ah_flag; /* affix name as number, uses "af_flagtype" */ | 1812 unsigned ah_flag; // affix name as number, uses "af_flagtype" |
1813 int ah_newID; /* prefix ID after renumbering; 0 if not used */ | 1813 int ah_newID; // prefix ID after renumbering; 0 if not used |
1814 int ah_combine; /* suffix may combine with prefix */ | 1814 int ah_combine; // suffix may combine with prefix |
1815 int ah_follows; /* another affix block should be following */ | 1815 int ah_follows; // another affix block should be following |
1816 affentry_T *ah_first; /* first affix entry */ | 1816 affentry_T *ah_first; // first affix entry |
1817 } affheader_T; | 1817 } affheader_T; |
1818 | 1818 |
1819 #define HI2AH(hi) ((affheader_T *)(hi)->hi_key) | 1819 #define HI2AH(hi) ((affheader_T *)(hi)->hi_key) |
1820 | 1820 |
1821 /* Flag used in compound items. */ | 1821 // Flag used in compound items. |
1822 typedef struct compitem_S | 1822 typedef struct compitem_S |
1823 { | 1823 { |
1824 char_u ci_key[AH_KEY_LEN]; /* key for hashtab == name of compound */ | 1824 char_u ci_key[AH_KEY_LEN]; // key for hashtab == name of compound |
1825 unsigned ci_flag; /* affix name as number, uses "af_flagtype" */ | 1825 unsigned ci_flag; // affix name as number, uses "af_flagtype" |
1826 int ci_newID; /* affix ID after renumbering. */ | 1826 int ci_newID; // affix ID after renumbering. |
1827 } compitem_T; | 1827 } compitem_T; |
1828 | 1828 |
1829 #define HI2CI(hi) ((compitem_T *)(hi)->hi_key) | 1829 #define HI2CI(hi) ((compitem_T *)(hi)->hi_key) |
1830 | 1830 |
1831 /* | 1831 /* |
1834 * once after ":mkspell" is done. | 1834 * once after ":mkspell" is done. |
1835 * Note: "sb_next" must be just before "sb_data" to make sure the alignment of | 1835 * Note: "sb_next" must be just before "sb_data" to make sure the alignment of |
1836 * "sb_data" is correct for systems where pointers must be aligned on | 1836 * "sb_data" is correct for systems where pointers must be aligned on |
1837 * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc). | 1837 * pointer-size boundaries and sizeof(pointer) > sizeof(int) (e.g., Sparc). |
1838 */ | 1838 */ |
1839 #define SBLOCKSIZE 16000 /* size of sb_data */ | 1839 #define SBLOCKSIZE 16000 // size of sb_data |
1840 typedef struct sblock_S sblock_T; | 1840 typedef struct sblock_S sblock_T; |
1841 struct sblock_S | 1841 struct sblock_S |
1842 { | 1842 { |
1843 int sb_used; /* nr of bytes already in use */ | 1843 int sb_used; // nr of bytes already in use |
1844 sblock_T *sb_next; /* next block in list */ | 1844 sblock_T *sb_next; // next block in list |
1845 char_u sb_data[1]; /* data, actually longer */ | 1845 char_u sb_data[1]; // data, actually longer |
1846 }; | 1846 }; |
1847 | 1847 |
1848 /* | 1848 /* |
1849 * A node in the tree. | 1849 * A node in the tree. |
1850 */ | 1850 */ |
1851 typedef struct wordnode_S wordnode_T; | 1851 typedef struct wordnode_S wordnode_T; |
1852 struct wordnode_S | 1852 struct wordnode_S |
1853 { | 1853 { |
1854 union /* shared to save space */ | 1854 union // shared to save space |
1855 { | 1855 { |
1856 char_u hashkey[6]; /* the hash key, only used while compressing */ | 1856 char_u hashkey[6]; // the hash key, only used while compressing |
1857 int index; /* index in written nodes (valid after first | 1857 int index; // index in written nodes (valid after first |
1858 round) */ | 1858 // round) |
1859 } wn_u1; | 1859 } wn_u1; |
1860 union /* shared to save space */ | 1860 union // shared to save space |
1861 { | 1861 { |
1862 wordnode_T *next; /* next node with same hash key */ | 1862 wordnode_T *next; // next node with same hash key |
1863 wordnode_T *wnode; /* parent node that will write this node */ | 1863 wordnode_T *wnode; // parent node that will write this node |
1864 } wn_u2; | 1864 } wn_u2; |
1865 wordnode_T *wn_child; /* child (next byte in word) */ | 1865 wordnode_T *wn_child; // child (next byte in word) |
1866 wordnode_T *wn_sibling; /* next sibling (alternate byte in word, | 1866 wordnode_T *wn_sibling; // next sibling (alternate byte in word, |
1867 always sorted) */ | 1867 // always sorted) |
1868 int wn_refs; /* Nr. of references to this node. Only | 1868 int wn_refs; // Nr. of references to this node. Only |
1869 relevant for first node in a list of | 1869 // relevant for first node in a list of |
1870 siblings, in following siblings it is | 1870 // siblings, in following siblings it is |
1871 always one. */ | 1871 // always one. |
1872 char_u wn_byte; /* Byte for this node. NUL for word end */ | 1872 char_u wn_byte; // Byte for this node. NUL for word end |
1873 | 1873 |
1874 /* Info for when "wn_byte" is NUL. | 1874 // Info for when "wn_byte" is NUL. |
1875 * In PREFIXTREE "wn_region" is used for the prefcondnr. | 1875 // In PREFIXTREE "wn_region" is used for the prefcondnr. |
1876 * In the soundfolded word tree "wn_flags" has the MSW of the wordnr and | 1876 // In the soundfolded word tree "wn_flags" has the MSW of the wordnr and |
1877 * "wn_region" the LSW of the wordnr. */ | 1877 // "wn_region" the LSW of the wordnr. |
1878 char_u wn_affixID; /* supported/required prefix ID or 0 */ | 1878 char_u wn_affixID; // supported/required prefix ID or 0 |
1879 short_u wn_flags; /* WF_ flags */ | 1879 short_u wn_flags; // WF_ flags |
1880 short wn_region; /* region mask */ | 1880 short wn_region; // region mask |
1881 | 1881 |
1882 #ifdef SPELL_PRINTTREE | 1882 #ifdef SPELL_PRINTTREE |
1883 int wn_nr; /* sequence nr for printing */ | 1883 int wn_nr; // sequence nr for printing |
1884 #endif | 1884 #endif |
1885 }; | 1885 }; |
1886 | 1886 |
1887 #define WN_MASK 0xffff /* mask relevant bits of "wn_flags" */ | 1887 #define WN_MASK 0xffff // mask relevant bits of "wn_flags" |
1888 | 1888 |
1889 #define HI2WN(hi) (wordnode_T *)((hi)->hi_key) | 1889 #define HI2WN(hi) (wordnode_T *)((hi)->hi_key) |
1890 | 1890 |
1891 /* | 1891 /* |
1892 * Info used while reading the spell files. | 1892 * Info used while reading the spell files. |
1893 */ | 1893 */ |
1894 typedef struct spellinfo_S | 1894 typedef struct spellinfo_S |
1895 { | 1895 { |
1896 wordnode_T *si_foldroot; /* tree with case-folded words */ | 1896 wordnode_T *si_foldroot; // tree with case-folded words |
1897 long si_foldwcount; /* nr of words in si_foldroot */ | 1897 long si_foldwcount; // nr of words in si_foldroot |
1898 | 1898 |
1899 wordnode_T *si_keeproot; /* tree with keep-case words */ | 1899 wordnode_T *si_keeproot; // tree with keep-case words |
1900 long si_keepwcount; /* nr of words in si_keeproot */ | 1900 long si_keepwcount; // nr of words in si_keeproot |
1901 | 1901 |
1902 wordnode_T *si_prefroot; /* tree with postponed prefixes */ | 1902 wordnode_T *si_prefroot; // tree with postponed prefixes |
1903 | 1903 |
1904 long si_sugtree; /* creating the soundfolding trie */ | 1904 long si_sugtree; // creating the soundfolding trie |
1905 | 1905 |
1906 sblock_T *si_blocks; /* memory blocks used */ | 1906 sblock_T *si_blocks; // memory blocks used |
1907 long si_blocks_cnt; /* memory blocks allocated */ | 1907 long si_blocks_cnt; // memory blocks allocated |
1908 int si_did_emsg; /* TRUE when ran out of memory */ | 1908 int si_did_emsg; // TRUE when ran out of memory |
1909 | 1909 |
1910 long si_compress_cnt; /* words to add before lowering | 1910 long si_compress_cnt; // words to add before lowering |
1911 compression limit */ | 1911 // compression limit |
1912 wordnode_T *si_first_free; /* List of nodes that have been freed during | 1912 wordnode_T *si_first_free; // List of nodes that have been freed during |
1913 compression, linked by "wn_child" field. */ | 1913 // compression, linked by "wn_child" field. |
1914 long si_free_count; /* number of nodes in si_first_free */ | 1914 long si_free_count; // number of nodes in si_first_free |
1915 #ifdef SPELL_PRINTTREE | 1915 #ifdef SPELL_PRINTTREE |
1916 int si_wordnode_nr; /* sequence nr for nodes */ | 1916 int si_wordnode_nr; // sequence nr for nodes |
1917 #endif | 1917 #endif |
1918 buf_T *si_spellbuf; /* buffer used to store soundfold word table */ | 1918 buf_T *si_spellbuf; // buffer used to store soundfold word table |
1919 | 1919 |
1920 int si_ascii; /* handling only ASCII words */ | 1920 int si_ascii; // handling only ASCII words |
1921 int si_add; /* addition file */ | 1921 int si_add; // addition file |
1922 int si_clear_chartab; /* when TRUE clear char tables */ | 1922 int si_clear_chartab; // when TRUE clear char tables |
1923 int si_region; /* region mask */ | 1923 int si_region; // region mask |
1924 vimconv_T si_conv; /* for conversion to 'encoding' */ | 1924 vimconv_T si_conv; // for conversion to 'encoding' |
1925 int si_memtot; /* runtime memory used */ | 1925 int si_memtot; // runtime memory used |
1926 int si_verbose; /* verbose messages */ | 1926 int si_verbose; // verbose messages |
1927 int si_msg_count; /* number of words added since last message */ | 1927 int si_msg_count; // number of words added since last message |
1928 char_u *si_info; /* info text chars or NULL */ | 1928 char_u *si_info; // info text chars or NULL |
1929 int si_region_count; /* number of regions supported (1 when there | 1929 int si_region_count; // number of regions supported (1 when there |
1930 are no regions) */ | 1930 // are no regions) |
1931 char_u si_region_name[MAXREGIONS * 2 + 1]; | 1931 char_u si_region_name[MAXREGIONS * 2 + 1]; |
1932 /* region names; used only if | 1932 // region names; used only if |
1933 * si_region_count > 1) */ | 1933 // si_region_count > 1) |
1934 | 1934 |
1935 garray_T si_rep; /* list of fromto_T entries from REP lines */ | 1935 garray_T si_rep; // list of fromto_T entries from REP lines |
1936 garray_T si_repsal; /* list of fromto_T entries from REPSAL lines */ | 1936 garray_T si_repsal; // list of fromto_T entries from REPSAL lines |
1937 garray_T si_sal; /* list of fromto_T entries from SAL lines */ | 1937 garray_T si_sal; // list of fromto_T entries from SAL lines |
1938 char_u *si_sofofr; /* SOFOFROM text */ | 1938 char_u *si_sofofr; // SOFOFROM text |
1939 char_u *si_sofoto; /* SOFOTO text */ | 1939 char_u *si_sofoto; // SOFOTO text |
1940 int si_nosugfile; /* NOSUGFILE item found */ | 1940 int si_nosugfile; // NOSUGFILE item found |
1941 int si_nosplitsugs; /* NOSPLITSUGS item found */ | 1941 int si_nosplitsugs; // NOSPLITSUGS item found |
1942 int si_nocompoundsugs; /* NOCOMPOUNDSUGS item found */ | 1942 int si_nocompoundsugs; // NOCOMPOUNDSUGS item found |
1943 int si_followup; /* soundsalike: ? */ | 1943 int si_followup; // soundsalike: ? |
1944 int si_collapse; /* soundsalike: ? */ | 1944 int si_collapse; // soundsalike: ? |
1945 hashtab_T si_commonwords; /* hashtable for common words */ | 1945 hashtab_T si_commonwords; // hashtable for common words |
1946 time_t si_sugtime; /* timestamp for .sug file */ | 1946 time_t si_sugtime; // timestamp for .sug file |
1947 int si_rem_accents; /* soundsalike: remove accents */ | 1947 int si_rem_accents; // soundsalike: remove accents |
1948 garray_T si_map; /* MAP info concatenated */ | 1948 garray_T si_map; // MAP info concatenated |
1949 char_u *si_midword; /* MIDWORD chars or NULL */ | 1949 char_u *si_midword; // MIDWORD chars or NULL |
1950 int si_compmax; /* max nr of words for compounding */ | 1950 int si_compmax; // max nr of words for compounding |
1951 int si_compminlen; /* minimal length for compounding */ | 1951 int si_compminlen; // minimal length for compounding |
1952 int si_compsylmax; /* max nr of syllables for compounding */ | 1952 int si_compsylmax; // max nr of syllables for compounding |
1953 int si_compoptions; /* COMP_ flags */ | 1953 int si_compoptions; // COMP_ flags |
1954 garray_T si_comppat; /* CHECKCOMPOUNDPATTERN items, each stored as | 1954 garray_T si_comppat; // CHECKCOMPOUNDPATTERN items, each stored as |
1955 a string */ | 1955 // a string |
1956 char_u *si_compflags; /* flags used for compounding */ | 1956 char_u *si_compflags; // flags used for compounding |
1957 char_u si_nobreak; /* NOBREAK */ | 1957 char_u si_nobreak; // NOBREAK |
1958 char_u *si_syllable; /* syllable string */ | 1958 char_u *si_syllable; // syllable string |
1959 garray_T si_prefcond; /* table with conditions for postponed | 1959 garray_T si_prefcond; // table with conditions for postponed |
1960 * prefixes, each stored as a string */ | 1960 // prefixes, each stored as a string |
1961 int si_newprefID; /* current value for ah_newID */ | 1961 int si_newprefID; // current value for ah_newID |
1962 int si_newcompID; /* current value for compound ID */ | 1962 int si_newcompID; // current value for compound ID |
1963 } spellinfo_T; | 1963 } spellinfo_T; |
1964 | 1964 |
1965 static int is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount); | 1965 static int is_aff_rule(char_u **items, int itemcnt, char *rulename, int mincount); |
1966 static void aff_process_flags(afffile_T *affile, affentry_T *entry); | 1966 static void aff_process_flags(afffile_T *affile, affentry_T *entry); |
1967 static int spell_info_item(char_u *s); | 1967 static int spell_info_item(char_u *s); |
1995 static int offset2bytes(int nr, char_u *buf); | 1995 static int offset2bytes(int nr, char_u *buf); |
1996 static void sug_write(spellinfo_T *spin, char_u *fname); | 1996 static void sug_write(spellinfo_T *spin, char_u *fname); |
1997 static void spell_message(spellinfo_T *spin, char_u *str); | 1997 static void spell_message(spellinfo_T *spin, char_u *str); |
1998 static void init_spellfile(void); | 1998 static void init_spellfile(void); |
1999 | 1999 |
2000 /* In the postponed prefixes tree wn_flags is used to store the WFP_ flags, | 2000 // In the postponed prefixes tree wn_flags is used to store the WFP_ flags, |
2001 * but it must be negative to indicate the prefix tree to tree_add_word(). | 2001 // but it must be negative to indicate the prefix tree to tree_add_word(). |
2002 * Use a negative number with the lower 8 bits zero. */ | 2002 // Use a negative number with the lower 8 bits zero. |
2003 #define PFX_FLAGS -256 | 2003 #define PFX_FLAGS -256 |
2004 | 2004 |
2005 /* flags for "condit" argument of store_aff_word() */ | 2005 // flags for "condit" argument of store_aff_word() |
2006 #define CONDIT_COMB 1 /* affix must combine */ | 2006 #define CONDIT_COMB 1 // affix must combine |
2007 #define CONDIT_CFIX 2 /* affix must have CIRCUMFIX flag */ | 2007 #define CONDIT_CFIX 2 // affix must have CIRCUMFIX flag |
2008 #define CONDIT_SUF 4 /* add a suffix for matching flags */ | 2008 #define CONDIT_SUF 4 // add a suffix for matching flags |
2009 #define CONDIT_AFF 8 /* word already has an affix */ | 2009 #define CONDIT_AFF 8 // word already has an affix |
2010 | 2010 |
2011 /* | 2011 /* |
2012 * Tunable parameters for when the tree is compressed. See 'mkspellmem'. | 2012 * Tunable parameters for when the tree is compressed. See 'mkspellmem'. |
2013 */ | 2013 */ |
2014 static long compress_start = 30000; /* memory / SBLOCKSIZE */ | 2014 static long compress_start = 30000; // memory / SBLOCKSIZE |
2015 static long compress_inc = 100; /* memory / SBLOCKSIZE */ | 2015 static long compress_inc = 100; // memory / SBLOCKSIZE |
2016 static long compress_added = 500000; /* word count */ | 2016 static long compress_added = 500000; // word count |
2017 | 2017 |
2018 /* | 2018 /* |
2019 * Check the 'mkspellmem' option. Return FAIL if it's wrong. | 2019 * Check the 'mkspellmem' option. Return FAIL if it's wrong. |
2020 * Sets "sps_flags". | 2020 * Sets "sps_flags". |
2021 */ | 2021 */ |
2027 long incr = 0; | 2027 long incr = 0; |
2028 long added = 0; | 2028 long added = 0; |
2029 | 2029 |
2030 if (!VIM_ISDIGIT(*p)) | 2030 if (!VIM_ISDIGIT(*p)) |
2031 return FAIL; | 2031 return FAIL; |
2032 /* block count = (value * 1024) / SBLOCKSIZE (but avoid overflow)*/ | 2032 // block count = (value * 1024) / SBLOCKSIZE (but avoid overflow) |
2033 start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102); | 2033 start = (getdigits(&p) * 10) / (SBLOCKSIZE / 102); |
2034 if (*p != ',') | 2034 if (*p != ',') |
2035 return FAIL; | 2035 return FAIL; |
2036 ++p; | 2036 ++p; |
2037 if (!VIM_ISDIGIT(*p)) | 2037 if (!VIM_ISDIGIT(*p)) |
2087 static void | 2087 static void |
2088 spell_print_node(wordnode_T *node, int depth) | 2088 spell_print_node(wordnode_T *node, int depth) |
2089 { | 2089 { |
2090 if (node->wn_u1.index) | 2090 if (node->wn_u1.index) |
2091 { | 2091 { |
2092 /* Done this node before, print the reference. */ | 2092 // Done this node before, print the reference. |
2093 PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); | 2093 PRINTSOME(line1, depth, "(%d)", node->wn_nr, 0); |
2094 PRINTSOME(line2, depth, " ", 0, 0); | 2094 PRINTSOME(line2, depth, " ", 0, 0); |
2095 PRINTSOME(line3, depth, " ", 0, 0); | 2095 PRINTSOME(line3, depth, " ", 0, 0); |
2096 msg(line1); | 2096 msg(line1); |
2097 msg(line2); | 2097 msg(line2); |
2104 if (node->wn_byte != NUL) | 2104 if (node->wn_byte != NUL) |
2105 { | 2105 { |
2106 if (node->wn_child != NULL) | 2106 if (node->wn_child != NULL) |
2107 PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0); | 2107 PRINTSOME(line1, depth, " %c -> ", node->wn_byte, 0); |
2108 else | 2108 else |
2109 /* Cannot happen? */ | 2109 // Cannot happen? |
2110 PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0); | 2110 PRINTSOME(line1, depth, " %c ???", node->wn_byte, 0); |
2111 } | 2111 } |
2112 else | 2112 else |
2113 PRINTSOME(line1, depth, " $ ", 0, 0); | 2113 PRINTSOME(line1, depth, " $ ", 0, 0); |
2114 | 2114 |
2124 msg(line1); | 2124 msg(line1); |
2125 msg(line2); | 2125 msg(line2); |
2126 msg(line3); | 2126 msg(line3); |
2127 } | 2127 } |
2128 | 2128 |
2129 /* do the children */ | 2129 // do the children |
2130 if (node->wn_byte != NUL && node->wn_child != NULL) | 2130 if (node->wn_byte != NUL && node->wn_child != NULL) |
2131 spell_print_node(node->wn_child, depth + 1); | 2131 spell_print_node(node->wn_child, depth + 1); |
2132 | 2132 |
2133 /* do the siblings */ | 2133 // do the siblings |
2134 if (node->wn_sibling != NULL) | 2134 if (node->wn_sibling != NULL) |
2135 { | 2135 { |
2136 /* get rid of all parent details except | */ | 2136 // get rid of all parent details except | |
2137 STRCPY(line1, line3); | 2137 STRCPY(line1, line3); |
2138 STRCPY(line2, line3); | 2138 STRCPY(line2, line3); |
2139 spell_print_node(node->wn_sibling, depth); | 2139 spell_print_node(node->wn_sibling, depth); |
2140 } | 2140 } |
2141 } | 2141 } |
2144 static void | 2144 static void |
2145 spell_print_tree(wordnode_T *root) | 2145 spell_print_tree(wordnode_T *root) |
2146 { | 2146 { |
2147 if (root != NULL) | 2147 if (root != NULL) |
2148 { | 2148 { |
2149 /* Clear the "wn_u1.index" fields, used to remember what has been | 2149 // Clear the "wn_u1.index" fields, used to remember what has been |
2150 * done. */ | 2150 // done. |
2151 spell_clear_flags(root); | 2151 spell_clear_flags(root); |
2152 | 2152 |
2153 /* Recursively print the tree. */ | 2153 // Recursively print the tree. |
2154 spell_print_node(root, 0); | 2154 spell_print_node(root, 0); |
2155 } | 2155 } |
2156 } | 2156 } |
2157 #endif /* SPELL_PRINTTREE */ | 2157 #endif // SPELL_PRINTTREE |
2158 | 2158 |
2159 /* | 2159 /* |
2160 * Read the affix file "fname". | 2160 * Read the affix file "fname". |
2161 * Returns an afffile_T, NULL for complete failure. | 2161 * Returns an afffile_T, NULL for complete failure. |
2162 */ | 2162 */ |
2185 int do_sal; | 2185 int do_sal; |
2186 int do_mapline; | 2186 int do_mapline; |
2187 int found_map = FALSE; | 2187 int found_map = FALSE; |
2188 hashitem_T *hi; | 2188 hashitem_T *hi; |
2189 int l; | 2189 int l; |
2190 int compminlen = 0; /* COMPOUNDMIN value */ | 2190 int compminlen = 0; // COMPOUNDMIN value |
2191 int compsylmax = 0; /* COMPOUNDSYLMAX value */ | 2191 int compsylmax = 0; // COMPOUNDSYLMAX value |
2192 int compoptions = 0; /* COMP_ flags */ | 2192 int compoptions = 0; // COMP_ flags |
2193 int compmax = 0; /* COMPOUNDWORDMAX value */ | 2193 int compmax = 0; // COMPOUNDWORDMAX value |
2194 char_u *compflags = NULL; /* COMPOUNDFLAG and COMPOUNDRULE | 2194 char_u *compflags = NULL; // COMPOUNDFLAG and COMPOUNDRULE |
2195 concatenated */ | 2195 // concatenated |
2196 char_u *midword = NULL; /* MIDWORD value */ | 2196 char_u *midword = NULL; // MIDWORD value |
2197 char_u *syllable = NULL; /* SYLLABLE value */ | 2197 char_u *syllable = NULL; // SYLLABLE value |
2198 char_u *sofofrom = NULL; /* SOFOFROM value */ | 2198 char_u *sofofrom = NULL; // SOFOFROM value |
2199 char_u *sofoto = NULL; /* SOFOTO value */ | 2199 char_u *sofoto = NULL; // SOFOTO value |
2200 | 2200 |
2201 /* | 2201 /* |
2202 * Open the file. | 2202 * Open the file. |
2203 */ | 2203 */ |
2204 fd = mch_fopen((char *)fname, "r"); | 2204 fd = mch_fopen((char *)fname, "r"); |
2209 } | 2209 } |
2210 | 2210 |
2211 vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname); | 2211 vim_snprintf((char *)IObuff, IOSIZE, _("Reading affix file %s..."), fname); |
2212 spell_message(spin, IObuff); | 2212 spell_message(spin, IObuff); |
2213 | 2213 |
2214 /* Only do REP lines when not done in another .aff file already. */ | 2214 // Only do REP lines when not done in another .aff file already. |
2215 do_rep = spin->si_rep.ga_len == 0; | 2215 do_rep = spin->si_rep.ga_len == 0; |
2216 | 2216 |
2217 /* Only do REPSAL lines when not done in another .aff file already. */ | 2217 // Only do REPSAL lines when not done in another .aff file already. |
2218 do_repsal = spin->si_repsal.ga_len == 0; | 2218 do_repsal = spin->si_repsal.ga_len == 0; |
2219 | 2219 |
2220 /* Only do SAL lines when not done in another .aff file already. */ | 2220 // Only do SAL lines when not done in another .aff file already. |
2221 do_sal = spin->si_sal.ga_len == 0; | 2221 do_sal = spin->si_sal.ga_len == 0; |
2222 | 2222 |
2223 /* Only do MAP lines when not done in another .aff file already. */ | 2223 // Only do MAP lines when not done in another .aff file already. |
2224 do_mapline = spin->si_map.ga_len == 0; | 2224 do_mapline = spin->si_map.ga_len == 0; |
2225 | 2225 |
2226 /* | 2226 /* |
2227 * Allocate and init the afffile_T structure. | 2227 * Allocate and init the afffile_T structure. |
2228 */ | 2228 */ |
2242 while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) | 2242 while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) |
2243 { | 2243 { |
2244 line_breakcheck(); | 2244 line_breakcheck(); |
2245 ++lnum; | 2245 ++lnum; |
2246 | 2246 |
2247 /* Skip comment lines. */ | 2247 // Skip comment lines. |
2248 if (*rline == '#') | 2248 if (*rline == '#') |
2249 continue; | 2249 continue; |
2250 | 2250 |
2251 /* Convert from "SET" to 'encoding' when needed. */ | 2251 // Convert from "SET" to 'encoding' when needed. |
2252 vim_free(pc); | 2252 vim_free(pc); |
2253 if (spin->si_conv.vc_type != CONV_NONE) | 2253 if (spin->si_conv.vc_type != CONV_NONE) |
2254 { | 2254 { |
2255 pc = string_convert(&spin->si_conv, rline, NULL); | 2255 pc = string_convert(&spin->si_conv, rline, NULL); |
2256 if (pc == NULL) | 2256 if (pc == NULL) |
2265 { | 2265 { |
2266 pc = NULL; | 2266 pc = NULL; |
2267 line = rline; | 2267 line = rline; |
2268 } | 2268 } |
2269 | 2269 |
2270 /* Split the line up in white separated items. Put a NUL after each | 2270 // Split the line up in white separated items. Put a NUL after each |
2271 * item. */ | 2271 // item. |
2272 itemcnt = 0; | 2272 itemcnt = 0; |
2273 for (p = line; ; ) | 2273 for (p = line; ; ) |
2274 { | 2274 { |
2275 while (*p != NUL && *p <= ' ') /* skip white space and CR/NL */ | 2275 while (*p != NUL && *p <= ' ') // skip white space and CR/NL |
2276 ++p; | 2276 ++p; |
2277 if (*p == NUL) | 2277 if (*p == NUL) |
2278 break; | 2278 break; |
2279 if (itemcnt == MAXITEMCNT) /* too many items */ | 2279 if (itemcnt == MAXITEMCNT) // too many items |
2280 break; | 2280 break; |
2281 items[itemcnt++] = p; | 2281 items[itemcnt++] = p; |
2282 /* A few items have arbitrary text argument, don't split them. */ | 2282 // A few items have arbitrary text argument, don't split them. |
2283 if (itemcnt == 2 && spell_info_item(items[0])) | 2283 if (itemcnt == 2 && spell_info_item(items[0])) |
2284 while (*p >= ' ' || *p == TAB) /* skip until CR/NL */ | 2284 while (*p >= ' ' || *p == TAB) // skip until CR/NL |
2285 ++p; | 2285 ++p; |
2286 else | 2286 else |
2287 while (*p > ' ') /* skip until white space or CR/NL */ | 2287 while (*p > ' ') // skip until white space or CR/NL |
2288 ++p; | 2288 ++p; |
2289 if (*p == NUL) | 2289 if (*p == NUL) |
2290 break; | 2290 break; |
2291 *p++ = NUL; | 2291 *p++ = NUL; |
2292 } | 2292 } |
2293 | 2293 |
2294 /* Handle non-empty lines. */ | 2294 // Handle non-empty lines. |
2295 if (itemcnt > 0) | 2295 if (itemcnt > 0) |
2296 { | 2296 { |
2297 if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) | 2297 if (is_aff_rule(items, itemcnt, "SET", 2) && aff->af_enc == NULL) |
2298 { | 2298 { |
2299 /* Setup for conversion from "ENC" to 'encoding'. */ | 2299 // Setup for conversion from "ENC" to 'encoding'. |
2300 aff->af_enc = enc_canonize(items[1]); | 2300 aff->af_enc = enc_canonize(items[1]); |
2301 if (aff->af_enc != NULL && !spin->si_ascii | 2301 if (aff->af_enc != NULL && !spin->si_ascii |
2302 && convert_setup(&spin->si_conv, aff->af_enc, | 2302 && convert_setup(&spin->si_conv, aff->af_enc, |
2303 p_enc) == FAIL) | 2303 p_enc) == FAIL) |
2304 smsg(_("Conversion in %s not supported: from %s to %s"), | 2304 smsg(_("Conversion in %s not supported: from %s to %s"), |
2355 { | 2355 { |
2356 midword = getroom_save(spin, items[1]); | 2356 midword = getroom_save(spin, items[1]); |
2357 } | 2357 } |
2358 else if (is_aff_rule(items, itemcnt, "TRY", 2)) | 2358 else if (is_aff_rule(items, itemcnt, "TRY", 2)) |
2359 { | 2359 { |
2360 /* ignored, we look in the tree for what chars may appear */ | 2360 // ignored, we look in the tree for what chars may appear |
2361 } | 2361 } |
2362 /* TODO: remove "RAR" later */ | 2362 // TODO: remove "RAR" later |
2363 else if ((is_aff_rule(items, itemcnt, "RAR", 2) | 2363 else if ((is_aff_rule(items, itemcnt, "RAR", 2) |
2364 || is_aff_rule(items, itemcnt, "RARE", 2)) | 2364 || is_aff_rule(items, itemcnt, "RARE", 2)) |
2365 && aff->af_rare == 0) | 2365 && aff->af_rare == 0) |
2366 { | 2366 { |
2367 aff->af_rare = affitem2flag(aff->af_flagtype, items[1], | 2367 aff->af_rare = affitem2flag(aff->af_flagtype, items[1], |
2368 fname, lnum); | 2368 fname, lnum); |
2369 } | 2369 } |
2370 /* TODO: remove "KEP" later */ | 2370 // TODO: remove "KEP" later |
2371 else if ((is_aff_rule(items, itemcnt, "KEP", 2) | 2371 else if ((is_aff_rule(items, itemcnt, "KEP", 2) |
2372 || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) | 2372 || is_aff_rule(items, itemcnt, "KEEPCASE", 2)) |
2373 && aff->af_keepcase == 0) | 2373 && aff->af_keepcase == 0) |
2374 { | 2374 { |
2375 aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1], | 2375 aff->af_keepcase = affitem2flag(aff->af_flagtype, items[1], |
2432 fname, lnum); | 2432 fname, lnum); |
2433 } | 2433 } |
2434 else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) | 2434 else if (is_aff_rule(items, itemcnt, "COMPOUNDFLAG", 2) |
2435 && compflags == NULL) | 2435 && compflags == NULL) |
2436 { | 2436 { |
2437 /* Turn flag "c" into COMPOUNDRULE compatible string "c+", | 2437 // Turn flag "c" into COMPOUNDRULE compatible string "c+", |
2438 * "Na" into "Na+", "1234" into "1234+". */ | 2438 // "Na" into "Na+", "1234" into "1234+". |
2439 p = getroom(spin, STRLEN(items[1]) + 2, FALSE); | 2439 p = getroom(spin, STRLEN(items[1]) + 2, FALSE); |
2440 if (p != NULL) | 2440 if (p != NULL) |
2441 { | 2441 { |
2442 STRCPY(p, items[1]); | 2442 STRCPY(p, items[1]); |
2443 STRCAT(p, "+"); | 2443 STRCAT(p, "+"); |
2444 compflags = p; | 2444 compflags = p; |
2445 } | 2445 } |
2446 } | 2446 } |
2447 else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) | 2447 else if (is_aff_rule(items, itemcnt, "COMPOUNDRULES", 2)) |
2448 { | 2448 { |
2449 /* We don't use the count, but do check that it's a number and | 2449 // We don't use the count, but do check that it's a number and |
2450 * not COMPOUNDRULE mistyped. */ | 2450 // not COMPOUNDRULE mistyped. |
2451 if (atoi((char *)items[1]) == 0) | 2451 if (atoi((char *)items[1]) == 0) |
2452 smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), | 2452 smsg(_("Wrong COMPOUNDRULES value in %s line %d: %s"), |
2453 fname, lnum, items[1]); | 2453 fname, lnum, items[1]); |
2454 } | 2454 } |
2455 else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) | 2455 else if (is_aff_rule(items, itemcnt, "COMPOUNDRULE", 2)) |
2456 { | 2456 { |
2457 /* Don't use the first rule if it is a number. */ | 2457 // Don't use the first rule if it is a number. |
2458 if (compflags != NULL || *skipdigits(items[1]) != NUL) | 2458 if (compflags != NULL || *skipdigits(items[1]) != NUL) |
2459 { | 2459 { |
2460 /* Concatenate this string to previously defined ones, | 2460 // Concatenate this string to previously defined ones, |
2461 * using a slash to separate them. */ | 2461 // using a slash to separate them. |
2462 l = (int)STRLEN(items[1]) + 1; | 2462 l = (int)STRLEN(items[1]) + 1; |
2463 if (compflags != NULL) | 2463 if (compflags != NULL) |
2464 l += (int)STRLEN(compflags) + 1; | 2464 l += (int)STRLEN(compflags) + 1; |
2465 p = getroom(spin, l, FALSE); | 2465 p = getroom(spin, l, FALSE); |
2466 if (p != NULL) | 2466 if (p != NULL) |
2524 else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) | 2524 else if (is_aff_rule(items, itemcnt, "CHECKCOMPOUNDPATTERN", 3)) |
2525 { | 2525 { |
2526 garray_T *gap = &spin->si_comppat; | 2526 garray_T *gap = &spin->si_comppat; |
2527 int i; | 2527 int i; |
2528 | 2528 |
2529 /* Only add the couple if it isn't already there. */ | 2529 // Only add the couple if it isn't already there. |
2530 for (i = 0; i < gap->ga_len - 1; i += 2) | 2530 for (i = 0; i < gap->ga_len - 1; i += 2) |
2531 if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0 | 2531 if (STRCMP(((char_u **)(gap->ga_data))[i], items[1]) == 0 |
2532 && STRCMP(((char_u **)(gap->ga_data))[i + 1], | 2532 && STRCMP(((char_u **)(gap->ga_data))[i + 1], |
2533 items[2]) == 0) | 2533 items[2]) == 0) |
2534 break; | 2534 break; |
2580 if (*items[0] == 'P') | 2580 if (*items[0] == 'P') |
2581 tp = &aff->af_pref; | 2581 tp = &aff->af_pref; |
2582 else | 2582 else |
2583 tp = &aff->af_suff; | 2583 tp = &aff->af_suff; |
2584 | 2584 |
2585 /* Myspell allows the same affix name to be used multiple | 2585 // Myspell allows the same affix name to be used multiple |
2586 * times. The affix files that do this have an undocumented | 2586 // times. The affix files that do this have an undocumented |
2587 * "S" flag on all but the last block, thus we check for that | 2587 // "S" flag on all but the last block, thus we check for that |
2588 * and store it in ah_follows. */ | 2588 // and store it in ah_follows. |
2589 vim_strncpy(key, items[1], AH_KEY_LEN - 1); | 2589 vim_strncpy(key, items[1], AH_KEY_LEN - 1); |
2590 hi = hash_find(tp, key); | 2590 hi = hash_find(tp, key); |
2591 if (!HASHITEM_EMPTY(hi)) | 2591 if (!HASHITEM_EMPTY(hi)) |
2592 { | 2592 { |
2593 cur_aff = HI2AH(hi); | 2593 cur_aff = HI2AH(hi); |
2598 smsg(_("Duplicate affix in %s line %d: %s"), | 2598 smsg(_("Duplicate affix in %s line %d: %s"), |
2599 fname, lnum, items[1]); | 2599 fname, lnum, items[1]); |
2600 } | 2600 } |
2601 else | 2601 else |
2602 { | 2602 { |
2603 /* New affix letter. */ | 2603 // New affix letter. |
2604 cur_aff = (affheader_T *)getroom(spin, | 2604 cur_aff = (affheader_T *)getroom(spin, |
2605 sizeof(affheader_T), TRUE); | 2605 sizeof(affheader_T), TRUE); |
2606 if (cur_aff == NULL) | 2606 if (cur_aff == NULL) |
2607 break; | 2607 break; |
2608 cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1], | 2608 cur_aff->ah_flag = affitem2flag(aff->af_flagtype, items[1], |
2623 hash_add(tp, cur_aff->ah_key); | 2623 hash_add(tp, cur_aff->ah_key); |
2624 | 2624 |
2625 cur_aff->ah_combine = (*items[2] == 'Y'); | 2625 cur_aff->ah_combine = (*items[2] == 'Y'); |
2626 } | 2626 } |
2627 | 2627 |
2628 /* Check for the "S" flag, which apparently means that another | 2628 // Check for the "S" flag, which apparently means that another |
2629 * block with the same affix name is following. */ | 2629 // block with the same affix name is following. |
2630 if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) | 2630 if (itemcnt > lasti && STRCMP(items[lasti], "S") == 0) |
2631 { | 2631 { |
2632 ++lasti; | 2632 ++lasti; |
2633 cur_aff->ah_follows = TRUE; | 2633 cur_aff->ah_follows = TRUE; |
2634 } | 2634 } |
2635 else | 2635 else |
2636 cur_aff->ah_follows = FALSE; | 2636 cur_aff->ah_follows = FALSE; |
2637 | 2637 |
2638 /* Myspell allows extra text after the item, but that might | 2638 // Myspell allows extra text after the item, but that might |
2639 * mean mistakes go unnoticed. Require a comment-starter. */ | 2639 // mean mistakes go unnoticed. Require a comment-starter. |
2640 if (itemcnt > lasti && *items[lasti] != '#') | 2640 if (itemcnt > lasti && *items[lasti] != '#') |
2641 smsg(_(e_afftrailing), fname, lnum, items[lasti]); | 2641 smsg(_(e_afftrailing), fname, lnum, items[lasti]); |
2642 | 2642 |
2643 if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) | 2643 if (STRCMP(items[2], "Y") != 0 && STRCMP(items[2], "N") != 0) |
2644 smsg(_("Expected Y or N in %s line %d: %s"), | 2644 smsg(_("Expected Y or N in %s line %d: %s"), |
2646 | 2646 |
2647 if (*items[0] == 'P' && aff->af_pfxpostpone) | 2647 if (*items[0] == 'P' && aff->af_pfxpostpone) |
2648 { | 2648 { |
2649 if (cur_aff->ah_newID == 0) | 2649 if (cur_aff->ah_newID == 0) |
2650 { | 2650 { |
2651 /* Use a new number in the .spl file later, to be able | 2651 // Use a new number in the .spl file later, to be able |
2652 * to handle multiple .aff files. */ | 2652 // to handle multiple .aff files. |
2653 check_renumber(spin); | 2653 check_renumber(spin); |
2654 cur_aff->ah_newID = ++spin->si_newprefID; | 2654 cur_aff->ah_newID = ++spin->si_newprefID; |
2655 | 2655 |
2656 /* We only really use ah_newID if the prefix is | 2656 // We only really use ah_newID if the prefix is |
2657 * postponed. We know that only after handling all | 2657 // postponed. We know that only after handling all |
2658 * the items. */ | 2658 // the items. |
2659 did_postpone_prefix = FALSE; | 2659 did_postpone_prefix = FALSE; |
2660 } | 2660 } |
2661 else | 2661 else |
2662 /* Did use the ID in a previous block. */ | 2662 // Did use the ID in a previous block. |
2663 did_postpone_prefix = TRUE; | 2663 did_postpone_prefix = TRUE; |
2664 } | 2664 } |
2665 | 2665 |
2666 aff_todo = atoi((char *)items[3]); | 2666 aff_todo = atoi((char *)items[3]); |
2667 } | 2667 } |
2673 { | 2673 { |
2674 affentry_T *aff_entry; | 2674 affentry_T *aff_entry; |
2675 int upper = FALSE; | 2675 int upper = FALSE; |
2676 int lasti = 5; | 2676 int lasti = 5; |
2677 | 2677 |
2678 /* Myspell allows extra text after the item, but that might | 2678 // Myspell allows extra text after the item, but that might |
2679 * mean mistakes go unnoticed. Require a comment-starter, | 2679 // mean mistakes go unnoticed. Require a comment-starter, |
2680 * unless IGNOREEXTRA is used. Hunspell uses a "-" item. */ | 2680 // unless IGNOREEXTRA is used. Hunspell uses a "-" item. |
2681 if (itemcnt > lasti | 2681 if (itemcnt > lasti |
2682 && !aff->af_ignoreextra | 2682 && !aff->af_ignoreextra |
2683 && *items[lasti] != '#' | 2683 && *items[lasti] != '#' |
2684 && (STRCMP(items[lasti], "-") != 0 | 2684 && (STRCMP(items[lasti], "-") != 0 |
2685 || itemcnt != lasti + 1)) | 2685 || itemcnt != lasti + 1)) |
2686 smsg(_(e_afftrailing), fname, lnum, items[lasti]); | 2686 smsg(_(e_afftrailing), fname, lnum, items[lasti]); |
2687 | 2687 |
2688 /* New item for an affix letter. */ | 2688 // New item for an affix letter. |
2689 --aff_todo; | 2689 --aff_todo; |
2690 aff_entry = (affentry_T *)getroom(spin, | 2690 aff_entry = (affentry_T *)getroom(spin, |
2691 sizeof(affentry_T), TRUE); | 2691 sizeof(affentry_T), TRUE); |
2692 if (aff_entry == NULL) | 2692 if (aff_entry == NULL) |
2693 break; | 2693 break; |
2696 aff_entry->ae_chop = getroom_save(spin, items[2]); | 2696 aff_entry->ae_chop = getroom_save(spin, items[2]); |
2697 if (STRCMP(items[3], "0") != 0) | 2697 if (STRCMP(items[3], "0") != 0) |
2698 { | 2698 { |
2699 aff_entry->ae_add = getroom_save(spin, items[3]); | 2699 aff_entry->ae_add = getroom_save(spin, items[3]); |
2700 | 2700 |
2701 /* Recognize flags on the affix: abcd/XYZ */ | 2701 // Recognize flags on the affix: abcd/XYZ |
2702 aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/'); | 2702 aff_entry->ae_flags = vim_strchr(aff_entry->ae_add, '/'); |
2703 if (aff_entry->ae_flags != NULL) | 2703 if (aff_entry->ae_flags != NULL) |
2704 { | 2704 { |
2705 *aff_entry->ae_flags++ = NUL; | 2705 *aff_entry->ae_flags++ = NUL; |
2706 aff_process_flags(aff, aff_entry); | 2706 aff_process_flags(aff, aff_entry); |
2707 } | 2707 } |
2708 } | 2708 } |
2709 | 2709 |
2710 /* Don't use an affix entry with non-ASCII characters when | 2710 // Don't use an affix entry with non-ASCII characters when |
2711 * "spin->si_ascii" is TRUE. */ | 2711 // "spin->si_ascii" is TRUE. |
2712 if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop) | 2712 if (!spin->si_ascii || !(has_non_ascii(aff_entry->ae_chop) |
2713 || has_non_ascii(aff_entry->ae_add))) | 2713 || has_non_ascii(aff_entry->ae_add))) |
2714 { | 2714 { |
2715 aff_entry->ae_next = cur_aff->ah_first; | 2715 aff_entry->ae_next = cur_aff->ah_first; |
2716 cur_aff->ah_first = aff_entry; | 2716 cur_aff->ah_first = aff_entry; |
2729 if (aff_entry->ae_prog == NULL) | 2729 if (aff_entry->ae_prog == NULL) |
2730 smsg(_("Broken condition in %s line %d: %s"), | 2730 smsg(_("Broken condition in %s line %d: %s"), |
2731 fname, lnum, items[4]); | 2731 fname, lnum, items[4]); |
2732 } | 2732 } |
2733 | 2733 |
2734 /* For postponed prefixes we need an entry in si_prefcond | 2734 // For postponed prefixes we need an entry in si_prefcond |
2735 * for the condition. Use an existing one if possible. | 2735 // for the condition. Use an existing one if possible. |
2736 * Can't be done for an affix with flags, ignoring | 2736 // Can't be done for an affix with flags, ignoring |
2737 * COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. */ | 2737 // COMPOUNDFORBIDFLAG and COMPOUNDPERMITFLAG. |
2738 if (*items[0] == 'P' && aff->af_pfxpostpone | 2738 if (*items[0] == 'P' && aff->af_pfxpostpone |
2739 && aff_entry->ae_flags == NULL) | 2739 && aff_entry->ae_flags == NULL) |
2740 { | 2740 { |
2741 /* When the chop string is one lower-case letter and | 2741 // When the chop string is one lower-case letter and |
2742 * the add string ends in the upper-case letter we set | 2742 // the add string ends in the upper-case letter we set |
2743 * the "upper" flag, clear "ae_chop" and remove the | 2743 // the "upper" flag, clear "ae_chop" and remove the |
2744 * letters from "ae_add". The condition must either | 2744 // letters from "ae_add". The condition must either |
2745 * be empty or start with the same letter. */ | 2745 // be empty or start with the same letter. |
2746 if (aff_entry->ae_chop != NULL | 2746 if (aff_entry->ae_chop != NULL |
2747 && aff_entry->ae_add != NULL | 2747 && aff_entry->ae_add != NULL |
2748 && aff_entry->ae_chop[(*mb_ptr2len)( | 2748 && aff_entry->ae_chop[(*mb_ptr2len)( |
2749 aff_entry->ae_chop)] == NUL) | 2749 aff_entry->ae_chop)] == NUL) |
2750 { | 2750 { |
2763 { | 2763 { |
2764 upper = TRUE; | 2764 upper = TRUE; |
2765 aff_entry->ae_chop = NULL; | 2765 aff_entry->ae_chop = NULL; |
2766 *p = NUL; | 2766 *p = NUL; |
2767 | 2767 |
2768 /* The condition is matched with the | 2768 // The condition is matched with the |
2769 * actual word, thus must check for the | 2769 // actual word, thus must check for the |
2770 * upper-case letter. */ | 2770 // upper-case letter. |
2771 if (aff_entry->ae_cond != NULL) | 2771 if (aff_entry->ae_cond != NULL) |
2772 { | 2772 { |
2773 char_u buf[MAXLINELEN]; | 2773 char_u buf[MAXLINELEN]; |
2774 | 2774 |
2775 if (has_mbyte) | 2775 if (has_mbyte) |
2798 { | 2798 { |
2799 int idx; | 2799 int idx; |
2800 char_u **pp; | 2800 char_u **pp; |
2801 int n; | 2801 int n; |
2802 | 2802 |
2803 /* Find a previously used condition. */ | 2803 // Find a previously used condition. |
2804 for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; | 2804 for (idx = spin->si_prefcond.ga_len - 1; idx >= 0; |
2805 --idx) | 2805 --idx) |
2806 { | 2806 { |
2807 p = ((char_u **)spin->si_prefcond.ga_data)[idx]; | 2807 p = ((char_u **)spin->si_prefcond.ga_data)[idx]; |
2808 if (str_equal(p, aff_entry->ae_cond)) | 2808 if (str_equal(p, aff_entry->ae_cond)) |
2809 break; | 2809 break; |
2810 } | 2810 } |
2811 if (idx < 0 && ga_grow(&spin->si_prefcond, 1) == OK) | 2811 if (idx < 0 && ga_grow(&spin->si_prefcond, 1) == OK) |
2812 { | 2812 { |
2813 /* Not found, add a new condition. */ | 2813 // Not found, add a new condition. |
2814 idx = spin->si_prefcond.ga_len++; | 2814 idx = spin->si_prefcond.ga_len++; |
2815 pp = ((char_u **)spin->si_prefcond.ga_data) | 2815 pp = ((char_u **)spin->si_prefcond.ga_data) |
2816 + idx; | 2816 + idx; |
2817 if (aff_entry->ae_cond == NULL) | 2817 if (aff_entry->ae_cond == NULL) |
2818 *pp = NULL; | 2818 *pp = NULL; |
2819 else | 2819 else |
2820 *pp = getroom_save(spin, | 2820 *pp = getroom_save(spin, |
2821 aff_entry->ae_cond); | 2821 aff_entry->ae_cond); |
2822 } | 2822 } |
2823 | 2823 |
2824 /* Add the prefix to the prefix tree. */ | 2824 // Add the prefix to the prefix tree. |
2825 if (aff_entry->ae_add == NULL) | 2825 if (aff_entry->ae_add == NULL) |
2826 p = (char_u *)""; | 2826 p = (char_u *)""; |
2827 else | 2827 else |
2828 p = aff_entry->ae_add; | 2828 p = aff_entry->ae_add; |
2829 | 2829 |
2830 /* PFX_FLAGS is a negative number, so that | 2830 // PFX_FLAGS is a negative number, so that |
2831 * tree_add_word() knows this is the prefix tree. */ | 2831 // tree_add_word() knows this is the prefix tree. |
2832 n = PFX_FLAGS; | 2832 n = PFX_FLAGS; |
2833 if (!cur_aff->ah_combine) | 2833 if (!cur_aff->ah_combine) |
2834 n |= WFP_NC; | 2834 n |= WFP_NC; |
2835 if (upper) | 2835 if (upper) |
2836 n |= WFP_UP; | 2836 n |= WFP_UP; |
2841 tree_add_word(spin, p, spin->si_prefroot, n, | 2841 tree_add_word(spin, p, spin->si_prefroot, n, |
2842 idx, cur_aff->ah_newID); | 2842 idx, cur_aff->ah_newID); |
2843 did_postpone_prefix = TRUE; | 2843 did_postpone_prefix = TRUE; |
2844 } | 2844 } |
2845 | 2845 |
2846 /* Didn't actually use ah_newID, backup si_newprefID. */ | 2846 // Didn't actually use ah_newID, backup si_newprefID. |
2847 if (aff_todo == 0 && !did_postpone_prefix) | 2847 if (aff_todo == 0 && !did_postpone_prefix) |
2848 { | 2848 { |
2849 --spin->si_newprefID; | 2849 --spin->si_newprefID; |
2850 cur_aff->ah_newID = 0; | 2850 cur_aff->ah_newID = 0; |
2851 } | 2851 } |
2865 upp = vim_strsave(items[1]); | 2865 upp = vim_strsave(items[1]); |
2866 } | 2866 } |
2867 else if (is_aff_rule(items, itemcnt, "REP", 2) | 2867 else if (is_aff_rule(items, itemcnt, "REP", 2) |
2868 || is_aff_rule(items, itemcnt, "REPSAL", 2)) | 2868 || is_aff_rule(items, itemcnt, "REPSAL", 2)) |
2869 { | 2869 { |
2870 /* Ignore REP/REPSAL count */; | 2870 // Ignore REP/REPSAL count |
2871 if (!isdigit(*items[1])) | 2871 if (!isdigit(*items[1])) |
2872 smsg(_("Expected REP(SAL) count in %s line %d"), | 2872 smsg(_("Expected REP(SAL) count in %s line %d"), |
2873 fname, lnum); | 2873 fname, lnum); |
2874 } | 2874 } |
2875 else if ((STRCMP(items[0], "REP") == 0 | 2875 else if ((STRCMP(items[0], "REP") == 0 |
2876 || STRCMP(items[0], "REPSAL") == 0) | 2876 || STRCMP(items[0], "REPSAL") == 0) |
2877 && itemcnt >= 3) | 2877 && itemcnt >= 3) |
2878 { | 2878 { |
2879 /* REP/REPSAL item */ | 2879 // REP/REPSAL item |
2880 /* Myspell ignores extra arguments, we require it starts with | 2880 // Myspell ignores extra arguments, we require it starts with |
2881 * # to detect mistakes. */ | 2881 // # to detect mistakes. |
2882 if (itemcnt > 3 && items[3][0] != '#') | 2882 if (itemcnt > 3 && items[3][0] != '#') |
2883 smsg(_(e_afftrailing), fname, lnum, items[3]); | 2883 smsg(_(e_afftrailing), fname, lnum, items[3]); |
2884 if (items[0][3] == 'S' ? do_repsal : do_rep) | 2884 if (items[0][3] == 'S' ? do_repsal : do_rep) |
2885 { | 2885 { |
2886 /* Replace underscore with space (can't include a space | 2886 // Replace underscore with space (can't include a space |
2887 * directly). */ | 2887 // directly). |
2888 for (p = items[1]; *p != NUL; MB_PTR_ADV(p)) | 2888 for (p = items[1]; *p != NUL; MB_PTR_ADV(p)) |
2889 if (*p == '_') | 2889 if (*p == '_') |
2890 *p = ' '; | 2890 *p = ' '; |
2891 for (p = items[2]; *p != NUL; MB_PTR_ADV(p)) | 2891 for (p = items[2]; *p != NUL; MB_PTR_ADV(p)) |
2892 if (*p == '_') | 2892 if (*p == '_') |
2896 : &spin->si_rep, items[1], items[2]); | 2896 : &spin->si_rep, items[1], items[2]); |
2897 } | 2897 } |
2898 } | 2898 } |
2899 else if (is_aff_rule(items, itemcnt, "MAP", 2)) | 2899 else if (is_aff_rule(items, itemcnt, "MAP", 2)) |
2900 { | 2900 { |
2901 /* MAP item or count */ | 2901 // MAP item or count |
2902 if (!found_map) | 2902 if (!found_map) |
2903 { | 2903 { |
2904 /* First line contains the count. */ | 2904 // First line contains the count. |
2905 found_map = TRUE; | 2905 found_map = TRUE; |
2906 if (!isdigit(*items[1])) | 2906 if (!isdigit(*items[1])) |
2907 smsg(_("Expected MAP count in %s line %d"), | 2907 smsg(_("Expected MAP count in %s line %d"), |
2908 fname, lnum); | 2908 fname, lnum); |
2909 } | 2909 } |
2910 else if (do_mapline) | 2910 else if (do_mapline) |
2911 { | 2911 { |
2912 int c; | 2912 int c; |
2913 | 2913 |
2914 /* Check that every character appears only once. */ | 2914 // Check that every character appears only once. |
2915 for (p = items[1]; *p != NUL; ) | 2915 for (p = items[1]; *p != NUL; ) |
2916 { | 2916 { |
2917 c = mb_ptr2char_adv(&p); | 2917 c = mb_ptr2char_adv(&p); |
2918 if ((spin->si_map.ga_len > 0 | 2918 if ((spin->si_map.ga_len > 0 |
2919 && vim_strchr(spin->si_map.ga_data, c) | 2919 && vim_strchr(spin->si_map.ga_data, c) |
2921 || vim_strchr(p, c) != NULL) | 2921 || vim_strchr(p, c) != NULL) |
2922 smsg(_("Duplicate character in MAP in %s line %d"), | 2922 smsg(_("Duplicate character in MAP in %s line %d"), |
2923 fname, lnum); | 2923 fname, lnum); |
2924 } | 2924 } |
2925 | 2925 |
2926 /* We simply concatenate all the MAP strings, separated by | 2926 // We simply concatenate all the MAP strings, separated by |
2927 * slashes. */ | 2927 // slashes. |
2928 ga_concat(&spin->si_map, items[1]); | 2928 ga_concat(&spin->si_map, items[1]); |
2929 ga_append(&spin->si_map, '/'); | 2929 ga_append(&spin->si_map, '/'); |
2930 } | 2930 } |
2931 } | 2931 } |
2932 /* Accept "SAL from to" and "SAL from to #comment". */ | 2932 // Accept "SAL from to" and "SAL from to #comment". |
2933 else if (is_aff_rule(items, itemcnt, "SAL", 3)) | 2933 else if (is_aff_rule(items, itemcnt, "SAL", 3)) |
2934 { | 2934 { |
2935 if (do_sal) | 2935 if (do_sal) |
2936 { | 2936 { |
2937 /* SAL item (sounds-a-like) | 2937 // SAL item (sounds-a-like) |
2938 * Either one of the known keys or a from-to pair. */ | 2938 // Either one of the known keys or a from-to pair. |
2939 if (STRCMP(items[1], "followup") == 0) | 2939 if (STRCMP(items[1], "followup") == 0) |
2940 spin->si_followup = sal_to_bool(items[2]); | 2940 spin->si_followup = sal_to_bool(items[2]); |
2941 else if (STRCMP(items[1], "collapse_result") == 0) | 2941 else if (STRCMP(items[1], "collapse_result") == 0) |
2942 spin->si_collapse = sal_to_bool(items[2]); | 2942 spin->si_collapse = sal_to_bool(items[2]); |
2943 else if (STRCMP(items[1], "remove_accents") == 0) | 2943 else if (STRCMP(items[1], "remove_accents") == 0) |
2944 spin->si_rem_accents = sal_to_bool(items[2]); | 2944 spin->si_rem_accents = sal_to_bool(items[2]); |
2945 else | 2945 else |
2946 /* when "to" is "_" it means empty */ | 2946 // when "to" is "_" it means empty |
2947 add_fromto(spin, &spin->si_sal, items[1], | 2947 add_fromto(spin, &spin->si_sal, items[1], |
2948 STRCMP(items[2], "_") == 0 ? (char_u *)"" | 2948 STRCMP(items[2], "_") == 0 ? (char_u *)"" |
2949 : items[2]); | 2949 : items[2]); |
2950 } | 2950 } |
2951 } | 2951 } |
2983 | 2983 |
2984 if (fol != NULL || low != NULL || upp != NULL) | 2984 if (fol != NULL || low != NULL || upp != NULL) |
2985 { | 2985 { |
2986 if (spin->si_clear_chartab) | 2986 if (spin->si_clear_chartab) |
2987 { | 2987 { |
2988 /* Clear the char type tables, don't want to use any of the | 2988 // Clear the char type tables, don't want to use any of the |
2989 * currently used spell properties. */ | 2989 // currently used spell properties. |
2990 init_spell_chartab(); | 2990 init_spell_chartab(); |
2991 spin->si_clear_chartab = FALSE; | 2991 spin->si_clear_chartab = FALSE; |
2992 } | 2992 } |
2993 | 2993 |
2994 /* | 2994 /* |
3008 vim_free(fol); | 3008 vim_free(fol); |
3009 vim_free(low); | 3009 vim_free(low); |
3010 vim_free(upp); | 3010 vim_free(upp); |
3011 } | 3011 } |
3012 | 3012 |
3013 /* Use compound specifications of the .aff file for the spell info. */ | 3013 // Use compound specifications of the .aff file for the spell info. |
3014 if (compmax != 0) | 3014 if (compmax != 0) |
3015 { | 3015 { |
3016 aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX"); | 3016 aff_check_number(spin->si_compmax, compmax, "COMPOUNDWORDMAX"); |
3017 spin->si_compmax = compmax; | 3017 spin->si_compmax = compmax; |
3018 } | 3018 } |
3038 } | 3038 } |
3039 | 3039 |
3040 if (compflags != NULL) | 3040 if (compflags != NULL) |
3041 process_compflags(spin, aff, compflags); | 3041 process_compflags(spin, aff, compflags); |
3042 | 3042 |
3043 /* Check that we didn't use too many renumbered flags. */ | 3043 // Check that we didn't use too many renumbered flags. |
3044 if (spin->si_newcompID < spin->si_newprefID) | 3044 if (spin->si_newcompID < spin->si_newprefID) |
3045 { | 3045 { |
3046 if (spin->si_newcompID == 127 || spin->si_newcompID == 255) | 3046 if (spin->si_newcompID == 127 || spin->si_newcompID == 255) |
3047 msg(_("Too many postponed prefixes")); | 3047 msg(_("Too many postponed prefixes")); |
3048 else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) | 3048 else if (spin->si_newprefID == 0 || spin->si_newprefID == 127) |
3129 } | 3129 } |
3130 if (affile->af_flagtype == AFT_NUM && *p == ',') | 3130 if (affile->af_flagtype == AFT_NUM && *p == ',') |
3131 ++p; | 3131 ++p; |
3132 } | 3132 } |
3133 if (*entry->ae_flags == NUL) | 3133 if (*entry->ae_flags == NUL) |
3134 entry->ae_flags = NULL; /* nothing left */ | 3134 entry->ae_flags = NULL; // nothing left |
3135 } | 3135 } |
3136 } | 3136 } |
3137 | 3137 |
3138 /* | 3138 /* |
3139 * Return TRUE if "s" is the name of an info item in the affix file. | 3139 * Return TRUE if "s" is the name of an info item in the affix file. |
3194 | 3194 |
3195 if (flagtype == AFT_NUM) | 3195 if (flagtype == AFT_NUM) |
3196 { | 3196 { |
3197 if (!VIM_ISDIGIT(**pp)) | 3197 if (!VIM_ISDIGIT(**pp)) |
3198 { | 3198 { |
3199 ++*pp; /* always advance, avoid getting stuck */ | 3199 ++*pp; // always advance, avoid getting stuck |
3200 return 0; | 3200 return 0; |
3201 } | 3201 } |
3202 res = getdigits(pp); | 3202 res = getdigits(pp); |
3203 if (res == 0) | 3203 if (res == 0) |
3204 res = ZERO_FLAG; | 3204 res = ZERO_FLAG; |
3237 int len; | 3237 int len; |
3238 char_u *tp; | 3238 char_u *tp; |
3239 char_u key[AH_KEY_LEN]; | 3239 char_u key[AH_KEY_LEN]; |
3240 hashitem_T *hi; | 3240 hashitem_T *hi; |
3241 | 3241 |
3242 /* Make room for the old and the new compflags, concatenated with a / in | 3242 // Make room for the old and the new compflags, concatenated with a / in |
3243 * between. Processing it makes it shorter, but we don't know by how | 3243 // between. Processing it makes it shorter, but we don't know by how |
3244 * much, thus allocate the maximum. */ | 3244 // much, thus allocate the maximum. |
3245 len = (int)STRLEN(compflags) + 1; | 3245 len = (int)STRLEN(compflags) + 1; |
3246 if (spin->si_compflags != NULL) | 3246 if (spin->si_compflags != NULL) |
3247 len += (int)STRLEN(spin->si_compflags) + 1; | 3247 len += (int)STRLEN(spin->si_compflags) + 1; |
3248 p = getroom(spin, len, FALSE); | 3248 p = getroom(spin, len, FALSE); |
3249 if (p == NULL) | 3249 if (p == NULL) |
3257 tp = p + STRLEN(p); | 3257 tp = p + STRLEN(p); |
3258 | 3258 |
3259 for (p = compflags; *p != NUL; ) | 3259 for (p = compflags; *p != NUL; ) |
3260 { | 3260 { |
3261 if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) | 3261 if (vim_strchr((char_u *)"/?*+[]", *p) != NULL) |
3262 /* Copy non-flag characters directly. */ | 3262 // Copy non-flag characters directly. |
3263 *tp++ = *p++; | 3263 *tp++ = *p++; |
3264 else | 3264 else |
3265 { | 3265 { |
3266 /* First get the flag number, also checks validity. */ | 3266 // First get the flag number, also checks validity. |
3267 prevp = p; | 3267 prevp = p; |
3268 flag = get_affitem(aff->af_flagtype, &p); | 3268 flag = get_affitem(aff->af_flagtype, &p); |
3269 if (flag != 0) | 3269 if (flag != 0) |
3270 { | 3270 { |
3271 /* Find the flag in the hashtable. If it was used before, use | 3271 // Find the flag in the hashtable. If it was used before, use |
3272 * the existing ID. Otherwise add a new entry. */ | 3272 // the existing ID. Otherwise add a new entry. |
3273 vim_strncpy(key, prevp, p - prevp); | 3273 vim_strncpy(key, prevp, p - prevp); |
3274 hi = hash_find(&aff->af_comp, key); | 3274 hi = hash_find(&aff->af_comp, key); |
3275 if (!HASHITEM_EMPTY(hi)) | 3275 if (!HASHITEM_EMPTY(hi)) |
3276 id = HI2CI(hi)->ci_newID; | 3276 id = HI2CI(hi)->ci_newID; |
3277 else | 3277 else |
3279 ci = (compitem_T *)getroom(spin, sizeof(compitem_T), TRUE); | 3279 ci = (compitem_T *)getroom(spin, sizeof(compitem_T), TRUE); |
3280 if (ci == NULL) | 3280 if (ci == NULL) |
3281 break; | 3281 break; |
3282 STRCPY(ci->ci_key, key); | 3282 STRCPY(ci->ci_key, key); |
3283 ci->ci_flag = flag; | 3283 ci->ci_flag = flag; |
3284 /* Avoid using a flag ID that has a special meaning in a | 3284 // Avoid using a flag ID that has a special meaning in a |
3285 * regexp (also inside []). */ | 3285 // regexp (also inside []). |
3286 do | 3286 do |
3287 { | 3287 { |
3288 check_renumber(spin); | 3288 check_renumber(spin); |
3289 id = spin->si_newcompID--; | 3289 id = spin->si_newcompID--; |
3290 } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL); | 3290 } while (vim_strchr((char_u *)"/?*+[]\\-^", id) != NULL); |
3350 n = getdigits(&p); | 3350 n = getdigits(&p); |
3351 if (n == 0) | 3351 if (n == 0) |
3352 n = ZERO_FLAG; | 3352 n = ZERO_FLAG; |
3353 if (n == flag) | 3353 if (n == flag) |
3354 return TRUE; | 3354 return TRUE; |
3355 if (*p != NUL) /* skip over comma */ | 3355 if (*p != NUL) // skip over comma |
3356 ++p; | 3356 ++p; |
3357 } | 3357 } |
3358 break; | 3358 break; |
3359 } | 3359 } |
3360 return FALSE; | 3360 return FALSE; |
3438 affheader_T *ah; | 3438 affheader_T *ah; |
3439 affentry_T *ae; | 3439 affentry_T *ae; |
3440 | 3440 |
3441 vim_free(aff->af_enc); | 3441 vim_free(aff->af_enc); |
3442 | 3442 |
3443 /* All this trouble to free the "ae_prog" items... */ | 3443 // All this trouble to free the "ae_prog" items... |
3444 for (ht = &aff->af_pref; ; ht = &aff->af_suff) | 3444 for (ht = &aff->af_pref; ; ht = &aff->af_suff) |
3445 { | 3445 { |
3446 todo = (int)ht->ht_used; | 3446 todo = (int)ht->ht_used; |
3447 for (hi = ht->ht_array; todo > 0; ++hi) | 3447 for (hi = ht->ht_array; todo > 0; ++hi) |
3448 { | 3448 { |
3499 { | 3499 { |
3500 semsg(_(e_notopen), fname); | 3500 semsg(_(e_notopen), fname); |
3501 return FAIL; | 3501 return FAIL; |
3502 } | 3502 } |
3503 | 3503 |
3504 /* The hashtable is only used to detect duplicated words. */ | 3504 // The hashtable is only used to detect duplicated words. |
3505 hash_init(&ht); | 3505 hash_init(&ht); |
3506 | 3506 |
3507 vim_snprintf((char *)IObuff, IOSIZE, | 3507 vim_snprintf((char *)IObuff, IOSIZE, |
3508 _("Reading dictionary file %s..."), fname); | 3508 _("Reading dictionary file %s..."), fname); |
3509 spell_message(spin, IObuff); | 3509 spell_message(spin, IObuff); |
3510 | 3510 |
3511 /* start with a message for the first line */ | 3511 // start with a message for the first line |
3512 spin->si_msg_count = 999999; | 3512 spin->si_msg_count = 999999; |
3513 | 3513 |
3514 /* Read and ignore the first line: word count. */ | 3514 // Read and ignore the first line: word count. |
3515 (void)vim_fgets(line, MAXLINELEN, fd); | 3515 (void)vim_fgets(line, MAXLINELEN, fd); |
3516 if (!vim_isdigit(*skipwhite(line))) | 3516 if (!vim_isdigit(*skipwhite(line))) |
3517 semsg(_("E760: No word count in %s"), fname); | 3517 semsg(_("E760: No word count in %s"), fname); |
3518 | 3518 |
3519 /* | 3519 /* |
3524 while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) | 3524 while (!vim_fgets(line, MAXLINELEN, fd) && !got_int) |
3525 { | 3525 { |
3526 line_breakcheck(); | 3526 line_breakcheck(); |
3527 ++lnum; | 3527 ++lnum; |
3528 if (line[0] == '#' || line[0] == '/') | 3528 if (line[0] == '#' || line[0] == '/') |
3529 continue; /* comment line */ | 3529 continue; // comment line |
3530 | 3530 |
3531 /* Remove CR, LF and white space from the end. White space halfway | 3531 // Remove CR, LF and white space from the end. White space halfway |
3532 * the word is kept to allow e.g., "et al.". */ | 3532 // the word is kept to allow e.g., "et al.". |
3533 l = (int)STRLEN(line); | 3533 l = (int)STRLEN(line); |
3534 while (l > 0 && line[l - 1] <= ' ') | 3534 while (l > 0 && line[l - 1] <= ' ') |
3535 --l; | 3535 --l; |
3536 if (l == 0) | 3536 if (l == 0) |
3537 continue; /* empty line */ | 3537 continue; // empty line |
3538 line[l] = NUL; | 3538 line[l] = NUL; |
3539 | 3539 |
3540 /* Convert from "SET" to 'encoding' when needed. */ | 3540 // Convert from "SET" to 'encoding' when needed. |
3541 if (spin->si_conv.vc_type != CONV_NONE) | 3541 if (spin->si_conv.vc_type != CONV_NONE) |
3542 { | 3542 { |
3543 pc = string_convert(&spin->si_conv, line, NULL); | 3543 pc = string_convert(&spin->si_conv, line, NULL); |
3544 if (pc == NULL) | 3544 if (pc == NULL) |
3545 { | 3545 { |
3553 { | 3553 { |
3554 pc = NULL; | 3554 pc = NULL; |
3555 w = line; | 3555 w = line; |
3556 } | 3556 } |
3557 | 3557 |
3558 /* Truncate the word at the "/", set "afflist" to what follows. | 3558 // Truncate the word at the "/", set "afflist" to what follows. |
3559 * Replace "\/" by "/" and "\\" by "\". */ | 3559 // Replace "\/" by "/" and "\\" by "\". |
3560 afflist = NULL; | 3560 afflist = NULL; |
3561 for (p = w; *p != NUL; MB_PTR_ADV(p)) | 3561 for (p = w; *p != NUL; MB_PTR_ADV(p)) |
3562 { | 3562 { |
3563 if (*p == '\\' && (p[1] == '\\' || p[1] == '/')) | 3563 if (*p == '\\' && (p[1] == '\\' || p[1] == '/')) |
3564 STRMOVE(p, p + 1); | 3564 STRMOVE(p, p + 1); |
3568 afflist = p + 1; | 3568 afflist = p + 1; |
3569 break; | 3569 break; |
3570 } | 3570 } |
3571 } | 3571 } |
3572 | 3572 |
3573 /* Skip non-ASCII words when "spin->si_ascii" is TRUE. */ | 3573 // Skip non-ASCII words when "spin->si_ascii" is TRUE. |
3574 if (spin->si_ascii && has_non_ascii(w)) | 3574 if (spin->si_ascii && has_non_ascii(w)) |
3575 { | 3575 { |
3576 ++non_ascii; | 3576 ++non_ascii; |
3577 vim_free(pc); | 3577 vim_free(pc); |
3578 continue; | 3578 continue; |
3579 } | 3579 } |
3580 | 3580 |
3581 /* This takes time, print a message every 10000 words. */ | 3581 // This takes time, print a message every 10000 words. |
3582 if (spin->si_verbose && spin->si_msg_count > 10000) | 3582 if (spin->si_verbose && spin->si_msg_count > 10000) |
3583 { | 3583 { |
3584 spin->si_msg_count = 0; | 3584 spin->si_msg_count = 0; |
3585 vim_snprintf((char *)message, sizeof(message), | 3585 vim_snprintf((char *)message, sizeof(message), |
3586 _("line %6d, word %6ld - %s"), | 3586 _("line %6d, word %6ld - %s"), |
3591 msg_didout = FALSE; | 3591 msg_didout = FALSE; |
3592 msg_col = 0; | 3592 msg_col = 0; |
3593 out_flush(); | 3593 out_flush(); |
3594 } | 3594 } |
3595 | 3595 |
3596 /* Store the word in the hashtable to be able to find duplicates. */ | 3596 // Store the word in the hashtable to be able to find duplicates. |
3597 dw = (char_u *)getroom_save(spin, w); | 3597 dw = (char_u *)getroom_save(spin, w); |
3598 if (dw == NULL) | 3598 if (dw == NULL) |
3599 { | 3599 { |
3600 retval = FAIL; | 3600 retval = FAIL; |
3601 vim_free(pc); | 3601 vim_free(pc); |
3621 store_afflist[0] = NUL; | 3621 store_afflist[0] = NUL; |
3622 pfxlen = 0; | 3622 pfxlen = 0; |
3623 need_affix = FALSE; | 3623 need_affix = FALSE; |
3624 if (afflist != NULL) | 3624 if (afflist != NULL) |
3625 { | 3625 { |
3626 /* Extract flags from the affix list. */ | 3626 // Extract flags from the affix list. |
3627 flags |= get_affix_flags(affile, afflist); | 3627 flags |= get_affix_flags(affile, afflist); |
3628 | 3628 |
3629 if (affile->af_needaffix != 0 && flag_in_afflist( | 3629 if (affile->af_needaffix != 0 && flag_in_afflist( |
3630 affile->af_flagtype, afflist, affile->af_needaffix)) | 3630 affile->af_flagtype, afflist, affile->af_needaffix)) |
3631 need_affix = TRUE; | 3631 need_affix = TRUE; |
3632 | 3632 |
3633 if (affile->af_pfxpostpone) | 3633 if (affile->af_pfxpostpone) |
3634 /* Need to store the list of prefix IDs with the word. */ | 3634 // Need to store the list of prefix IDs with the word. |
3635 pfxlen = get_pfxlist(affile, afflist, store_afflist); | 3635 pfxlen = get_pfxlist(affile, afflist, store_afflist); |
3636 | 3636 |
3637 if (spin->si_compflags != NULL) | 3637 if (spin->si_compflags != NULL) |
3638 /* Need to store the list of compound flags with the word. | 3638 // Need to store the list of compound flags with the word. |
3639 * Concatenate them to the list of prefix IDs. */ | 3639 // Concatenate them to the list of prefix IDs. |
3640 get_compflags(affile, afflist, store_afflist + pfxlen); | 3640 get_compflags(affile, afflist, store_afflist + pfxlen); |
3641 } | 3641 } |
3642 | 3642 |
3643 /* Add the word to the word tree(s). */ | 3643 // Add the word to the word tree(s). |
3644 if (store_word(spin, dw, flags, spin->si_region, | 3644 if (store_word(spin, dw, flags, spin->si_region, |
3645 store_afflist, need_affix) == FAIL) | 3645 store_afflist, need_affix) == FAIL) |
3646 retval = FAIL; | 3646 retval = FAIL; |
3647 | 3647 |
3648 if (afflist != NULL) | 3648 if (afflist != NULL) |
3649 { | 3649 { |
3650 /* Find all matching suffixes and add the resulting words. | 3650 // Find all matching suffixes and add the resulting words. |
3651 * Additionally do matching prefixes that combine. */ | 3651 // Additionally do matching prefixes that combine. |
3652 if (store_aff_word(spin, dw, afflist, affile, | 3652 if (store_aff_word(spin, dw, afflist, affile, |
3653 &affile->af_suff, &affile->af_pref, | 3653 &affile->af_suff, &affile->af_pref, |
3654 CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) | 3654 CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) |
3655 retval = FAIL; | 3655 retval = FAIL; |
3656 | 3656 |
3657 /* Find all matching prefixes and add the resulting words. */ | 3657 // Find all matching prefixes and add the resulting words. |
3658 if (store_aff_word(spin, dw, afflist, affile, | 3658 if (store_aff_word(spin, dw, afflist, affile, |
3659 &affile->af_pref, NULL, | 3659 &affile->af_pref, NULL, |
3660 CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) | 3660 CONDIT_SUF, flags, store_afflist, pfxlen) == FAIL) |
3661 retval = FAIL; | 3661 retval = FAIL; |
3662 } | 3662 } |
3727 for (p = afflist; *p != NUL; ) | 3727 for (p = afflist; *p != NUL; ) |
3728 { | 3728 { |
3729 prevp = p; | 3729 prevp = p; |
3730 if (get_affitem(affile->af_flagtype, &p) != 0) | 3730 if (get_affitem(affile->af_flagtype, &p) != 0) |
3731 { | 3731 { |
3732 /* A flag is a postponed prefix flag if it appears in "af_pref" | 3732 // A flag is a postponed prefix flag if it appears in "af_pref" |
3733 * and its ID is not zero. */ | 3733 // and its ID is not zero. |
3734 vim_strncpy(key, prevp, p - prevp); | 3734 vim_strncpy(key, prevp, p - prevp); |
3735 hi = hash_find(&affile->af_pref, key); | 3735 hi = hash_find(&affile->af_pref, key); |
3736 if (!HASHITEM_EMPTY(hi)) | 3736 if (!HASHITEM_EMPTY(hi)) |
3737 { | 3737 { |
3738 id = HI2AH(hi)->ah_newID; | 3738 id = HI2AH(hi)->ah_newID; |
3768 for (p = afflist; *p != NUL; ) | 3768 for (p = afflist; *p != NUL; ) |
3769 { | 3769 { |
3770 prevp = p; | 3770 prevp = p; |
3771 if (get_affitem(affile->af_flagtype, &p) != 0) | 3771 if (get_affitem(affile->af_flagtype, &p) != 0) |
3772 { | 3772 { |
3773 /* A flag is a compound flag if it appears in "af_comp". */ | 3773 // A flag is a compound flag if it appears in "af_comp". |
3774 vim_strncpy(key, prevp, p - prevp); | 3774 vim_strncpy(key, prevp, p - prevp); |
3775 hi = hash_find(&affile->af_comp, key); | 3775 hi = hash_find(&affile->af_comp, key); |
3776 if (!HASHITEM_EMPTY(hi)) | 3776 if (!HASHITEM_EMPTY(hi)) |
3777 store_afflist[cnt++] = HI2CI(hi)->ci_newID; | 3777 store_afflist[cnt++] = HI2CI(hi)->ci_newID; |
3778 } | 3778 } |
3792 * | 3792 * |
3793 * Returns FAIL when out of memory. | 3793 * Returns FAIL when out of memory. |
3794 */ | 3794 */ |
3795 static int | 3795 static int |
3796 store_aff_word( | 3796 store_aff_word( |
3797 spellinfo_T *spin, /* spell info */ | 3797 spellinfo_T *spin, // spell info |
3798 char_u *word, /* basic word start */ | 3798 char_u *word, // basic word start |
3799 char_u *afflist, /* list of names of supported affixes */ | 3799 char_u *afflist, // list of names of supported affixes |
3800 afffile_T *affile, | 3800 afffile_T *affile, |
3801 hashtab_T *ht, | 3801 hashtab_T *ht, |
3802 hashtab_T *xht, | 3802 hashtab_T *xht, |
3803 int condit, /* CONDIT_SUF et al. */ | 3803 int condit, // CONDIT_SUF et al. |
3804 int flags, /* flags for the word */ | 3804 int flags, // flags for the word |
3805 char_u *pfxlist, /* list of prefix IDs */ | 3805 char_u *pfxlist, // list of prefix IDs |
3806 int pfxlen) /* nr of flags in "pfxlist" for prefixes, rest | 3806 int pfxlen) // nr of flags in "pfxlist" for prefixes, rest |
3807 * is compound flags */ | 3807 // is compound flags |
3808 { | 3808 { |
3809 int todo; | 3809 int todo; |
3810 hashitem_T *hi; | 3810 hashitem_T *hi; |
3811 affheader_T *ah; | 3811 affheader_T *ah; |
3812 affentry_T *ae; | 3812 affentry_T *ae; |
3829 if (!HASHITEM_EMPTY(hi)) | 3829 if (!HASHITEM_EMPTY(hi)) |
3830 { | 3830 { |
3831 --todo; | 3831 --todo; |
3832 ah = HI2AH(hi); | 3832 ah = HI2AH(hi); |
3833 | 3833 |
3834 /* Check that the affix combines, if required, and that the word | 3834 // Check that the affix combines, if required, and that the word |
3835 * supports this affix. */ | 3835 // supports this affix. |
3836 if (((condit & CONDIT_COMB) == 0 || ah->ah_combine) | 3836 if (((condit & CONDIT_COMB) == 0 || ah->ah_combine) |
3837 && flag_in_afflist(affile->af_flagtype, afflist, | 3837 && flag_in_afflist(affile->af_flagtype, afflist, |
3838 ah->ah_flag)) | 3838 ah->ah_flag)) |
3839 { | 3839 { |
3840 /* Loop over all affix entries with this name. */ | 3840 // Loop over all affix entries with this name. |
3841 for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) | 3841 for (ae = ah->ah_first; ae != NULL; ae = ae->ae_next) |
3842 { | 3842 { |
3843 /* Check the condition. It's not logical to match case | 3843 // Check the condition. It's not logical to match case |
3844 * here, but it is required for compatibility with | 3844 // here, but it is required for compatibility with |
3845 * Myspell. | 3845 // Myspell. |
3846 * Another requirement from Myspell is that the chop | 3846 // Another requirement from Myspell is that the chop |
3847 * string is shorter than the word itself. | 3847 // string is shorter than the word itself. |
3848 * For prefixes, when "PFXPOSTPONE" was used, only do | 3848 // For prefixes, when "PFXPOSTPONE" was used, only do |
3849 * prefixes with a chop string and/or flags. | 3849 // prefixes with a chop string and/or flags. |
3850 * When a previously added affix had CIRCUMFIX this one | 3850 // When a previously added affix had CIRCUMFIX this one |
3851 * must have it too, if it had not then this one must not | 3851 // must have it too, if it had not then this one must not |
3852 * have one either. */ | 3852 // have one either. |
3853 if ((xht != NULL || !affile->af_pfxpostpone | 3853 if ((xht != NULL || !affile->af_pfxpostpone |
3854 || ae->ae_chop != NULL | 3854 || ae->ae_chop != NULL |
3855 || ae->ae_flags != NULL) | 3855 || ae->ae_flags != NULL) |
3856 && (ae->ae_chop == NULL | 3856 && (ae->ae_chop == NULL |
3857 || STRLEN(ae->ae_chop) < wordlen) | 3857 || STRLEN(ae->ae_chop) < wordlen) |
3862 == ((condit & CONDIT_AFF) == 0 | 3862 == ((condit & CONDIT_AFF) == 0 |
3863 || ae->ae_flags == NULL | 3863 || ae->ae_flags == NULL |
3864 || !flag_in_afflist(affile->af_flagtype, | 3864 || !flag_in_afflist(affile->af_flagtype, |
3865 ae->ae_flags, affile->af_circumfix)))) | 3865 ae->ae_flags, affile->af_circumfix)))) |
3866 { | 3866 { |
3867 /* Match. Remove the chop and add the affix. */ | 3867 // Match. Remove the chop and add the affix. |
3868 if (xht == NULL) | 3868 if (xht == NULL) |
3869 { | 3869 { |
3870 /* prefix: chop/add at the start of the word */ | 3870 // prefix: chop/add at the start of the word |
3871 if (ae->ae_add == NULL) | 3871 if (ae->ae_add == NULL) |
3872 *newword = NUL; | 3872 *newword = NUL; |
3873 else | 3873 else |
3874 vim_strncpy(newword, ae->ae_add, MAXWLEN - 1); | 3874 vim_strncpy(newword, ae->ae_add, MAXWLEN - 1); |
3875 p = word; | 3875 p = word; |
3876 if (ae->ae_chop != NULL) | 3876 if (ae->ae_chop != NULL) |
3877 { | 3877 { |
3878 /* Skip chop string. */ | 3878 // Skip chop string. |
3879 if (has_mbyte) | 3879 if (has_mbyte) |
3880 { | 3880 { |
3881 i = mb_charlen(ae->ae_chop); | 3881 i = mb_charlen(ae->ae_chop); |
3882 for ( ; i > 0; --i) | 3882 for ( ; i > 0; --i) |
3883 MB_PTR_ADV(p); | 3883 MB_PTR_ADV(p); |
3887 } | 3887 } |
3888 STRCAT(newword, p); | 3888 STRCAT(newword, p); |
3889 } | 3889 } |
3890 else | 3890 else |
3891 { | 3891 { |
3892 /* suffix: chop/add at the end of the word */ | 3892 // suffix: chop/add at the end of the word |
3893 vim_strncpy(newword, word, MAXWLEN - 1); | 3893 vim_strncpy(newword, word, MAXWLEN - 1); |
3894 if (ae->ae_chop != NULL) | 3894 if (ae->ae_chop != NULL) |
3895 { | 3895 { |
3896 /* Remove chop string. */ | 3896 // Remove chop string. |
3897 p = newword + STRLEN(newword); | 3897 p = newword + STRLEN(newword); |
3898 i = (int)MB_CHARLEN(ae->ae_chop); | 3898 i = (int)MB_CHARLEN(ae->ae_chop); |
3899 for ( ; i > 0; --i) | 3899 for ( ; i > 0; --i) |
3900 MB_PTR_BACK(newword, p); | 3900 MB_PTR_BACK(newword, p); |
3901 *p = NUL; | 3901 *p = NUL; |
3909 use_pfxlen = pfxlen; | 3909 use_pfxlen = pfxlen; |
3910 need_affix = FALSE; | 3910 need_affix = FALSE; |
3911 use_condit = condit | CONDIT_COMB | CONDIT_AFF; | 3911 use_condit = condit | CONDIT_COMB | CONDIT_AFF; |
3912 if (ae->ae_flags != NULL) | 3912 if (ae->ae_flags != NULL) |
3913 { | 3913 { |
3914 /* Extract flags from the affix list. */ | 3914 // Extract flags from the affix list. |
3915 use_flags |= get_affix_flags(affile, ae->ae_flags); | 3915 use_flags |= get_affix_flags(affile, ae->ae_flags); |
3916 | 3916 |
3917 if (affile->af_needaffix != 0 && flag_in_afflist( | 3917 if (affile->af_needaffix != 0 && flag_in_afflist( |
3918 affile->af_flagtype, ae->ae_flags, | 3918 affile->af_flagtype, ae->ae_flags, |
3919 affile->af_needaffix)) | 3919 affile->af_needaffix)) |
3920 need_affix = TRUE; | 3920 need_affix = TRUE; |
3921 | 3921 |
3922 /* When there is a CIRCUMFIX flag the other affix | 3922 // When there is a CIRCUMFIX flag the other affix |
3923 * must also have it and we don't add the word | 3923 // must also have it and we don't add the word |
3924 * with one affix. */ | 3924 // with one affix. |
3925 if (affile->af_circumfix != 0 && flag_in_afflist( | 3925 if (affile->af_circumfix != 0 && flag_in_afflist( |
3926 affile->af_flagtype, ae->ae_flags, | 3926 affile->af_flagtype, ae->ae_flags, |
3927 affile->af_circumfix)) | 3927 affile->af_circumfix)) |
3928 { | 3928 { |
3929 use_condit |= CONDIT_CFIX; | 3929 use_condit |= CONDIT_CFIX; |
3933 | 3933 |
3934 if (affile->af_pfxpostpone | 3934 if (affile->af_pfxpostpone |
3935 || spin->si_compflags != NULL) | 3935 || spin->si_compflags != NULL) |
3936 { | 3936 { |
3937 if (affile->af_pfxpostpone) | 3937 if (affile->af_pfxpostpone) |
3938 /* Get prefix IDS from the affix list. */ | 3938 // Get prefix IDS from the affix list. |
3939 use_pfxlen = get_pfxlist(affile, | 3939 use_pfxlen = get_pfxlist(affile, |
3940 ae->ae_flags, store_afflist); | 3940 ae->ae_flags, store_afflist); |
3941 else | 3941 else |
3942 use_pfxlen = 0; | 3942 use_pfxlen = 0; |
3943 use_pfxlist = store_afflist; | 3943 use_pfxlist = store_afflist; |
3944 | 3944 |
3945 /* Combine the prefix IDs. Avoid adding the | 3945 // Combine the prefix IDs. Avoid adding the |
3946 * same ID twice. */ | 3946 // same ID twice. |
3947 for (i = 0; i < pfxlen; ++i) | 3947 for (i = 0; i < pfxlen; ++i) |
3948 { | 3948 { |
3949 for (j = 0; j < use_pfxlen; ++j) | 3949 for (j = 0; j < use_pfxlen; ++j) |
3950 if (pfxlist[i] == use_pfxlist[j]) | 3950 if (pfxlist[i] == use_pfxlist[j]) |
3951 break; | 3951 break; |
3952 if (j == use_pfxlen) | 3952 if (j == use_pfxlen) |
3953 use_pfxlist[use_pfxlen++] = pfxlist[i]; | 3953 use_pfxlist[use_pfxlen++] = pfxlist[i]; |
3954 } | 3954 } |
3955 | 3955 |
3956 if (spin->si_compflags != NULL) | 3956 if (spin->si_compflags != NULL) |
3957 /* Get compound IDS from the affix list. */ | 3957 // Get compound IDS from the affix list. |
3958 get_compflags(affile, ae->ae_flags, | 3958 get_compflags(affile, ae->ae_flags, |
3959 use_pfxlist + use_pfxlen); | 3959 use_pfxlist + use_pfxlen); |
3960 | 3960 |
3961 /* Combine the list of compound flags. | 3961 // Combine the list of compound flags. |
3962 * Concatenate them to the prefix IDs list. | 3962 // Concatenate them to the prefix IDs list. |
3963 * Avoid adding the same ID twice. */ | 3963 // Avoid adding the same ID twice. |
3964 for (i = pfxlen; pfxlist[i] != NUL; ++i) | 3964 for (i = pfxlen; pfxlist[i] != NUL; ++i) |
3965 { | 3965 { |
3966 for (j = use_pfxlen; | 3966 for (j = use_pfxlen; |
3967 use_pfxlist[j] != NUL; ++j) | 3967 use_pfxlist[j] != NUL; ++j) |
3968 if (pfxlist[i] == use_pfxlist[j]) | 3968 if (pfxlist[i] == use_pfxlist[j]) |
3974 } | 3974 } |
3975 } | 3975 } |
3976 } | 3976 } |
3977 } | 3977 } |
3978 | 3978 |
3979 /* Obey a "COMPOUNDFORBIDFLAG" of the affix: don't | 3979 // Obey a "COMPOUNDFORBIDFLAG" of the affix: don't |
3980 * use the compound flags. */ | 3980 // use the compound flags. |
3981 if (use_pfxlist != NULL && ae->ae_compforbid) | 3981 if (use_pfxlist != NULL && ae->ae_compforbid) |
3982 { | 3982 { |
3983 vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen); | 3983 vim_strncpy(pfx_pfxlist, use_pfxlist, use_pfxlen); |
3984 use_pfxlist = pfx_pfxlist; | 3984 use_pfxlist = pfx_pfxlist; |
3985 } | 3985 } |
3986 | 3986 |
3987 /* When there are postponed prefixes... */ | 3987 // When there are postponed prefixes... |
3988 if (spin->si_prefroot != NULL | 3988 if (spin->si_prefroot != NULL |
3989 && spin->si_prefroot->wn_sibling != NULL) | 3989 && spin->si_prefroot->wn_sibling != NULL) |
3990 { | 3990 { |
3991 /* ... add a flag to indicate an affix was used. */ | 3991 // ... add a flag to indicate an affix was used. |
3992 use_flags |= WF_HAS_AFF; | 3992 use_flags |= WF_HAS_AFF; |
3993 | 3993 |
3994 /* ... don't use a prefix list if combining | 3994 // ... don't use a prefix list if combining |
3995 * affixes is not allowed. But do use the | 3995 // affixes is not allowed. But do use the |
3996 * compound flags after them. */ | 3996 // compound flags after them. |
3997 if (!ah->ah_combine && use_pfxlist != NULL) | 3997 if (!ah->ah_combine && use_pfxlist != NULL) |
3998 use_pfxlist += use_pfxlen; | 3998 use_pfxlist += use_pfxlen; |
3999 } | 3999 } |
4000 | 4000 |
4001 /* When compounding is supported and there is no | 4001 // When compounding is supported and there is no |
4002 * "COMPOUNDPERMITFLAG" then forbid compounding on the | 4002 // "COMPOUNDPERMITFLAG" then forbid compounding on the |
4003 * side where the affix is applied. */ | 4003 // side where the affix is applied. |
4004 if (spin->si_compflags != NULL && !ae->ae_comppermit) | 4004 if (spin->si_compflags != NULL && !ae->ae_comppermit) |
4005 { | 4005 { |
4006 if (xht != NULL) | 4006 if (xht != NULL) |
4007 use_flags |= WF_NOCOMPAFT; | 4007 use_flags |= WF_NOCOMPAFT; |
4008 else | 4008 else |
4009 use_flags |= WF_NOCOMPBEF; | 4009 use_flags |= WF_NOCOMPBEF; |
4010 } | 4010 } |
4011 | 4011 |
4012 /* Store the modified word. */ | 4012 // Store the modified word. |
4013 if (store_word(spin, newword, use_flags, | 4013 if (store_word(spin, newword, use_flags, |
4014 spin->si_region, use_pfxlist, | 4014 spin->si_region, use_pfxlist, |
4015 need_affix) == FAIL) | 4015 need_affix) == FAIL) |
4016 retval = FAIL; | 4016 retval = FAIL; |
4017 | 4017 |
4018 /* When added a prefix or a first suffix and the affix | 4018 // When added a prefix or a first suffix and the affix |
4019 * has flags may add a(nother) suffix. RECURSIVE! */ | 4019 // has flags may add a(nother) suffix. RECURSIVE! |
4020 if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) | 4020 if ((condit & CONDIT_SUF) && ae->ae_flags != NULL) |
4021 if (store_aff_word(spin, newword, ae->ae_flags, | 4021 if (store_aff_word(spin, newword, ae->ae_flags, |
4022 affile, &affile->af_suff, xht, | 4022 affile, &affile->af_suff, xht, |
4023 use_condit & (xht == NULL | 4023 use_condit & (xht == NULL |
4024 ? ~0 : ~CONDIT_SUF), | 4024 ? ~0 : ~CONDIT_SUF), |
4025 use_flags, use_pfxlist, pfxlen) == FAIL) | 4025 use_flags, use_pfxlist, pfxlen) == FAIL) |
4026 retval = FAIL; | 4026 retval = FAIL; |
4027 | 4027 |
4028 /* When added a suffix and combining is allowed also | 4028 // When added a suffix and combining is allowed also |
4029 * try adding a prefix additionally. Both for the | 4029 // try adding a prefix additionally. Both for the |
4030 * word flags and for the affix flags. RECURSIVE! */ | 4030 // word flags and for the affix flags. RECURSIVE! |
4031 if (xht != NULL && ah->ah_combine) | 4031 if (xht != NULL && ah->ah_combine) |
4032 { | 4032 { |
4033 if (store_aff_word(spin, newword, | 4033 if (store_aff_word(spin, newword, |
4034 afflist, affile, | 4034 afflist, affile, |
4035 xht, NULL, use_condit, | 4035 xht, NULL, use_condit, |
4090 while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) | 4090 while (!vim_fgets(rline, MAXLINELEN, fd) && !got_int) |
4091 { | 4091 { |
4092 line_breakcheck(); | 4092 line_breakcheck(); |
4093 ++lnum; | 4093 ++lnum; |
4094 | 4094 |
4095 /* Skip comment lines. */ | 4095 // Skip comment lines. |
4096 if (*rline == '#') | 4096 if (*rline == '#') |
4097 continue; | 4097 continue; |
4098 | 4098 |
4099 /* Remove CR, LF and white space from the end. */ | 4099 // Remove CR, LF and white space from the end. |
4100 l = (int)STRLEN(rline); | 4100 l = (int)STRLEN(rline); |
4101 while (l > 0 && rline[l - 1] <= ' ') | 4101 while (l > 0 && rline[l - 1] <= ' ') |
4102 --l; | 4102 --l; |
4103 if (l == 0) | 4103 if (l == 0) |
4104 continue; /* empty or blank line */ | 4104 continue; // empty or blank line |
4105 rline[l] = NUL; | 4105 rline[l] = NUL; |
4106 | 4106 |
4107 /* Convert from "/encoding={encoding}" to 'encoding' when needed. */ | 4107 // Convert from "/encoding={encoding}" to 'encoding' when needed. |
4108 vim_free(pc); | 4108 vim_free(pc); |
4109 if (spin->si_conv.vc_type != CONV_NONE) | 4109 if (spin->si_conv.vc_type != CONV_NONE) |
4110 { | 4110 { |
4111 pc = string_convert(&spin->si_conv, rline, NULL); | 4111 pc = string_convert(&spin->si_conv, rline, NULL); |
4112 if (pc == NULL) | 4112 if (pc == NULL) |
4136 fname, lnum, line - 1); | 4136 fname, lnum, line - 1); |
4137 else | 4137 else |
4138 { | 4138 { |
4139 char_u *enc; | 4139 char_u *enc; |
4140 | 4140 |
4141 /* Setup for conversion to 'encoding'. */ | 4141 // Setup for conversion to 'encoding'. |
4142 line += 9; | 4142 line += 9; |
4143 enc = enc_canonize(line); | 4143 enc = enc_canonize(line); |
4144 if (enc != NULL && !spin->si_ascii | 4144 if (enc != NULL && !spin->si_ascii |
4145 && convert_setup(&spin->si_conv, enc, | 4145 && convert_setup(&spin->si_conv, enc, |
4146 p_enc) == FAIL) | 4146 p_enc) == FAIL) |
4166 else | 4166 else |
4167 { | 4167 { |
4168 spin->si_region_count = (int)STRLEN(line) / 2; | 4168 spin->si_region_count = (int)STRLEN(line) / 2; |
4169 STRCPY(spin->si_region_name, line); | 4169 STRCPY(spin->si_region_name, line); |
4170 | 4170 |
4171 /* Adjust the mask for a word valid in all regions. */ | 4171 // Adjust the mask for a word valid in all regions. |
4172 spin->si_region = (1 << spin->si_region_count) - 1; | 4172 spin->si_region = (1 << spin->si_region_count) - 1; |
4173 } | 4173 } |
4174 } | 4174 } |
4175 continue; | 4175 continue; |
4176 } | 4176 } |
4181 } | 4181 } |
4182 | 4182 |
4183 flags = 0; | 4183 flags = 0; |
4184 regionmask = spin->si_region; | 4184 regionmask = spin->si_region; |
4185 | 4185 |
4186 /* Check for flags and region after a slash. */ | 4186 // Check for flags and region after a slash. |
4187 p = vim_strchr(line, '/'); | 4187 p = vim_strchr(line, '/'); |
4188 if (p != NULL) | 4188 if (p != NULL) |
4189 { | 4189 { |
4190 *p++ = NUL; | 4190 *p++ = NUL; |
4191 while (*p != NUL) | 4191 while (*p != NUL) |
4192 { | 4192 { |
4193 if (*p == '=') /* keep-case word */ | 4193 if (*p == '=') // keep-case word |
4194 flags |= WF_KEEPCAP | WF_FIXCAP; | 4194 flags |= WF_KEEPCAP | WF_FIXCAP; |
4195 else if (*p == '!') /* Bad, bad, wicked word. */ | 4195 else if (*p == '!') // Bad, bad, wicked word. |
4196 flags |= WF_BANNED; | 4196 flags |= WF_BANNED; |
4197 else if (*p == '?') /* Rare word. */ | 4197 else if (*p == '?') // Rare word. |
4198 flags |= WF_RARE; | 4198 flags |= WF_RARE; |
4199 else if (VIM_ISDIGIT(*p)) /* region number(s) */ | 4199 else if (VIM_ISDIGIT(*p)) // region number(s) |
4200 { | 4200 { |
4201 if ((flags & WF_REGION) == 0) /* first one */ | 4201 if ((flags & WF_REGION) == 0) // first one |
4202 regionmask = 0; | 4202 regionmask = 0; |
4203 flags |= WF_REGION; | 4203 flags |= WF_REGION; |
4204 | 4204 |
4205 l = *p - '0'; | 4205 l = *p - '0'; |
4206 if (l == 0 || l > spin->si_region_count) | 4206 if (l == 0 || l > spin->si_region_count) |
4219 } | 4219 } |
4220 ++p; | 4220 ++p; |
4221 } | 4221 } |
4222 } | 4222 } |
4223 | 4223 |
4224 /* Skip non-ASCII words when "spin->si_ascii" is TRUE. */ | 4224 // Skip non-ASCII words when "spin->si_ascii" is TRUE. |
4225 if (spin->si_ascii && has_non_ascii(line)) | 4225 if (spin->si_ascii && has_non_ascii(line)) |
4226 { | 4226 { |
4227 ++non_ascii; | 4227 ++non_ascii; |
4228 continue; | 4228 continue; |
4229 } | 4229 } |
4230 | 4230 |
4231 /* Normal word: store it. */ | 4231 // Normal word: store it. |
4232 if (store_word(spin, line, flags, regionmask, NULL, FALSE) == FAIL) | 4232 if (store_word(spin, line, flags, regionmask, NULL, FALSE) == FAIL) |
4233 { | 4233 { |
4234 retval = FAIL; | 4234 retval = FAIL; |
4235 break; | 4235 break; |
4236 } | 4236 } |
4258 * Returns NULL when out of memory. | 4258 * Returns NULL when out of memory. |
4259 */ | 4259 */ |
4260 static void * | 4260 static void * |
4261 getroom( | 4261 getroom( |
4262 spellinfo_T *spin, | 4262 spellinfo_T *spin, |
4263 size_t len, /* length needed */ | 4263 size_t len, // length needed |
4264 int align) /* align for pointer */ | 4264 int align) // align for pointer |
4265 { | 4265 { |
4266 char_u *p; | 4266 char_u *p; |
4267 sblock_T *bl = spin->si_blocks; | 4267 sblock_T *bl = spin->si_blocks; |
4268 | 4268 |
4269 if (align && bl != NULL) | 4269 if (align && bl != NULL) |
4270 /* Round size up for alignment. On some systems structures need to be | 4270 // Round size up for alignment. On some systems structures need to be |
4271 * aligned to the size of a pointer (e.g., SPARC). */ | 4271 // aligned to the size of a pointer (e.g., SPARC). |
4272 bl->sb_used = (bl->sb_used + sizeof(char *) - 1) | 4272 bl->sb_used = (bl->sb_used + sizeof(char *) - 1) |
4273 & ~(sizeof(char *) - 1); | 4273 & ~(sizeof(char *) - 1); |
4274 | 4274 |
4275 if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) | 4275 if (bl == NULL || bl->sb_used + len > SBLOCKSIZE) |
4276 { | 4276 { |
4277 if (len >= SBLOCKSIZE) | 4277 if (len >= SBLOCKSIZE) |
4278 bl = NULL; | 4278 bl = NULL; |
4279 else | 4279 else |
4280 /* Allocate a block of memory. It is not freed until much later. */ | 4280 // Allocate a block of memory. It is not freed until much later. |
4281 bl = alloc_clear(sizeof(sblock_T) + SBLOCKSIZE); | 4281 bl = alloc_clear(sizeof(sblock_T) + SBLOCKSIZE); |
4282 if (bl == NULL) | 4282 if (bl == NULL) |
4283 { | 4283 { |
4284 if (!spin->si_did_emsg) | 4284 if (!spin->si_did_emsg) |
4285 { | 4285 { |
4353 */ | 4353 */ |
4354 static int | 4354 static int |
4355 store_word( | 4355 store_word( |
4356 spellinfo_T *spin, | 4356 spellinfo_T *spin, |
4357 char_u *word, | 4357 char_u *word, |
4358 int flags, /* extra flags, WF_BANNED */ | 4358 int flags, // extra flags, WF_BANNED |
4359 int region, /* supported region(s) */ | 4359 int region, // supported region(s) |
4360 char_u *pfxlist, /* list of prefix IDs or NULL */ | 4360 char_u *pfxlist, // list of prefix IDs or NULL |
4361 int need_affix) /* only store word with affix ID */ | 4361 int need_affix) // only store word with affix ID |
4362 { | 4362 { |
4363 int len = (int)STRLEN(word); | 4363 int len = (int)STRLEN(word); |
4364 int ct = captype(word, word + len); | 4364 int ct = captype(word, word + len); |
4365 char_u foldword[MAXWLEN]; | 4365 char_u foldword[MAXWLEN]; |
4366 int res = OK; | 4366 int res = OK; |
4411 wordnode_T *np; | 4411 wordnode_T *np; |
4412 wordnode_T *copyp, **copyprev; | 4412 wordnode_T *copyp, **copyprev; |
4413 wordnode_T **prev = NULL; | 4413 wordnode_T **prev = NULL; |
4414 int i; | 4414 int i; |
4415 | 4415 |
4416 /* Add each byte of the word to the tree, including the NUL at the end. */ | 4416 // Add each byte of the word to the tree, including the NUL at the end. |
4417 for (i = 0; ; ++i) | 4417 for (i = 0; ; ++i) |
4418 { | 4418 { |
4419 /* When there is more than one reference to this node we need to make | 4419 // When there is more than one reference to this node we need to make |
4420 * a copy, so that we can modify it. Copy the whole list of siblings | 4420 // a copy, so that we can modify it. Copy the whole list of siblings |
4421 * (we don't optimize for a partly shared list of siblings). */ | 4421 // (we don't optimize for a partly shared list of siblings). |
4422 if (node != NULL && node->wn_refs > 1) | 4422 if (node != NULL && node->wn_refs > 1) |
4423 { | 4423 { |
4424 --node->wn_refs; | 4424 --node->wn_refs; |
4425 copyprev = prev; | 4425 copyprev = prev; |
4426 for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) | 4426 for (copyp = node; copyp != NULL; copyp = copyp->wn_sibling) |
4427 { | 4427 { |
4428 /* Allocate a new node and copy the info. */ | 4428 // Allocate a new node and copy the info. |
4429 np = get_wordnode(spin); | 4429 np = get_wordnode(spin); |
4430 if (np == NULL) | 4430 if (np == NULL) |
4431 return FAIL; | 4431 return FAIL; |
4432 np->wn_child = copyp->wn_child; | 4432 np->wn_child = copyp->wn_child; |
4433 if (np->wn_child != NULL) | 4433 if (np->wn_child != NULL) |
4434 ++np->wn_child->wn_refs; /* child gets extra ref */ | 4434 ++np->wn_child->wn_refs; // child gets extra ref |
4435 np->wn_byte = copyp->wn_byte; | 4435 np->wn_byte = copyp->wn_byte; |
4436 if (np->wn_byte == NUL) | 4436 if (np->wn_byte == NUL) |
4437 { | 4437 { |
4438 np->wn_flags = copyp->wn_flags; | 4438 np->wn_flags = copyp->wn_flags; |
4439 np->wn_region = copyp->wn_region; | 4439 np->wn_region = copyp->wn_region; |
4440 np->wn_affixID = copyp->wn_affixID; | 4440 np->wn_affixID = copyp->wn_affixID; |
4441 } | 4441 } |
4442 | 4442 |
4443 /* Link the new node in the list, there will be one ref. */ | 4443 // Link the new node in the list, there will be one ref. |
4444 np->wn_refs = 1; | 4444 np->wn_refs = 1; |
4445 if (copyprev != NULL) | 4445 if (copyprev != NULL) |
4446 *copyprev = np; | 4446 *copyprev = np; |
4447 copyprev = &np->wn_sibling; | 4447 copyprev = &np->wn_sibling; |
4448 | 4448 |
4449 /* Let "node" point to the head of the copied list. */ | 4449 // Let "node" point to the head of the copied list. |
4450 if (copyp == node) | 4450 if (copyp == node) |
4451 node = np; | 4451 node = np; |
4452 } | 4452 } |
4453 } | 4453 } |
4454 | 4454 |
4455 /* Look for the sibling that has the same character. They are sorted | 4455 // Look for the sibling that has the same character. They are sorted |
4456 * on byte value, thus stop searching when a sibling is found with a | 4456 // on byte value, thus stop searching when a sibling is found with a |
4457 * higher byte value. For zero bytes (end of word) the sorting is | 4457 // higher byte value. For zero bytes (end of word) the sorting is |
4458 * done on flags and then on affixID. */ | 4458 // done on flags and then on affixID. |
4459 while (node != NULL | 4459 while (node != NULL |
4460 && (node->wn_byte < word[i] | 4460 && (node->wn_byte < word[i] |
4461 || (node->wn_byte == NUL | 4461 || (node->wn_byte == NUL |
4462 && (flags < 0 | 4462 && (flags < 0 |
4463 ? node->wn_affixID < (unsigned)affixID | 4463 ? node->wn_affixID < (unsigned)affixID |
4477 && (flags < 0 | 4477 && (flags < 0 |
4478 || spin->si_sugtree | 4478 || spin->si_sugtree |
4479 || node->wn_flags != (flags & WN_MASK) | 4479 || node->wn_flags != (flags & WN_MASK) |
4480 || node->wn_affixID != affixID))) | 4480 || node->wn_affixID != affixID))) |
4481 { | 4481 { |
4482 /* Allocate a new node. */ | 4482 // Allocate a new node. |
4483 np = get_wordnode(spin); | 4483 np = get_wordnode(spin); |
4484 if (np == NULL) | 4484 if (np == NULL) |
4485 return FAIL; | 4485 return FAIL; |
4486 np->wn_byte = word[i]; | 4486 np->wn_byte = word[i]; |
4487 | 4487 |
4488 /* If "node" is NULL this is a new child or the end of the sibling | 4488 // If "node" is NULL this is a new child or the end of the sibling |
4489 * list: ref count is one. Otherwise use ref count of sibling and | 4489 // list: ref count is one. Otherwise use ref count of sibling and |
4490 * make ref count of sibling one (matters when inserting in front | 4490 // make ref count of sibling one (matters when inserting in front |
4491 * of the list of siblings). */ | 4491 // of the list of siblings). |
4492 if (node == NULL) | 4492 if (node == NULL) |
4493 np->wn_refs = 1; | 4493 np->wn_refs = 1; |
4494 else | 4494 else |
4495 { | 4495 { |
4496 np->wn_refs = node->wn_refs; | 4496 np->wn_refs = node->wn_refs; |
4515 #ifdef SPELL_PRINTTREE | 4515 #ifdef SPELL_PRINTTREE |
4516 smsg("Added \"%s\"", word); | 4516 smsg("Added \"%s\"", word); |
4517 spell_print_tree(root->wn_sibling); | 4517 spell_print_tree(root->wn_sibling); |
4518 #endif | 4518 #endif |
4519 | 4519 |
4520 /* count nr of words added since last message */ | 4520 // count nr of words added since last message |
4521 ++spin->si_msg_count; | 4521 ++spin->si_msg_count; |
4522 | 4522 |
4523 if (spin->si_compress_cnt > 1) | 4523 if (spin->si_compress_cnt > 1) |
4524 { | 4524 { |
4525 if (--spin->si_compress_cnt == 1) | 4525 if (--spin->si_compress_cnt == 1) |
4526 /* Did enough words to lower the block count limit. */ | 4526 // Did enough words to lower the block count limit. |
4527 spin->si_blocks_cnt += compress_inc; | 4527 spin->si_blocks_cnt += compress_inc; |
4528 } | 4528 } |
4529 | 4529 |
4530 /* | 4530 /* |
4531 * When we have allocated lots of memory we need to compress the word tree | 4531 * When we have allocated lots of memory we need to compress the word tree |
4543 if (spin->si_compress_cnt == 1 | 4543 if (spin->si_compress_cnt == 1 |
4544 ? spin->si_free_count < MAXWLEN | 4544 ? spin->si_free_count < MAXWLEN |
4545 : spin->si_blocks_cnt >= compress_start) | 4545 : spin->si_blocks_cnt >= compress_start) |
4546 #endif | 4546 #endif |
4547 { | 4547 { |
4548 /* Decrement the block counter. The effect is that we compress again | 4548 // Decrement the block counter. The effect is that we compress again |
4549 * when the freed up room has been used and another "compress_inc" | 4549 // when the freed up room has been used and another "compress_inc" |
4550 * blocks have been allocated. Unless "compress_added" words have | 4550 // blocks have been allocated. Unless "compress_added" words have |
4551 * been added, then the limit is put back again. */ | 4551 // been added, then the limit is put back again. |
4552 spin->si_blocks_cnt -= compress_inc; | 4552 spin->si_blocks_cnt -= compress_inc; |
4553 spin->si_compress_cnt = compress_added; | 4553 spin->si_compress_cnt = compress_added; |
4554 | 4554 |
4555 if (spin->si_verbose) | 4555 if (spin->si_verbose) |
4556 { | 4556 { |
4560 msg_didout = FALSE; | 4560 msg_didout = FALSE; |
4561 msg_col = 0; | 4561 msg_col = 0; |
4562 out_flush(); | 4562 out_flush(); |
4563 } | 4563 } |
4564 | 4564 |
4565 /* Compress both trees. Either they both have many nodes, which makes | 4565 // Compress both trees. Either they both have many nodes, which makes |
4566 * compression useful, or one of them is small, which means | 4566 // compression useful, or one of them is small, which means |
4567 * compression goes fast. But when filling the soundfold word tree | 4567 // compression goes fast. But when filling the soundfold word tree |
4568 * there is no keep-case tree. */ | 4568 // there is no keep-case tree. |
4569 wordtree_compress(spin, spin->si_foldroot); | 4569 wordtree_compress(spin, spin->si_foldroot); |
4570 if (affixID >= 0) | 4570 if (affixID >= 0) |
4571 wordtree_compress(spin, spin->si_keeproot); | 4571 wordtree_compress(spin, spin->si_keeproot); |
4572 } | 4572 } |
4573 | 4573 |
4619 if (np->wn_child != NULL) | 4619 if (np->wn_child != NULL) |
4620 cnt += deref_wordnode(spin, np->wn_child); | 4620 cnt += deref_wordnode(spin, np->wn_child); |
4621 free_wordnode(spin, np); | 4621 free_wordnode(spin, np); |
4622 ++cnt; | 4622 ++cnt; |
4623 } | 4623 } |
4624 ++cnt; /* length field */ | 4624 ++cnt; // length field |
4625 } | 4625 } |
4626 return cnt; | 4626 return cnt; |
4627 } | 4627 } |
4628 | 4628 |
4629 /* | 4629 /* |
4647 hashtab_T ht; | 4647 hashtab_T ht; |
4648 int n; | 4648 int n; |
4649 int tot = 0; | 4649 int tot = 0; |
4650 int perc; | 4650 int perc; |
4651 | 4651 |
4652 /* Skip the root itself, it's not actually used. The first sibling is the | 4652 // Skip the root itself, it's not actually used. The first sibling is the |
4653 * start of the tree. */ | 4653 // start of the tree. |
4654 if (root->wn_sibling != NULL) | 4654 if (root->wn_sibling != NULL) |
4655 { | 4655 { |
4656 hash_init(&ht); | 4656 hash_init(&ht); |
4657 n = node_compress(spin, root->wn_sibling, &ht, &tot); | 4657 n = node_compress(spin, root->wn_sibling, &ht, &tot); |
4658 | 4658 |
4685 static int | 4685 static int |
4686 node_compress( | 4686 node_compress( |
4687 spellinfo_T *spin, | 4687 spellinfo_T *spin, |
4688 wordnode_T *node, | 4688 wordnode_T *node, |
4689 hashtab_T *ht, | 4689 hashtab_T *ht, |
4690 int *tot) /* total count of nodes before compressing, | 4690 int *tot) // total count of nodes before compressing, |
4691 incremented while going through the tree */ | 4691 // incremented while going through the tree |
4692 { | 4692 { |
4693 wordnode_T *np; | 4693 wordnode_T *np; |
4694 wordnode_T *tp; | 4694 wordnode_T *tp; |
4695 wordnode_T *child; | 4695 wordnode_T *child; |
4696 hash_T hash; | 4696 hash_T hash; |
4708 for (np = node; np != NULL && !got_int; np = np->wn_sibling) | 4708 for (np = node; np != NULL && !got_int; np = np->wn_sibling) |
4709 { | 4709 { |
4710 ++len; | 4710 ++len; |
4711 if ((child = np->wn_child) != NULL) | 4711 if ((child = np->wn_child) != NULL) |
4712 { | 4712 { |
4713 /* Compress the child first. This fills hashkey. */ | 4713 // Compress the child first. This fills hashkey. |
4714 compressed += node_compress(spin, child, ht, tot); | 4714 compressed += node_compress(spin, child, ht, tot); |
4715 | 4715 |
4716 /* Try to find an identical child. */ | 4716 // Try to find an identical child. |
4717 hash = hash_hash(child->wn_u1.hashkey); | 4717 hash = hash_hash(child->wn_u1.hashkey); |
4718 hi = hash_lookup(ht, child->wn_u1.hashkey, hash); | 4718 hi = hash_lookup(ht, child->wn_u1.hashkey, hash); |
4719 if (!HASHITEM_EMPTY(hi)) | 4719 if (!HASHITEM_EMPTY(hi)) |
4720 { | 4720 { |
4721 /* There are children we encountered before with a hash value | 4721 // There are children we encountered before with a hash value |
4722 * identical to the current child. Now check if there is one | 4722 // identical to the current child. Now check if there is one |
4723 * that is really identical. */ | 4723 // that is really identical. |
4724 for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) | 4724 for (tp = HI2WN(hi); tp != NULL; tp = tp->wn_u2.next) |
4725 if (node_equal(child, tp)) | 4725 if (node_equal(child, tp)) |
4726 { | 4726 { |
4727 /* Found one! Now use that child in place of the | 4727 // Found one! Now use that child in place of the |
4728 * current one. This means the current child and all | 4728 // current one. This means the current child and all |
4729 * its siblings is unlinked from the tree. */ | 4729 // its siblings is unlinked from the tree. |
4730 ++tp->wn_refs; | 4730 ++tp->wn_refs; |
4731 compressed += deref_wordnode(spin, child); | 4731 compressed += deref_wordnode(spin, child); |
4732 np->wn_child = tp; | 4732 np->wn_child = tp; |
4733 break; | 4733 break; |
4734 } | 4734 } |
4735 if (tp == NULL) | 4735 if (tp == NULL) |
4736 { | 4736 { |
4737 /* No other child with this hash value equals the child of | 4737 // No other child with this hash value equals the child of |
4738 * the node, add it to the linked list after the first | 4738 // the node, add it to the linked list after the first |
4739 * item. */ | 4739 // item. |
4740 tp = HI2WN(hi); | 4740 tp = HI2WN(hi); |
4741 child->wn_u2.next = tp->wn_u2.next; | 4741 child->wn_u2.next = tp->wn_u2.next; |
4742 tp->wn_u2.next = child; | 4742 tp->wn_u2.next = child; |
4743 } | 4743 } |
4744 } | 4744 } |
4745 else | 4745 else |
4746 /* No other child has this hash value, add it to the | 4746 // No other child has this hash value, add it to the |
4747 * hashtable. */ | 4747 // hashtable. |
4748 hash_add_item(ht, hi, child->wn_u1.hashkey, hash); | 4748 hash_add_item(ht, hi, child->wn_u1.hashkey, hash); |
4749 } | 4749 } |
4750 } | 4750 } |
4751 *tot += len + 1; /* add one for the node that stores the length */ | 4751 *tot += len + 1; // add one for the node that stores the length |
4752 | 4752 |
4753 /* | 4753 /* |
4754 * Make a hash key for the node and its siblings, so that we can quickly | 4754 * Make a hash key for the node and its siblings, so that we can quickly |
4755 * find a lookalike node. This must be done after compressing the sibling | 4755 * find a lookalike node. This must be done after compressing the sibling |
4756 * list, otherwise the hash key would become invalid by the compression. | 4756 * list, otherwise the hash key would become invalid by the compression. |
4758 node->wn_u1.hashkey[0] = len; | 4758 node->wn_u1.hashkey[0] = len; |
4759 nr = 0; | 4759 nr = 0; |
4760 for (np = node; np != NULL; np = np->wn_sibling) | 4760 for (np = node; np != NULL; np = np->wn_sibling) |
4761 { | 4761 { |
4762 if (np->wn_byte == NUL) | 4762 if (np->wn_byte == NUL) |
4763 /* end node: use wn_flags, wn_region and wn_affixID */ | 4763 // end node: use wn_flags, wn_region and wn_affixID |
4764 n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16); | 4764 n = np->wn_flags + (np->wn_region << 8) + (np->wn_affixID << 16); |
4765 else | 4765 else |
4766 /* byte node: use the byte value and the child pointer */ | 4766 // byte node: use the byte value and the child pointer |
4767 n = (unsigned)(np->wn_byte + ((long_u)np->wn_child << 8)); | 4767 n = (unsigned)(np->wn_byte + ((long_u)np->wn_child << 8)); |
4768 nr = nr * 101 + n; | 4768 nr = nr * 101 + n; |
4769 } | 4769 } |
4770 | 4770 |
4771 /* Avoid NUL bytes, it terminates the hash key. */ | 4771 // Avoid NUL bytes, it terminates the hash key. |
4772 n = nr & 0xff; | 4772 n = nr & 0xff; |
4773 node->wn_u1.hashkey[1] = n == 0 ? 1 : n; | 4773 node->wn_u1.hashkey[1] = n == 0 ? 1 : n; |
4774 n = (nr >> 8) & 0xff; | 4774 n = (nr >> 8) & 0xff; |
4775 node->wn_u1.hashkey[2] = n == 0 ? 1 : n; | 4775 node->wn_u1.hashkey[2] = n == 0 ? 1 : n; |
4776 n = (nr >> 16) & 0xff; | 4776 n = (nr >> 16) & 0xff; |
4777 node->wn_u1.hashkey[3] = n == 0 ? 1 : n; | 4777 node->wn_u1.hashkey[3] = n == 0 ? 1 : n; |
4778 n = (nr >> 24) & 0xff; | 4778 n = (nr >> 24) & 0xff; |
4779 node->wn_u1.hashkey[4] = n == 0 ? 1 : n; | 4779 node->wn_u1.hashkey[4] = n == 0 ? 1 : n; |
4780 node->wn_u1.hashkey[5] = NUL; | 4780 node->wn_u1.hashkey[5] = NUL; |
4781 | 4781 |
4782 /* Check for CTRL-C pressed now and then. */ | 4782 // Check for CTRL-C pressed now and then. |
4783 fast_breakcheck(); | 4783 fast_breakcheck(); |
4784 | 4784 |
4785 return compressed; | 4785 return compressed; |
4786 } | 4786 } |
4787 | 4787 |
4838 garray_T *gap; | 4838 garray_T *gap; |
4839 fromto_T *ftp; | 4839 fromto_T *ftp; |
4840 char_u *p; | 4840 char_u *p; |
4841 int rr; | 4841 int rr; |
4842 int retval = OK; | 4842 int retval = OK; |
4843 size_t fwv = 1; /* collect return value of fwrite() to avoid | 4843 size_t fwv = 1; // collect return value of fwrite() to avoid |
4844 warnings from picky compiler */ | 4844 // warnings from picky compiler |
4845 | 4845 |
4846 fd = mch_fopen((char *)fname, "w"); | 4846 fd = mch_fopen((char *)fname, "w"); |
4847 if (fd == NULL) | 4847 if (fd == NULL) |
4848 { | 4848 { |
4849 semsg(_(e_notopen), fname); | 4849 semsg(_(e_notopen), fname); |
4850 return FAIL; | 4850 return FAIL; |
4851 } | 4851 } |
4852 | 4852 |
4853 /* <HEADER>: <fileID> <versionnr> */ | 4853 // <HEADER>: <fileID> <versionnr> |
4854 /* <fileID> */ | 4854 // <fileID> |
4855 fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); | 4855 fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); |
4856 if (fwv != (size_t)1) | 4856 if (fwv != (size_t)1) |
4857 /* Catch first write error, don't try writing more. */ | 4857 // Catch first write error, don't try writing more. |
4858 goto theend; | 4858 goto theend; |
4859 | 4859 |
4860 putc(VIMSPELLVERSION, fd); /* <versionnr> */ | 4860 putc(VIMSPELLVERSION, fd); // <versionnr> |
4861 | 4861 |
4862 /* | 4862 /* |
4863 * <SECTIONS>: <section> ... <sectionend> | 4863 * <SECTIONS>: <section> ... <sectionend> |
4864 */ | 4864 */ |
4865 | 4865 |
4866 /* SN_INFO: <infotext> */ | 4866 // SN_INFO: <infotext> |
4867 if (spin->si_info != NULL) | 4867 if (spin->si_info != NULL) |
4868 { | 4868 { |
4869 putc(SN_INFO, fd); /* <sectionID> */ | 4869 putc(SN_INFO, fd); // <sectionID> |
4870 putc(0, fd); /* <sectionflags> */ | 4870 putc(0, fd); // <sectionflags> |
4871 | 4871 |
4872 i = (int)STRLEN(spin->si_info); | 4872 i = (int)STRLEN(spin->si_info); |
4873 put_bytes(fd, (long_u)i, 4); /* <sectionlen> */ | 4873 put_bytes(fd, (long_u)i, 4); // <sectionlen> |
4874 fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); /* <infotext> */ | 4874 fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); // <infotext> |
4875 } | 4875 } |
4876 | 4876 |
4877 /* SN_REGION: <regionname> ... | 4877 // SN_REGION: <regionname> ... |
4878 * Write the region names only if there is more than one. */ | 4878 // Write the region names only if there is more than one. |
4879 if (spin->si_region_count > 1) | 4879 if (spin->si_region_count > 1) |
4880 { | 4880 { |
4881 putc(SN_REGION, fd); /* <sectionID> */ | 4881 putc(SN_REGION, fd); // <sectionID> |
4882 putc(SNF_REQUIRED, fd); /* <sectionflags> */ | 4882 putc(SNF_REQUIRED, fd); // <sectionflags> |
4883 l = spin->si_region_count * 2; | 4883 l = spin->si_region_count * 2; |
4884 put_bytes(fd, (long_u)l, 4); /* <sectionlen> */ | 4884 put_bytes(fd, (long_u)l, 4); // <sectionlen> |
4885 fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); | 4885 fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); |
4886 /* <regionname> ... */ | 4886 // <regionname> ... |
4887 regionmask = (1 << spin->si_region_count) - 1; | 4887 regionmask = (1 << spin->si_region_count) - 1; |
4888 } | 4888 } |
4889 else | 4889 else |
4890 regionmask = 0; | 4890 regionmask = 0; |
4891 | 4891 |
4892 /* SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars> | 4892 // SN_CHARFLAGS: <charflagslen> <charflags> <folcharslen> <folchars> |
4893 * | 4893 // |
4894 * The table with character flags and the table for case folding. | 4894 // The table with character flags and the table for case folding. |
4895 * This makes sure the same characters are recognized as word characters | 4895 // This makes sure the same characters are recognized as word characters |
4896 * when generating an when using a spell file. | 4896 // when generating an when using a spell file. |
4897 * Skip this for ASCII, the table may conflict with the one used for | 4897 // Skip this for ASCII, the table may conflict with the one used for |
4898 * 'encoding'. | 4898 // 'encoding'. |
4899 * Also skip this for an .add.spl file, the main spell file must contain | 4899 // Also skip this for an .add.spl file, the main spell file must contain |
4900 * the table (avoids that it conflicts). File is shorter too. | 4900 // the table (avoids that it conflicts). File is shorter too. |
4901 */ | |
4902 if (!spin->si_ascii && !spin->si_add) | 4901 if (!spin->si_ascii && !spin->si_add) |
4903 { | 4902 { |
4904 char_u folchars[128 * 8]; | 4903 char_u folchars[128 * 8]; |
4905 int flags; | 4904 int flags; |
4906 | 4905 |
4907 putc(SN_CHARFLAGS, fd); /* <sectionID> */ | 4906 putc(SN_CHARFLAGS, fd); // <sectionID> |
4908 putc(SNF_REQUIRED, fd); /* <sectionflags> */ | 4907 putc(SNF_REQUIRED, fd); // <sectionflags> |
4909 | 4908 |
4910 /* Form the <folchars> string first, we need to know its length. */ | 4909 // Form the <folchars> string first, we need to know its length. |
4911 l = 0; | 4910 l = 0; |
4912 for (i = 128; i < 256; ++i) | 4911 for (i = 128; i < 256; ++i) |
4913 { | 4912 { |
4914 if (has_mbyte) | 4913 if (has_mbyte) |
4915 l += mb_char2bytes(spelltab.st_fold[i], folchars + l); | 4914 l += mb_char2bytes(spelltab.st_fold[i], folchars + l); |
4916 else | 4915 else |
4917 folchars[l++] = spelltab.st_fold[i]; | 4916 folchars[l++] = spelltab.st_fold[i]; |
4918 } | 4917 } |
4919 put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); /* <sectionlen> */ | 4918 put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); // <sectionlen> |
4920 | 4919 |
4921 fputc(128, fd); /* <charflagslen> */ | 4920 fputc(128, fd); // <charflagslen> |
4922 for (i = 128; i < 256; ++i) | 4921 for (i = 128; i < 256; ++i) |
4923 { | 4922 { |
4924 flags = 0; | 4923 flags = 0; |
4925 if (spelltab.st_isw[i]) | 4924 if (spelltab.st_isw[i]) |
4926 flags |= CF_WORD; | 4925 flags |= CF_WORD; |
4927 if (spelltab.st_isu[i]) | 4926 if (spelltab.st_isu[i]) |
4928 flags |= CF_UPPER; | 4927 flags |= CF_UPPER; |
4929 fputc(flags, fd); /* <charflags> */ | 4928 fputc(flags, fd); // <charflags> |
4930 } | 4929 } |
4931 | 4930 |
4932 put_bytes(fd, (long_u)l, 2); /* <folcharslen> */ | 4931 put_bytes(fd, (long_u)l, 2); // <folcharslen> |
4933 fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); /* <folchars> */ | 4932 fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); // <folchars> |
4934 } | 4933 } |
4935 | 4934 |
4936 /* SN_MIDWORD: <midword> */ | 4935 // SN_MIDWORD: <midword> |
4937 if (spin->si_midword != NULL) | 4936 if (spin->si_midword != NULL) |
4938 { | 4937 { |
4939 putc(SN_MIDWORD, fd); /* <sectionID> */ | 4938 putc(SN_MIDWORD, fd); // <sectionID> |
4940 putc(SNF_REQUIRED, fd); /* <sectionflags> */ | 4939 putc(SNF_REQUIRED, fd); // <sectionflags> |
4941 | 4940 |
4942 i = (int)STRLEN(spin->si_midword); | 4941 i = (int)STRLEN(spin->si_midword); |
4943 put_bytes(fd, (long_u)i, 4); /* <sectionlen> */ | 4942 put_bytes(fd, (long_u)i, 4); // <sectionlen> |
4944 fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); | 4943 fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); |
4945 /* <midword> */ | 4944 // <midword> |
4946 } | 4945 } |
4947 | 4946 |
4948 /* SN_PREFCOND: <prefcondcnt> <prefcond> ... */ | 4947 // SN_PREFCOND: <prefcondcnt> <prefcond> ... |
4949 if (spin->si_prefcond.ga_len > 0) | 4948 if (spin->si_prefcond.ga_len > 0) |
4950 { | 4949 { |
4951 putc(SN_PREFCOND, fd); /* <sectionID> */ | 4950 putc(SN_PREFCOND, fd); // <sectionID> |
4952 putc(SNF_REQUIRED, fd); /* <sectionflags> */ | 4951 putc(SNF_REQUIRED, fd); // <sectionflags> |
4953 | 4952 |
4954 l = write_spell_prefcond(NULL, &spin->si_prefcond); | 4953 l = write_spell_prefcond(NULL, &spin->si_prefcond); |
4955 put_bytes(fd, (long_u)l, 4); /* <sectionlen> */ | 4954 put_bytes(fd, (long_u)l, 4); // <sectionlen> |
4956 | 4955 |
4957 write_spell_prefcond(fd, &spin->si_prefcond); | 4956 write_spell_prefcond(fd, &spin->si_prefcond); |
4958 } | 4957 } |
4959 | 4958 |
4960 /* SN_REP: <repcount> <rep> ... | 4959 // SN_REP: <repcount> <rep> ... |
4961 * SN_SAL: <salflags> <salcount> <sal> ... | 4960 // SN_SAL: <salflags> <salcount> <sal> ... |
4962 * SN_REPSAL: <repcount> <rep> ... */ | 4961 // SN_REPSAL: <repcount> <rep> ... |
4963 | 4962 |
4964 /* round 1: SN_REP section | 4963 // round 1: SN_REP section |
4965 * round 2: SN_SAL section (unless SN_SOFO is used) | 4964 // round 2: SN_SAL section (unless SN_SOFO is used) |
4966 * round 3: SN_REPSAL section */ | 4965 // round 3: SN_REPSAL section |
4967 for (round = 1; round <= 3; ++round) | 4966 for (round = 1; round <= 3; ++round) |
4968 { | 4967 { |
4969 if (round == 1) | 4968 if (round == 1) |
4970 gap = &spin->si_rep; | 4969 gap = &spin->si_rep; |
4971 else if (round == 2) | 4970 else if (round == 2) |
4972 { | 4971 { |
4973 /* Don't write SN_SAL when using a SN_SOFO section */ | 4972 // Don't write SN_SAL when using a SN_SOFO section |
4974 if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) | 4973 if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) |
4975 continue; | 4974 continue; |
4976 gap = &spin->si_sal; | 4975 gap = &spin->si_sal; |
4977 } | 4976 } |
4978 else | 4977 else |
4979 gap = &spin->si_repsal; | 4978 gap = &spin->si_repsal; |
4980 | 4979 |
4981 /* Don't write the section if there are no items. */ | 4980 // Don't write the section if there are no items. |
4982 if (gap->ga_len == 0) | 4981 if (gap->ga_len == 0) |
4983 continue; | 4982 continue; |
4984 | 4983 |
4985 /* Sort the REP/REPSAL items. */ | 4984 // Sort the REP/REPSAL items. |
4986 if (round != 2) | 4985 if (round != 2) |
4987 qsort(gap->ga_data, (size_t)gap->ga_len, | 4986 qsort(gap->ga_data, (size_t)gap->ga_len, |
4988 sizeof(fromto_T), rep_compare); | 4987 sizeof(fromto_T), rep_compare); |
4989 | 4988 |
4990 i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); | 4989 i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); |
4991 putc(i, fd); /* <sectionID> */ | 4990 putc(i, fd); // <sectionID> |
4992 | 4991 |
4993 /* This is for making suggestions, section is not required. */ | 4992 // This is for making suggestions, section is not required. |
4994 putc(0, fd); /* <sectionflags> */ | 4993 putc(0, fd); // <sectionflags> |
4995 | 4994 |
4996 /* Compute the length of what follows. */ | 4995 // Compute the length of what follows. |
4997 l = 2; /* count <repcount> or <salcount> */ | 4996 l = 2; // count <repcount> or <salcount> |
4998 for (i = 0; i < gap->ga_len; ++i) | 4997 for (i = 0; i < gap->ga_len; ++i) |
4999 { | 4998 { |
5000 ftp = &((fromto_T *)gap->ga_data)[i]; | 4999 ftp = &((fromto_T *)gap->ga_data)[i]; |
5001 l += 1 + (int)STRLEN(ftp->ft_from); /* count <*fromlen> and <*from> */ | 5000 l += 1 + (int)STRLEN(ftp->ft_from); // count <*fromlen> and <*from> |
5002 l += 1 + (int)STRLEN(ftp->ft_to); /* count <*tolen> and <*to> */ | 5001 l += 1 + (int)STRLEN(ftp->ft_to); // count <*tolen> and <*to> |
5003 } | 5002 } |
5004 if (round == 2) | 5003 if (round == 2) |
5005 ++l; /* count <salflags> */ | 5004 ++l; // count <salflags> |
5006 put_bytes(fd, (long_u)l, 4); /* <sectionlen> */ | 5005 put_bytes(fd, (long_u)l, 4); // <sectionlen> |
5007 | 5006 |
5008 if (round == 2) | 5007 if (round == 2) |
5009 { | 5008 { |
5010 i = 0; | 5009 i = 0; |
5011 if (spin->si_followup) | 5010 if (spin->si_followup) |
5012 i |= SAL_F0LLOWUP; | 5011 i |= SAL_F0LLOWUP; |
5013 if (spin->si_collapse) | 5012 if (spin->si_collapse) |
5014 i |= SAL_COLLAPSE; | 5013 i |= SAL_COLLAPSE; |
5015 if (spin->si_rem_accents) | 5014 if (spin->si_rem_accents) |
5016 i |= SAL_REM_ACCENTS; | 5015 i |= SAL_REM_ACCENTS; |
5017 putc(i, fd); /* <salflags> */ | 5016 putc(i, fd); // <salflags> |
5018 } | 5017 } |
5019 | 5018 |
5020 put_bytes(fd, (long_u)gap->ga_len, 2); /* <repcount> or <salcount> */ | 5019 put_bytes(fd, (long_u)gap->ga_len, 2); // <repcount> or <salcount> |
5021 for (i = 0; i < gap->ga_len; ++i) | 5020 for (i = 0; i < gap->ga_len; ++i) |
5022 { | 5021 { |
5023 /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */ | 5022 // <rep> : <repfromlen> <repfrom> <reptolen> <repto> |
5024 /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */ | 5023 // <sal> : <salfromlen> <salfrom> <saltolen> <salto> |
5025 ftp = &((fromto_T *)gap->ga_data)[i]; | 5024 ftp = &((fromto_T *)gap->ga_data)[i]; |
5026 for (rr = 1; rr <= 2; ++rr) | 5025 for (rr = 1; rr <= 2; ++rr) |
5027 { | 5026 { |
5028 p = rr == 1 ? ftp->ft_from : ftp->ft_to; | 5027 p = rr == 1 ? ftp->ft_from : ftp->ft_to; |
5029 l = (int)STRLEN(p); | 5028 l = (int)STRLEN(p); |
5033 } | 5032 } |
5034 } | 5033 } |
5035 | 5034 |
5036 } | 5035 } |
5037 | 5036 |
5038 /* SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto> | 5037 // SN_SOFO: <sofofromlen> <sofofrom> <sofotolen> <sofoto> |
5039 * This is for making suggestions, section is not required. */ | 5038 // This is for making suggestions, section is not required. |
5040 if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) | 5039 if (spin->si_sofofr != NULL && spin->si_sofoto != NULL) |
5041 { | 5040 { |
5042 putc(SN_SOFO, fd); /* <sectionID> */ | 5041 putc(SN_SOFO, fd); // <sectionID> |
5043 putc(0, fd); /* <sectionflags> */ | 5042 putc(0, fd); // <sectionflags> |
5044 | 5043 |
5045 l = (int)STRLEN(spin->si_sofofr); | 5044 l = (int)STRLEN(spin->si_sofofr); |
5046 put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); | 5045 put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); |
5047 /* <sectionlen> */ | 5046 // <sectionlen> |
5048 | 5047 |
5049 put_bytes(fd, (long_u)l, 2); /* <sofofromlen> */ | 5048 put_bytes(fd, (long_u)l, 2); // <sofofromlen> |
5050 fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); /* <sofofrom> */ | 5049 fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); // <sofofrom> |
5051 | 5050 |
5052 l = (int)STRLEN(spin->si_sofoto); | 5051 l = (int)STRLEN(spin->si_sofoto); |
5053 put_bytes(fd, (long_u)l, 2); /* <sofotolen> */ | 5052 put_bytes(fd, (long_u)l, 2); // <sofotolen> |
5054 fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); /* <sofoto> */ | 5053 fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); // <sofoto> |
5055 } | 5054 } |
5056 | 5055 |
5057 /* SN_WORDS: <word> ... | 5056 // SN_WORDS: <word> ... |
5058 * This is for making suggestions, section is not required. */ | 5057 // This is for making suggestions, section is not required. |
5059 if (spin->si_commonwords.ht_used > 0) | 5058 if (spin->si_commonwords.ht_used > 0) |
5060 { | 5059 { |
5061 putc(SN_WORDS, fd); /* <sectionID> */ | 5060 putc(SN_WORDS, fd); // <sectionID> |
5062 putc(0, fd); /* <sectionflags> */ | 5061 putc(0, fd); // <sectionflags> |
5063 | 5062 |
5064 /* round 1: count the bytes | 5063 // round 1: count the bytes |
5065 * round 2: write the bytes */ | 5064 // round 2: write the bytes |
5066 for (round = 1; round <= 2; ++round) | 5065 for (round = 1; round <= 2; ++round) |
5067 { | 5066 { |
5068 int todo; | 5067 int todo; |
5069 int len = 0; | 5068 int len = 0; |
5070 hashitem_T *hi; | 5069 hashitem_T *hi; |
5073 for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) | 5072 for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) |
5074 if (!HASHITEM_EMPTY(hi)) | 5073 if (!HASHITEM_EMPTY(hi)) |
5075 { | 5074 { |
5076 l = (int)STRLEN(hi->hi_key) + 1; | 5075 l = (int)STRLEN(hi->hi_key) + 1; |
5077 len += l; | 5076 len += l; |
5078 if (round == 2) /* <word> */ | 5077 if (round == 2) // <word> |
5079 fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); | 5078 fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); |
5080 --todo; | 5079 --todo; |
5081 } | 5080 } |
5082 if (round == 1) | 5081 if (round == 1) |
5083 put_bytes(fd, (long_u)len, 4); /* <sectionlen> */ | 5082 put_bytes(fd, (long_u)len, 4); // <sectionlen> |
5084 } | 5083 } |
5085 } | 5084 } |
5086 | 5085 |
5087 /* SN_MAP: <mapstr> | 5086 // SN_MAP: <mapstr> |
5088 * This is for making suggestions, section is not required. */ | 5087 // This is for making suggestions, section is not required. |
5089 if (spin->si_map.ga_len > 0) | 5088 if (spin->si_map.ga_len > 0) |
5090 { | 5089 { |
5091 putc(SN_MAP, fd); /* <sectionID> */ | 5090 putc(SN_MAP, fd); // <sectionID> |
5092 putc(0, fd); /* <sectionflags> */ | 5091 putc(0, fd); // <sectionflags> |
5093 l = spin->si_map.ga_len; | 5092 l = spin->si_map.ga_len; |
5094 put_bytes(fd, (long_u)l, 4); /* <sectionlen> */ | 5093 put_bytes(fd, (long_u)l, 4); // <sectionlen> |
5095 fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); | 5094 fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); |
5096 /* <mapstr> */ | 5095 // <mapstr> |
5097 } | 5096 } |
5098 | 5097 |
5099 /* SN_SUGFILE: <timestamp> | 5098 // SN_SUGFILE: <timestamp> |
5100 * This is used to notify that a .sug file may be available and at the | 5099 // This is used to notify that a .sug file may be available and at the |
5101 * same time allows for checking that a .sug file that is found matches | 5100 // same time allows for checking that a .sug file that is found matches |
5102 * with this .spl file. That's because the word numbers must be exactly | 5101 // with this .spl file. That's because the word numbers must be exactly |
5103 * right. */ | 5102 // right. |
5104 if (!spin->si_nosugfile | 5103 if (!spin->si_nosugfile |
5105 && (spin->si_sal.ga_len > 0 | 5104 && (spin->si_sal.ga_len > 0 |
5106 || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) | 5105 || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) |
5107 { | 5106 { |
5108 putc(SN_SUGFILE, fd); /* <sectionID> */ | 5107 putc(SN_SUGFILE, fd); // <sectionID> |
5109 putc(0, fd); /* <sectionflags> */ | 5108 putc(0, fd); // <sectionflags> |
5110 put_bytes(fd, (long_u)8, 4); /* <sectionlen> */ | 5109 put_bytes(fd, (long_u)8, 4); // <sectionlen> |
5111 | 5110 |
5112 /* Set si_sugtime and write it to the file. */ | 5111 // Set si_sugtime and write it to the file. |
5113 spin->si_sugtime = time(NULL); | 5112 spin->si_sugtime = time(NULL); |
5114 put_time(fd, spin->si_sugtime); /* <timestamp> */ | 5113 put_time(fd, spin->si_sugtime); // <timestamp> |
5115 } | 5114 } |
5116 | 5115 |
5117 /* SN_NOSPLITSUGS: nothing | 5116 // SN_NOSPLITSUGS: nothing |
5118 * This is used to notify that no suggestions with word splits are to be | 5117 // This is used to notify that no suggestions with word splits are to be |
5119 * made. */ | 5118 // made. |
5120 if (spin->si_nosplitsugs) | 5119 if (spin->si_nosplitsugs) |
5121 { | 5120 { |
5122 putc(SN_NOSPLITSUGS, fd); /* <sectionID> */ | 5121 putc(SN_NOSPLITSUGS, fd); // <sectionID> |
5123 putc(0, fd); /* <sectionflags> */ | 5122 putc(0, fd); // <sectionflags> |
5124 put_bytes(fd, (long_u)0, 4); /* <sectionlen> */ | 5123 put_bytes(fd, (long_u)0, 4); // <sectionlen> |
5125 } | 5124 } |
5126 | 5125 |
5127 /* SN_NOCOMPUNDSUGS: nothing | 5126 // SN_NOCOMPUNDSUGS: nothing |
5128 * This is used to notify that no suggestions with compounds are to be | 5127 // This is used to notify that no suggestions with compounds are to be |
5129 * made. */ | 5128 // made. |
5130 if (spin->si_nocompoundsugs) | 5129 if (spin->si_nocompoundsugs) |
5131 { | 5130 { |
5132 putc(SN_NOCOMPOUNDSUGS, fd); /* <sectionID> */ | 5131 putc(SN_NOCOMPOUNDSUGS, fd); // <sectionID> |
5133 putc(0, fd); /* <sectionflags> */ | 5132 putc(0, fd); // <sectionflags> |
5134 put_bytes(fd, (long_u)0, 4); /* <sectionlen> */ | 5133 put_bytes(fd, (long_u)0, 4); // <sectionlen> |
5135 } | 5134 } |
5136 | 5135 |
5137 /* SN_COMPOUND: compound info. | 5136 // SN_COMPOUND: compound info. |
5138 * We don't mark it required, when not supported all compound words will | 5137 // We don't mark it required, when not supported all compound words will |
5139 * be bad words. */ | 5138 // be bad words. |
5140 if (spin->si_compflags != NULL) | 5139 if (spin->si_compflags != NULL) |
5141 { | 5140 { |
5142 putc(SN_COMPOUND, fd); /* <sectionID> */ | 5141 putc(SN_COMPOUND, fd); // <sectionID> |
5143 putc(0, fd); /* <sectionflags> */ | 5142 putc(0, fd); // <sectionflags> |
5144 | 5143 |
5145 l = (int)STRLEN(spin->si_compflags); | 5144 l = (int)STRLEN(spin->si_compflags); |
5146 for (i = 0; i < spin->si_comppat.ga_len; ++i) | 5145 for (i = 0; i < spin->si_comppat.ga_len; ++i) |
5147 l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; | 5146 l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; |
5148 put_bytes(fd, (long_u)(l + 7), 4); /* <sectionlen> */ | 5147 put_bytes(fd, (long_u)(l + 7), 4); // <sectionlen> |
5149 | 5148 |
5150 putc(spin->si_compmax, fd); /* <compmax> */ | 5149 putc(spin->si_compmax, fd); // <compmax> |
5151 putc(spin->si_compminlen, fd); /* <compminlen> */ | 5150 putc(spin->si_compminlen, fd); // <compminlen> |
5152 putc(spin->si_compsylmax, fd); /* <compsylmax> */ | 5151 putc(spin->si_compsylmax, fd); // <compsylmax> |
5153 putc(0, fd); /* for Vim 7.0b compatibility */ | 5152 putc(0, fd); // for Vim 7.0b compatibility |
5154 putc(spin->si_compoptions, fd); /* <compoptions> */ | 5153 putc(spin->si_compoptions, fd); // <compoptions> |
5155 put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); | 5154 put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); |
5156 /* <comppatcount> */ | 5155 // <comppatcount> |
5157 for (i = 0; i < spin->si_comppat.ga_len; ++i) | 5156 for (i = 0; i < spin->si_comppat.ga_len; ++i) |
5158 { | 5157 { |
5159 p = ((char_u **)(spin->si_comppat.ga_data))[i]; | 5158 p = ((char_u **)(spin->si_comppat.ga_data))[i]; |
5160 putc((int)STRLEN(p), fd); /* <comppatlen> */ | 5159 putc((int)STRLEN(p), fd); // <comppatlen> |
5161 fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); | 5160 fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); |
5162 /* <comppattext> */ | 5161 // <comppattext> |
5163 } | 5162 } |
5164 /* <compflags> */ | 5163 // <compflags> |
5165 fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), | 5164 fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), |
5166 (size_t)1, fd); | 5165 (size_t)1, fd); |
5167 } | 5166 } |
5168 | 5167 |
5169 /* SN_NOBREAK: NOBREAK flag */ | 5168 // SN_NOBREAK: NOBREAK flag |
5170 if (spin->si_nobreak) | 5169 if (spin->si_nobreak) |
5171 { | 5170 { |
5172 putc(SN_NOBREAK, fd); /* <sectionID> */ | 5171 putc(SN_NOBREAK, fd); // <sectionID> |
5173 putc(0, fd); /* <sectionflags> */ | 5172 putc(0, fd); // <sectionflags> |
5174 | 5173 |
5175 /* It's empty, the presence of the section flags the feature. */ | 5174 // It's empty, the presence of the section flags the feature. |
5176 put_bytes(fd, (long_u)0, 4); /* <sectionlen> */ | 5175 put_bytes(fd, (long_u)0, 4); // <sectionlen> |
5177 } | 5176 } |
5178 | 5177 |
5179 /* SN_SYLLABLE: syllable info. | 5178 // SN_SYLLABLE: syllable info. |
5180 * We don't mark it required, when not supported syllables will not be | 5179 // We don't mark it required, when not supported syllables will not be |
5181 * counted. */ | 5180 // counted. |
5182 if (spin->si_syllable != NULL) | 5181 if (spin->si_syllable != NULL) |
5183 { | 5182 { |
5184 putc(SN_SYLLABLE, fd); /* <sectionID> */ | 5183 putc(SN_SYLLABLE, fd); // <sectionID> |
5185 putc(0, fd); /* <sectionflags> */ | 5184 putc(0, fd); // <sectionflags> |
5186 | 5185 |
5187 l = (int)STRLEN(spin->si_syllable); | 5186 l = (int)STRLEN(spin->si_syllable); |
5188 put_bytes(fd, (long_u)l, 4); /* <sectionlen> */ | 5187 put_bytes(fd, (long_u)l, 4); // <sectionlen> |
5189 fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); | 5188 fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); |
5190 /* <syllable> */ | 5189 // <syllable> |
5191 } | 5190 } |
5192 | 5191 |
5193 /* end of <SECTIONS> */ | 5192 // end of <SECTIONS> |
5194 putc(SN_END, fd); /* <sectionend> */ | 5193 putc(SN_END, fd); // <sectionend> |
5195 | 5194 |
5196 | 5195 |
5197 /* | 5196 /* |
5198 * <LWORDTREE> <KWORDTREE> <PREFIXTREE> | 5197 * <LWORDTREE> <KWORDTREE> <PREFIXTREE> |
5199 */ | 5198 */ |
5205 else if (round == 2) | 5204 else if (round == 2) |
5206 tree = spin->si_keeproot->wn_sibling; | 5205 tree = spin->si_keeproot->wn_sibling; |
5207 else | 5206 else |
5208 tree = spin->si_prefroot->wn_sibling; | 5207 tree = spin->si_prefroot->wn_sibling; |
5209 | 5208 |
5210 /* Clear the index and wnode fields in the tree. */ | 5209 // Clear the index and wnode fields in the tree. |
5211 clear_node(tree); | 5210 clear_node(tree); |
5212 | 5211 |
5213 /* Count the number of nodes. Needed to be able to allocate the | 5212 // Count the number of nodes. Needed to be able to allocate the |
5214 * memory when reading the nodes. Also fills in index for shared | 5213 // memory when reading the nodes. Also fills in index for shared |
5215 * nodes. */ | 5214 // nodes. |
5216 nodecount = put_node(NULL, tree, 0, regionmask, round == 3); | 5215 nodecount = put_node(NULL, tree, 0, regionmask, round == 3); |
5217 | 5216 |
5218 /* number of nodes in 4 bytes */ | 5217 // number of nodes in 4 bytes |
5219 put_bytes(fd, (long_u)nodecount, 4); /* <nodecount> */ | 5218 put_bytes(fd, (long_u)nodecount, 4); // <nodecount> |
5220 spin->si_memtot += nodecount + nodecount * sizeof(int); | 5219 spin->si_memtot += nodecount + nodecount * sizeof(int); |
5221 | 5220 |
5222 /* Write the nodes. */ | 5221 // Write the nodes. |
5223 (void)put_node(fd, tree, 0, regionmask, round == 3); | 5222 (void)put_node(fd, tree, 0, regionmask, round == 3); |
5224 } | 5223 } |
5225 | 5224 |
5226 /* Write another byte to check for errors (file system full). */ | 5225 // Write another byte to check for errors (file system full). |
5227 if (putc(0, fd) == EOF) | 5226 if (putc(0, fd) == EOF) |
5228 retval = FAIL; | 5227 retval = FAIL; |
5229 theend: | 5228 theend: |
5230 if (fclose(fd) == EOF) | 5229 if (fclose(fd) == EOF) |
5231 retval = FAIL; | 5230 retval = FAIL; |
5272 * | 5271 * |
5273 * Returns the number of nodes used. | 5272 * Returns the number of nodes used. |
5274 */ | 5273 */ |
5275 static int | 5274 static int |
5276 put_node( | 5275 put_node( |
5277 FILE *fd, /* NULL when only counting */ | 5276 FILE *fd, // NULL when only counting |
5278 wordnode_T *node, | 5277 wordnode_T *node, |
5279 int idx, | 5278 int idx, |
5280 int regionmask, | 5279 int regionmask, |
5281 int prefixtree) /* TRUE for PREFIXTREE */ | 5280 int prefixtree) // TRUE for PREFIXTREE |
5282 { | 5281 { |
5283 int newindex = idx; | 5282 int newindex = idx; |
5284 int siblingcount = 0; | 5283 int siblingcount = 0; |
5285 wordnode_T *np; | 5284 wordnode_T *np; |
5286 int flags; | 5285 int flags; |
5287 | 5286 |
5288 /* If "node" is zero the tree is empty. */ | 5287 // If "node" is zero the tree is empty. |
5289 if (node == NULL) | 5288 if (node == NULL) |
5290 return 0; | 5289 return 0; |
5291 | 5290 |
5292 /* Store the index where this node is written. */ | 5291 // Store the index where this node is written. |
5293 node->wn_u1.index = idx; | 5292 node->wn_u1.index = idx; |
5294 | 5293 |
5295 /* Count the number of siblings. */ | 5294 // Count the number of siblings. |
5296 for (np = node; np != NULL; np = np->wn_sibling) | 5295 for (np = node; np != NULL; np = np->wn_sibling) |
5297 ++siblingcount; | 5296 ++siblingcount; |
5298 | 5297 |
5299 /* Write the sibling count. */ | 5298 // Write the sibling count. |
5300 if (fd != NULL) | 5299 if (fd != NULL) |
5301 putc(siblingcount, fd); /* <siblingcount> */ | 5300 putc(siblingcount, fd); // <siblingcount> |
5302 | 5301 |
5303 /* Write each sibling byte and optionally extra info. */ | 5302 // Write each sibling byte and optionally extra info. |
5304 for (np = node; np != NULL; np = np->wn_sibling) | 5303 for (np = node; np != NULL; np = np->wn_sibling) |
5305 { | 5304 { |
5306 if (np->wn_byte == 0) | 5305 if (np->wn_byte == 0) |
5307 { | 5306 { |
5308 if (fd != NULL) | 5307 if (fd != NULL) |
5309 { | 5308 { |
5310 /* For a NUL byte (end of word) write the flags etc. */ | 5309 // For a NUL byte (end of word) write the flags etc. |
5311 if (prefixtree) | 5310 if (prefixtree) |
5312 { | 5311 { |
5313 /* In PREFIXTREE write the required affixID and the | 5312 // In PREFIXTREE write the required affixID and the |
5314 * associated condition nr (stored in wn_region). The | 5313 // associated condition nr (stored in wn_region). The |
5315 * byte value is misused to store the "rare" and "not | 5314 // byte value is misused to store the "rare" and "not |
5316 * combining" flags */ | 5315 // combining" flags |
5317 if (np->wn_flags == (short_u)PFX_FLAGS) | 5316 if (np->wn_flags == (short_u)PFX_FLAGS) |
5318 putc(BY_NOFLAGS, fd); /* <byte> */ | 5317 putc(BY_NOFLAGS, fd); // <byte> |
5319 else | 5318 else |
5320 { | 5319 { |
5321 putc(BY_FLAGS, fd); /* <byte> */ | 5320 putc(BY_FLAGS, fd); // <byte> |
5322 putc(np->wn_flags, fd); /* <pflags> */ | 5321 putc(np->wn_flags, fd); // <pflags> |
5323 } | 5322 } |
5324 putc(np->wn_affixID, fd); /* <affixID> */ | 5323 putc(np->wn_affixID, fd); // <affixID> |
5325 put_bytes(fd, (long_u)np->wn_region, 2); /* <prefcondnr> */ | 5324 put_bytes(fd, (long_u)np->wn_region, 2); // <prefcondnr> |
5326 } | 5325 } |
5327 else | 5326 else |
5328 { | 5327 { |
5329 /* For word trees we write the flag/region items. */ | 5328 // For word trees we write the flag/region items. |
5330 flags = np->wn_flags; | 5329 flags = np->wn_flags; |
5331 if (regionmask != 0 && np->wn_region != regionmask) | 5330 if (regionmask != 0 && np->wn_region != regionmask) |
5332 flags |= WF_REGION; | 5331 flags |= WF_REGION; |
5333 if (np->wn_affixID != 0) | 5332 if (np->wn_affixID != 0) |
5334 flags |= WF_AFX; | 5333 flags |= WF_AFX; |
5335 if (flags == 0) | 5334 if (flags == 0) |
5336 { | 5335 { |
5337 /* word without flags or region */ | 5336 // word without flags or region |
5338 putc(BY_NOFLAGS, fd); /* <byte> */ | 5337 putc(BY_NOFLAGS, fd); // <byte> |
5339 } | 5338 } |
5340 else | 5339 else |
5341 { | 5340 { |
5342 if (np->wn_flags >= 0x100) | 5341 if (np->wn_flags >= 0x100) |
5343 { | 5342 { |
5344 putc(BY_FLAGS2, fd); /* <byte> */ | 5343 putc(BY_FLAGS2, fd); // <byte> |
5345 putc(flags, fd); /* <flags> */ | 5344 putc(flags, fd); // <flags> |
5346 putc((unsigned)flags >> 8, fd); /* <flags2> */ | 5345 putc((unsigned)flags >> 8, fd); // <flags2> |
5347 } | 5346 } |
5348 else | 5347 else |
5349 { | 5348 { |
5350 putc(BY_FLAGS, fd); /* <byte> */ | 5349 putc(BY_FLAGS, fd); // <byte> |
5351 putc(flags, fd); /* <flags> */ | 5350 putc(flags, fd); // <flags> |
5352 } | 5351 } |
5353 if (flags & WF_REGION) | 5352 if (flags & WF_REGION) |
5354 putc(np->wn_region, fd); /* <region> */ | 5353 putc(np->wn_region, fd); // <region> |
5355 if (flags & WF_AFX) | 5354 if (flags & WF_AFX) |
5356 putc(np->wn_affixID, fd); /* <affixID> */ | 5355 putc(np->wn_affixID, fd); // <affixID> |
5357 } | 5356 } |
5358 } | 5357 } |
5359 } | 5358 } |
5360 } | 5359 } |
5361 else | 5360 else |
5362 { | 5361 { |
5363 if (np->wn_child->wn_u1.index != 0 | 5362 if (np->wn_child->wn_u1.index != 0 |
5364 && np->wn_child->wn_u2.wnode != node) | 5363 && np->wn_child->wn_u2.wnode != node) |
5365 { | 5364 { |
5366 /* The child is written elsewhere, write the reference. */ | 5365 // The child is written elsewhere, write the reference. |
5367 if (fd != NULL) | 5366 if (fd != NULL) |
5368 { | 5367 { |
5369 putc(BY_INDEX, fd); /* <byte> */ | 5368 putc(BY_INDEX, fd); // <byte> |
5370 /* <nodeidx> */ | 5369 // <nodeidx> |
5371 put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); | 5370 put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); |
5372 } | 5371 } |
5373 } | 5372 } |
5374 else if (np->wn_child->wn_u2.wnode == NULL) | 5373 else if (np->wn_child->wn_u2.wnode == NULL) |
5375 /* We will write the child below and give it an index. */ | 5374 // We will write the child below and give it an index. |
5376 np->wn_child->wn_u2.wnode = node; | 5375 np->wn_child->wn_u2.wnode = node; |
5377 | 5376 |
5378 if (fd != NULL) | 5377 if (fd != NULL) |
5379 if (putc(np->wn_byte, fd) == EOF) /* <byte> or <xbyte> */ | 5378 if (putc(np->wn_byte, fd) == EOF) // <byte> or <xbyte> |
5380 { | 5379 { |
5381 emsg(_(e_write)); | 5380 emsg(_(e_write)); |
5382 return 0; | 5381 return 0; |
5383 } | 5382 } |
5384 } | 5383 } |
5385 } | 5384 } |
5386 | 5385 |
5387 /* Space used in the array when reading: one for each sibling and one for | 5386 // Space used in the array when reading: one for each sibling and one for |
5388 * the count. */ | 5387 // the count. |
5389 newindex += siblingcount + 1; | 5388 newindex += siblingcount + 1; |
5390 | 5389 |
5391 /* Recursively dump the children of each sibling. */ | 5390 // Recursively dump the children of each sibling. |
5392 for (np = node; np != NULL; np = np->wn_sibling) | 5391 for (np = node; np != NULL; np = np->wn_sibling) |
5393 if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) | 5392 if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) |
5394 newindex = put_node(fd, np->wn_child, newindex, regionmask, | 5393 newindex = put_node(fd, np->wn_child, newindex, regionmask, |
5395 prefixtree); | 5394 prefixtree); |
5396 | 5395 |
5414 { | 5413 { |
5415 ascii = TRUE; | 5414 ascii = TRUE; |
5416 arg = skipwhite(arg + 6); | 5415 arg = skipwhite(arg + 6); |
5417 } | 5416 } |
5418 | 5417 |
5419 /* Expand all the remaining arguments (e.g., $VIMRUNTIME). */ | 5418 // Expand all the remaining arguments (e.g., $VIMRUNTIME). |
5420 if (get_arglist_exp(arg, &fcount, &fnames, FALSE) == OK) | 5419 if (get_arglist_exp(arg, &fcount, &fnames, FALSE) == OK) |
5421 { | 5420 { |
5422 mkspell(fcount, fnames, ascii, eap->forceit, FALSE); | 5421 mkspell(fcount, fnames, ascii, eap->forceit, FALSE); |
5423 FreeWild(fcount, fnames); | 5422 FreeWild(fcount, fnames); |
5424 } | 5423 } |
5459 /* | 5458 /* |
5460 * Clear the info in "spin" that is used. | 5459 * Clear the info in "spin" that is used. |
5461 */ | 5460 */ |
5462 spin->si_blocks = NULL; | 5461 spin->si_blocks = NULL; |
5463 spin->si_blocks_cnt = 0; | 5462 spin->si_blocks_cnt = 0; |
5464 spin->si_compress_cnt = 0; /* will stay at 0 all the time*/ | 5463 spin->si_compress_cnt = 0; // will stay at 0 all the time |
5465 spin->si_free_count = 0; | 5464 spin->si_free_count = 0; |
5466 spin->si_first_free = NULL; | 5465 spin->si_first_free = NULL; |
5467 spin->si_foldwcount = 0; | 5466 spin->si_foldwcount = 0; |
5468 | 5467 |
5469 /* | 5468 /* |
5529 int c; | 5528 int c; |
5530 idx_T n; | 5529 idx_T n; |
5531 unsigned words_done = 0; | 5530 unsigned words_done = 0; |
5532 int wordcount[MAXWLEN]; | 5531 int wordcount[MAXWLEN]; |
5533 | 5532 |
5534 /* We use si_foldroot for the soundfolded trie. */ | 5533 // We use si_foldroot for the soundfolded trie. |
5535 spin->si_foldroot = wordtree_alloc(spin); | 5534 spin->si_foldroot = wordtree_alloc(spin); |
5536 if (spin->si_foldroot == NULL) | 5535 if (spin->si_foldroot == NULL) |
5537 return FAIL; | 5536 return FAIL; |
5538 | 5537 |
5539 /* let tree_add_word() know we're adding to the soundfolded tree */ | 5538 // let tree_add_word() know we're adding to the soundfolded tree |
5540 spin->si_sugtree = TRUE; | 5539 spin->si_sugtree = TRUE; |
5541 | 5540 |
5542 /* | 5541 /* |
5543 * Go through the whole case-folded tree, soundfold each word and put it | 5542 * Go through the whole case-folded tree, soundfold each word and put it |
5544 * in the trie. | 5543 * in the trie. |
5553 depth = 0; | 5552 depth = 0; |
5554 while (depth >= 0 && !got_int) | 5553 while (depth >= 0 && !got_int) |
5555 { | 5554 { |
5556 if (curi[depth] > byts[arridx[depth]]) | 5555 if (curi[depth] > byts[arridx[depth]]) |
5557 { | 5556 { |
5558 /* Done all bytes at this node, go up one level. */ | 5557 // Done all bytes at this node, go up one level. |
5559 idxs[arridx[depth]] = wordcount[depth]; | 5558 idxs[arridx[depth]] = wordcount[depth]; |
5560 if (depth > 0) | 5559 if (depth > 0) |
5561 wordcount[depth - 1] += wordcount[depth]; | 5560 wordcount[depth - 1] += wordcount[depth]; |
5562 | 5561 |
5563 --depth; | 5562 --depth; |
5564 line_breakcheck(); | 5563 line_breakcheck(); |
5565 } | 5564 } |
5566 else | 5565 else |
5567 { | 5566 { |
5568 | 5567 |
5569 /* Do one more byte at this node. */ | 5568 // Do one more byte at this node. |
5570 n = arridx[depth] + curi[depth]; | 5569 n = arridx[depth] + curi[depth]; |
5571 ++curi[depth]; | 5570 ++curi[depth]; |
5572 | 5571 |
5573 c = byts[n]; | 5572 c = byts[n]; |
5574 if (c == 0) | 5573 if (c == 0) |
5575 { | 5574 { |
5576 /* Sound-fold the word. */ | 5575 // Sound-fold the word. |
5577 tword[depth] = NUL; | 5576 tword[depth] = NUL; |
5578 spell_soundfold(slang, tword, TRUE, tsalword); | 5577 spell_soundfold(slang, tword, TRUE, tsalword); |
5579 | 5578 |
5580 /* We use the "flags" field for the MSB of the wordnr, | 5579 // We use the "flags" field for the MSB of the wordnr, |
5581 * "region" for the LSB of the wordnr. */ | 5580 // "region" for the LSB of the wordnr. |
5582 if (tree_add_word(spin, tsalword, spin->si_foldroot, | 5581 if (tree_add_word(spin, tsalword, spin->si_foldroot, |
5583 words_done >> 16, words_done & 0xffff, | 5582 words_done >> 16, words_done & 0xffff, |
5584 0) == FAIL) | 5583 0) == FAIL) |
5585 return FAIL; | 5584 return FAIL; |
5586 | 5585 |
5587 ++words_done; | 5586 ++words_done; |
5588 ++wordcount[depth]; | 5587 ++wordcount[depth]; |
5589 | 5588 |
5590 /* Reset the block count each time to avoid compression | 5589 // Reset the block count each time to avoid compression |
5591 * kicking in. */ | 5590 // kicking in. |
5592 spin->si_blocks_cnt = 0; | 5591 spin->si_blocks_cnt = 0; |
5593 | 5592 |
5594 /* Skip over any other NUL bytes (same word with different | 5593 // Skip over any other NUL bytes (same word with different |
5595 * flags). */ | 5594 // flags). |
5596 while (byts[n + 1] == 0) | 5595 while (byts[n + 1] == 0) |
5597 { | 5596 { |
5598 ++n; | 5597 ++n; |
5599 ++curi[depth]; | 5598 ++curi[depth]; |
5600 } | 5599 } |
5601 } | 5600 } |
5602 else | 5601 else |
5603 { | 5602 { |
5604 /* Normal char, go one level deeper. */ | 5603 // Normal char, go one level deeper. |
5605 tword[depth++] = c; | 5604 tword[depth++] = c; |
5606 arridx[depth] = idxs[n]; | 5605 arridx[depth] = idxs[n]; |
5607 curi[depth] = 1; | 5606 curi[depth] = 1; |
5608 wordcount[depth] = 0; | 5607 wordcount[depth] = 0; |
5609 } | 5608 } |
5626 sug_maketable(spellinfo_T *spin) | 5625 sug_maketable(spellinfo_T *spin) |
5627 { | 5626 { |
5628 garray_T ga; | 5627 garray_T ga; |
5629 int res = OK; | 5628 int res = OK; |
5630 | 5629 |
5631 /* Allocate a buffer, open a memline for it and create the swap file | 5630 // Allocate a buffer, open a memline for it and create the swap file |
5632 * (uses a temp file, not a .swp file). */ | 5631 // (uses a temp file, not a .swp file). |
5633 spin->si_spellbuf = open_spellbuf(); | 5632 spin->si_spellbuf = open_spellbuf(); |
5634 if (spin->si_spellbuf == NULL) | 5633 if (spin->si_spellbuf == NULL) |
5635 return FAIL; | 5634 return FAIL; |
5636 | 5635 |
5637 /* Use a buffer to store the line info, avoids allocating many small | 5636 // Use a buffer to store the line info, avoids allocating many small |
5638 * pieces of memory. */ | 5637 // pieces of memory. |
5639 ga_init2(&ga, 1, 100); | 5638 ga_init2(&ga, 1, 100); |
5640 | 5639 |
5641 /* recursively go through the tree */ | 5640 // recursively go through the tree |
5642 if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) | 5641 if (sug_filltable(spin, spin->si_foldroot->wn_sibling, 0, &ga) == -1) |
5643 res = FAIL; | 5642 res = FAIL; |
5644 | 5643 |
5645 ga_clear(&ga); | 5644 ga_clear(&ga); |
5646 return res; | 5645 return res; |
5654 static int | 5653 static int |
5655 sug_filltable( | 5654 sug_filltable( |
5656 spellinfo_T *spin, | 5655 spellinfo_T *spin, |
5657 wordnode_T *node, | 5656 wordnode_T *node, |
5658 int startwordnr, | 5657 int startwordnr, |
5659 garray_T *gap) /* place to store line of numbers */ | 5658 garray_T *gap) // place to store line of numbers |
5660 { | 5659 { |
5661 wordnode_T *p, *np; | 5660 wordnode_T *p, *np; |
5662 int wordnr = startwordnr; | 5661 int wordnr = startwordnr; |
5663 int nr; | 5662 int nr; |
5664 int prev_nr; | 5663 int prev_nr; |
5673 { | 5672 { |
5674 if (ga_grow(gap, 10) == FAIL) | 5673 if (ga_grow(gap, 10) == FAIL) |
5675 return -1; | 5674 return -1; |
5676 | 5675 |
5677 nr = (np->wn_flags << 16) + (np->wn_region & 0xffff); | 5676 nr = (np->wn_flags << 16) + (np->wn_region & 0xffff); |
5678 /* Compute the offset from the previous nr and store the | 5677 // Compute the offset from the previous nr and store the |
5679 * offset in a way that it takes a minimum number of bytes. | 5678 // offset in a way that it takes a minimum number of bytes. |
5680 * It's a bit like utf-8, but without the need to mark | 5679 // It's a bit like utf-8, but without the need to mark |
5681 * following bytes. */ | 5680 // following bytes. |
5682 nr -= prev_nr; | 5681 nr -= prev_nr; |
5683 prev_nr += nr; | 5682 prev_nr += nr; |
5684 gap->ga_len += offset2bytes(nr, | 5683 gap->ga_len += offset2bytes(nr, |
5685 (char_u *)gap->ga_data + gap->ga_len); | 5684 (char_u *)gap->ga_data + gap->ga_len); |
5686 } | 5685 } |
5687 | 5686 |
5688 /* add the NUL byte */ | 5687 // add the NUL byte |
5689 ((char_u *)gap->ga_data)[gap->ga_len++] = NUL; | 5688 ((char_u *)gap->ga_data)[gap->ga_len++] = NUL; |
5690 | 5689 |
5691 if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr, | 5690 if (ml_append_buf(spin->si_spellbuf, (linenr_T)wordnr, |
5692 gap->ga_data, gap->ga_len, TRUE) == FAIL) | 5691 gap->ga_data, gap->ga_len, TRUE) == FAIL) |
5693 return -1; | 5692 return -1; |
5694 ++wordnr; | 5693 ++wordnr; |
5695 | 5694 |
5696 /* Remove extra NUL entries, we no longer need them. We don't | 5695 // Remove extra NUL entries, we no longer need them. We don't |
5697 * bother freeing the nodes, the won't be reused anyway. */ | 5696 // bother freeing the nodes, the won't be reused anyway. |
5698 while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) | 5697 while (p->wn_sibling != NULL && p->wn_sibling->wn_byte == NUL) |
5699 p->wn_sibling = p->wn_sibling->wn_sibling; | 5698 p->wn_sibling = p->wn_sibling->wn_sibling; |
5700 | 5699 |
5701 /* Clear the flags on the remaining NUL node, so that compression | 5700 // Clear the flags on the remaining NUL node, so that compression |
5702 * works a lot better. */ | 5701 // works a lot better. |
5703 p->wn_flags = 0; | 5702 p->wn_flags = 0; |
5704 p->wn_region = 0; | 5703 p->wn_region = 0; |
5705 } | 5704 } |
5706 else | 5705 else |
5707 { | 5706 { |
5722 offset2bytes(int nr, char_u *buf) | 5721 offset2bytes(int nr, char_u *buf) |
5723 { | 5722 { |
5724 int rem; | 5723 int rem; |
5725 int b1, b2, b3, b4; | 5724 int b1, b2, b3, b4; |
5726 | 5725 |
5727 /* Split the number in parts of base 255. We need to avoid NUL bytes. */ | 5726 // Split the number in parts of base 255. We need to avoid NUL bytes. |
5728 b1 = nr % 255 + 1; | 5727 b1 = nr % 255 + 1; |
5729 rem = nr / 255; | 5728 rem = nr / 255; |
5730 b2 = rem % 255 + 1; | 5729 b2 = rem % 255 + 1; |
5731 rem = rem / 255; | 5730 rem = rem / 255; |
5732 b3 = rem % 255 + 1; | 5731 b3 = rem % 255 + 1; |
5733 b4 = rem / 255 + 1; | 5732 b4 = rem / 255 + 1; |
5734 | 5733 |
5735 if (b4 > 1 || b3 > 0x1f) /* 4 bytes */ | 5734 if (b4 > 1 || b3 > 0x1f) // 4 bytes |
5736 { | 5735 { |
5737 buf[0] = 0xe0 + b4; | 5736 buf[0] = 0xe0 + b4; |
5738 buf[1] = b3; | 5737 buf[1] = b3; |
5739 buf[2] = b2; | 5738 buf[2] = b2; |
5740 buf[3] = b1; | 5739 buf[3] = b1; |
5741 return 4; | 5740 return 4; |
5742 } | 5741 } |
5743 if (b3 > 1 || b2 > 0x3f ) /* 3 bytes */ | 5742 if (b3 > 1 || b2 > 0x3f ) // 3 bytes |
5744 { | 5743 { |
5745 buf[0] = 0xc0 + b3; | 5744 buf[0] = 0xc0 + b3; |
5746 buf[1] = b2; | 5745 buf[1] = b2; |
5747 buf[2] = b1; | 5746 buf[2] = b1; |
5748 return 3; | 5747 return 3; |
5749 } | 5748 } |
5750 if (b2 > 1 || b1 > 0x7f ) /* 2 bytes */ | 5749 if (b2 > 1 || b1 > 0x7f ) // 2 bytes |
5751 { | 5750 { |
5752 buf[0] = 0x80 + b2; | 5751 buf[0] = 0x80 + b2; |
5753 buf[1] = b1; | 5752 buf[1] = b1; |
5754 return 2; | 5753 return 2; |
5755 } | 5754 } |
5756 /* 1 byte */ | 5755 // 1 byte |
5757 buf[0] = b1; | 5756 buf[0] = b1; |
5758 return 1; | 5757 return 1; |
5759 } | 5758 } |
5760 | 5759 |
5761 /* | 5760 /* |
5770 int wcount; | 5769 int wcount; |
5771 char_u *line; | 5770 char_u *line; |
5772 linenr_T lnum; | 5771 linenr_T lnum; |
5773 int len; | 5772 int len; |
5774 | 5773 |
5775 /* Create the file. Note that an existing file is silently overwritten! */ | 5774 // Create the file. Note that an existing file is silently overwritten! |
5776 fd = mch_fopen((char *)fname, "w"); | 5775 fd = mch_fopen((char *)fname, "w"); |
5777 if (fd == NULL) | 5776 if (fd == NULL) |
5778 { | 5777 { |
5779 semsg(_(e_notopen), fname); | 5778 semsg(_(e_notopen), fname); |
5780 return; | 5779 return; |
5785 spell_message(spin, IObuff); | 5784 spell_message(spin, IObuff); |
5786 | 5785 |
5787 /* | 5786 /* |
5788 * <SUGHEADER>: <fileID> <versionnr> <timestamp> | 5787 * <SUGHEADER>: <fileID> <versionnr> <timestamp> |
5789 */ | 5788 */ |
5790 if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) /* <fileID> */ | 5789 if (fwrite(VIMSUGMAGIC, VIMSUGMAGICL, (size_t)1, fd) != 1) // <fileID> |
5791 { | 5790 { |
5792 emsg(_(e_write)); | 5791 emsg(_(e_write)); |
5793 goto theend; | 5792 goto theend; |
5794 } | 5793 } |
5795 putc(VIMSUGVERSION, fd); /* <versionnr> */ | 5794 putc(VIMSUGVERSION, fd); // <versionnr> |
5796 | 5795 |
5797 /* Write si_sugtime to the file. */ | 5796 // Write si_sugtime to the file. |
5798 put_time(fd, spin->si_sugtime); /* <timestamp> */ | 5797 put_time(fd, spin->si_sugtime); // <timestamp> |
5799 | 5798 |
5800 /* | 5799 /* |
5801 * <SUGWORDTREE> | 5800 * <SUGWORDTREE> |
5802 */ | 5801 */ |
5803 spin->si_memtot = 0; | 5802 spin->si_memtot = 0; |
5804 tree = spin->si_foldroot->wn_sibling; | 5803 tree = spin->si_foldroot->wn_sibling; |
5805 | 5804 |
5806 /* Clear the index and wnode fields in the tree. */ | 5805 // Clear the index and wnode fields in the tree. |
5807 clear_node(tree); | 5806 clear_node(tree); |
5808 | 5807 |
5809 /* Count the number of nodes. Needed to be able to allocate the | 5808 // Count the number of nodes. Needed to be able to allocate the |
5810 * memory when reading the nodes. Also fills in index for shared | 5809 // memory when reading the nodes. Also fills in index for shared |
5811 * nodes. */ | 5810 // nodes. |
5812 nodecount = put_node(NULL, tree, 0, 0, FALSE); | 5811 nodecount = put_node(NULL, tree, 0, 0, FALSE); |
5813 | 5812 |
5814 /* number of nodes in 4 bytes */ | 5813 // number of nodes in 4 bytes |
5815 put_bytes(fd, (long_u)nodecount, 4); /* <nodecount> */ | 5814 put_bytes(fd, (long_u)nodecount, 4); // <nodecount> |
5816 spin->si_memtot += nodecount + nodecount * sizeof(int); | 5815 spin->si_memtot += nodecount + nodecount * sizeof(int); |
5817 | 5816 |
5818 /* Write the nodes. */ | 5817 // Write the nodes. |
5819 (void)put_node(fd, tree, 0, 0, FALSE); | 5818 (void)put_node(fd, tree, 0, 0, FALSE); |
5820 | 5819 |
5821 /* | 5820 /* |
5822 * <SUGTABLE>: <sugwcount> <sugline> ... | 5821 * <SUGTABLE>: <sugwcount> <sugline> ... |
5823 */ | 5822 */ |
5824 wcount = spin->si_spellbuf->b_ml.ml_line_count; | 5823 wcount = spin->si_spellbuf->b_ml.ml_line_count; |
5825 put_bytes(fd, (long_u)wcount, 4); /* <sugwcount> */ | 5824 put_bytes(fd, (long_u)wcount, 4); // <sugwcount> |
5826 | 5825 |
5827 for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) | 5826 for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) |
5828 { | 5827 { |
5829 /* <sugline>: <sugnr> ... NUL */ | 5828 // <sugline>: <sugnr> ... NUL |
5830 line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); | 5829 line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); |
5831 len = (int)STRLEN(line) + 1; | 5830 len = (int)STRLEN(line) + 1; |
5832 if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) | 5831 if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) |
5833 { | 5832 { |
5834 emsg(_(e_write)); | 5833 emsg(_(e_write)); |
5835 goto theend; | 5834 goto theend; |
5836 } | 5835 } |
5837 spin->si_memtot += len; | 5836 spin->si_memtot += len; |
5838 } | 5837 } |
5839 | 5838 |
5840 /* Write another byte to check for errors. */ | 5839 // Write another byte to check for errors. |
5841 if (putc(0, fd) == EOF) | 5840 if (putc(0, fd) == EOF) |
5842 emsg(_(e_write)); | 5841 emsg(_(e_write)); |
5843 | 5842 |
5844 vim_snprintf((char *)IObuff, IOSIZE, | 5843 vim_snprintf((char *)IObuff, IOSIZE, |
5845 _("Estimated runtime memory use: %d bytes"), spin->si_memtot); | 5844 _("Estimated runtime memory use: %d bytes"), spin->si_memtot); |
5846 spell_message(spin, IObuff); | 5845 spell_message(spin, IObuff); |
5847 | 5846 |
5848 theend: | 5847 theend: |
5849 /* close the file */ | 5848 // close the file |
5850 fclose(fd); | 5849 fclose(fd); |
5851 } | 5850 } |
5852 | 5851 |
5853 | 5852 |
5854 /* | 5853 /* |
5860 */ | 5859 */ |
5861 void | 5860 void |
5862 mkspell( | 5861 mkspell( |
5863 int fcount, | 5862 int fcount, |
5864 char_u **fnames, | 5863 char_u **fnames, |
5865 int ascii, /* -ascii argument given */ | 5864 int ascii, // -ascii argument given |
5866 int over_write, /* overwrite existing output file */ | 5865 int over_write, // overwrite existing output file |
5867 int added_word) /* invoked through "zg" */ | 5866 int added_word) // invoked through "zg" |
5868 { | 5867 { |
5869 char_u *fname = NULL; | 5868 char_u *fname = NULL; |
5870 char_u *wfname; | 5869 char_u *wfname; |
5871 char_u **innames; | 5870 char_u **innames; |
5872 int incount; | 5871 int incount; |
5887 ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20); | 5886 ga_init2(&spin.si_sal, (int)sizeof(fromto_T), 20); |
5888 ga_init2(&spin.si_map, (int)sizeof(char_u), 100); | 5887 ga_init2(&spin.si_map, (int)sizeof(char_u), 100); |
5889 ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20); | 5888 ga_init2(&spin.si_comppat, (int)sizeof(char_u *), 20); |
5890 ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50); | 5889 ga_init2(&spin.si_prefcond, (int)sizeof(char_u *), 50); |
5891 hash_init(&spin.si_commonwords); | 5890 hash_init(&spin.si_commonwords); |
5892 spin.si_newcompID = 127; /* start compound ID at first maximum */ | 5891 spin.si_newcompID = 127; // start compound ID at first maximum |
5893 | 5892 |
5894 /* default: fnames[0] is output file, following are input files */ | 5893 // default: fnames[0] is output file, following are input files |
5895 innames = &fnames[1]; | 5894 innames = &fnames[1]; |
5896 incount = fcount - 1; | 5895 incount = fcount - 1; |
5897 | 5896 |
5898 wfname = alloc(MAXPATHL); | 5897 wfname = alloc(MAXPATHL); |
5899 if (wfname == NULL) | 5898 if (wfname == NULL) |
5902 if (fcount >= 1) | 5901 if (fcount >= 1) |
5903 { | 5902 { |
5904 len = (int)STRLEN(fnames[0]); | 5903 len = (int)STRLEN(fnames[0]); |
5905 if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) | 5904 if (fcount == 1 && len > 4 && STRCMP(fnames[0] + len - 4, ".add") == 0) |
5906 { | 5905 { |
5907 /* For ":mkspell path/en.latin1.add" output file is | 5906 // For ":mkspell path/en.latin1.add" output file is |
5908 * "path/en.latin1.add.spl". */ | 5907 // "path/en.latin1.add.spl". |
5909 innames = &fnames[0]; | 5908 innames = &fnames[0]; |
5910 incount = 1; | 5909 incount = 1; |
5911 vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); | 5910 vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]); |
5912 } | 5911 } |
5913 else if (fcount == 1) | 5912 else if (fcount == 1) |
5914 { | 5913 { |
5915 /* For ":mkspell path/vim" output file is "path/vim.latin1.spl". */ | 5914 // For ":mkspell path/vim" output file is "path/vim.latin1.spl". |
5916 innames = &fnames[0]; | 5915 innames = &fnames[0]; |
5917 incount = 1; | 5916 incount = 1; |
5918 vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, | 5917 vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, |
5919 fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); | 5918 fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); |
5920 } | 5919 } |
5921 else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) | 5920 else if (len > 4 && STRCMP(fnames[0] + len - 4, ".spl") == 0) |
5922 { | 5921 { |
5923 /* Name ends in ".spl", use as the file name. */ | 5922 // Name ends in ".spl", use as the file name. |
5924 vim_strncpy(wfname, fnames[0], MAXPATHL - 1); | 5923 vim_strncpy(wfname, fnames[0], MAXPATHL - 1); |
5925 } | 5924 } |
5926 else | 5925 else |
5927 /* Name should be language, make the file name from it. */ | 5926 // Name should be language, make the file name from it. |
5928 vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, | 5927 vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL, |
5929 fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); | 5928 fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc()); |
5930 | 5929 |
5931 /* Check for .ascii.spl. */ | 5930 // Check for .ascii.spl. |
5932 if (strstr((char *)gettail(wfname), SPL_FNAME_ASCII) != NULL) | 5931 if (strstr((char *)gettail(wfname), SPL_FNAME_ASCII) != NULL) |
5933 spin.si_ascii = TRUE; | 5932 spin.si_ascii = TRUE; |
5934 | 5933 |
5935 /* Check for .add.spl. */ | 5934 // Check for .add.spl. |
5936 if (strstr((char *)gettail(wfname), SPL_FNAME_ADD) != NULL) | 5935 if (strstr((char *)gettail(wfname), SPL_FNAME_ADD) != NULL) |
5937 spin.si_add = TRUE; | 5936 spin.si_add = TRUE; |
5938 } | 5937 } |
5939 | 5938 |
5940 if (incount <= 0) | 5939 if (incount <= 0) |
5941 emsg(_(e_invarg)); /* need at least output and input names */ | 5940 emsg(_(e_invarg)); // need at least output and input names |
5942 else if (vim_strchr(gettail(wfname), '_') != NULL) | 5941 else if (vim_strchr(gettail(wfname), '_') != NULL) |
5943 emsg(_("E751: Output file name must not have region name")); | 5942 emsg(_("E751: Output file name must not have region name")); |
5944 else if (incount > MAXREGIONS) | 5943 else if (incount > MAXREGIONS) |
5945 semsg(_("E754: Only up to %d regions supported"), MAXREGIONS); | 5944 semsg(_("E754: Only up to %d regions supported"), MAXREGIONS); |
5946 else | 5945 else |
5947 { | 5946 { |
5948 /* Check for overwriting before doing things that may take a lot of | 5947 // Check for overwriting before doing things that may take a lot of |
5949 * time. */ | 5948 // time. |
5950 if (!over_write && mch_stat((char *)wfname, &st) >= 0) | 5949 if (!over_write && mch_stat((char *)wfname, &st) >= 0) |
5951 { | 5950 { |
5952 emsg(_(e_exists)); | 5951 emsg(_(e_exists)); |
5953 goto theend; | 5952 goto theend; |
5954 } | 5953 } |
5995 { | 5994 { |
5996 free_blocks(spin.si_blocks); | 5995 free_blocks(spin.si_blocks); |
5997 goto theend; | 5996 goto theend; |
5998 } | 5997 } |
5999 | 5998 |
6000 /* When not producing a .add.spl file clear the character table when | 5999 // When not producing a .add.spl file clear the character table when |
6001 * we encounter one in the .aff file. This means we dump the current | 6000 // we encounter one in the .aff file. This means we dump the current |
6002 * one in the .spl file if the .aff file doesn't define one. That's | 6001 // one in the .spl file if the .aff file doesn't define one. That's |
6003 * better than guessing the contents, the table will match a | 6002 // better than guessing the contents, the table will match a |
6004 * previously loaded spell file. */ | 6003 // previously loaded spell file. |
6005 if (!spin.si_add) | 6004 if (!spin.si_add) |
6006 spin.si_clear_chartab = TRUE; | 6005 spin.si_clear_chartab = TRUE; |
6007 | 6006 |
6008 /* | 6007 /* |
6009 * Read all the .aff and .dic files. | 6008 * Read all the .aff and .dic files. |
6016 spin.si_region = 1 << i; | 6015 spin.si_region = 1 << i; |
6017 | 6016 |
6018 vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]); | 6017 vim_snprintf((char *)fname, MAXPATHL, "%s.aff", innames[i]); |
6019 if (mch_stat((char *)fname, &st) >= 0) | 6018 if (mch_stat((char *)fname, &st) >= 0) |
6020 { | 6019 { |
6021 /* Read the .aff file. Will init "spin->si_conv" based on the | 6020 // Read the .aff file. Will init "spin->si_conv" based on the |
6022 * "SET" line. */ | 6021 // "SET" line. |
6023 afile[i] = spell_read_aff(&spin, fname); | 6022 afile[i] = spell_read_aff(&spin, fname); |
6024 if (afile[i] == NULL) | 6023 if (afile[i] == NULL) |
6025 error = TRUE; | 6024 error = TRUE; |
6026 else | 6025 else |
6027 { | 6026 { |
6028 /* Read the .dic file and store the words in the trees. */ | 6027 // Read the .dic file and store the words in the trees. |
6029 vim_snprintf((char *)fname, MAXPATHL, "%s.dic", | 6028 vim_snprintf((char *)fname, MAXPATHL, "%s.dic", |
6030 innames[i]); | 6029 innames[i]); |
6031 if (spell_read_dic(&spin, fname, afile[i]) == FAIL) | 6030 if (spell_read_dic(&spin, fname, afile[i]) == FAIL) |
6032 error = TRUE; | 6031 error = TRUE; |
6033 } | 6032 } |
6034 } | 6033 } |
6035 else | 6034 else |
6036 { | 6035 { |
6037 /* No .aff file, try reading the file as a word list. Store | 6036 // No .aff file, try reading the file as a word list. Store |
6038 * the words in the trees. */ | 6037 // the words in the trees. |
6039 if (spell_read_wordfile(&spin, innames[i]) == FAIL) | 6038 if (spell_read_wordfile(&spin, innames[i]) == FAIL) |
6040 error = TRUE; | 6039 error = TRUE; |
6041 } | 6040 } |
6042 | 6041 |
6043 /* Free any conversion stuff. */ | 6042 // Free any conversion stuff. |
6044 convert_setup(&spin.si_conv, NULL, NULL); | 6043 convert_setup(&spin.si_conv, NULL, NULL); |
6045 } | 6044 } |
6046 | 6045 |
6047 if (spin.si_compflags != NULL && spin.si_nobreak) | 6046 if (spin.si_compflags != NULL && spin.si_nobreak) |
6048 msg(_("Warning: both compounding and NOBREAK specified")); | 6047 msg(_("Warning: both compounding and NOBREAK specified")); |
6079 */ | 6078 */ |
6080 if (!error) | 6079 if (!error) |
6081 spell_reload_one(wfname, added_word); | 6080 spell_reload_one(wfname, added_word); |
6082 } | 6081 } |
6083 | 6082 |
6084 /* Free the allocated memory. */ | 6083 // Free the allocated memory. |
6085 ga_clear(&spin.si_rep); | 6084 ga_clear(&spin.si_rep); |
6086 ga_clear(&spin.si_repsal); | 6085 ga_clear(&spin.si_repsal); |
6087 ga_clear(&spin.si_sal); | 6086 ga_clear(&spin.si_sal); |
6088 ga_clear(&spin.si_map); | 6087 ga_clear(&spin.si_map); |
6089 ga_clear(&spin.si_comppat); | 6088 ga_clear(&spin.si_comppat); |
6090 ga_clear(&spin.si_prefcond); | 6089 ga_clear(&spin.si_prefcond); |
6091 hash_clear_all(&spin.si_commonwords, 0); | 6090 hash_clear_all(&spin.si_commonwords, 0); |
6092 | 6091 |
6093 /* Free the .aff file structures. */ | 6092 // Free the .aff file structures. |
6094 for (i = 0; i < incount; ++i) | 6093 for (i = 0; i < incount; ++i) |
6095 if (afile[i] != NULL) | 6094 if (afile[i] != NULL) |
6096 spell_free_aff(afile[i]); | 6095 spell_free_aff(afile[i]); |
6097 | 6096 |
6098 /* Free all the bits and pieces at once. */ | 6097 // Free all the bits and pieces at once. |
6099 free_blocks(spin.si_blocks); | 6098 free_blocks(spin.si_blocks); |
6100 | 6099 |
6101 /* | 6100 /* |
6102 * If there is soundfolding info and no NOSUGFILE item create the | 6101 * If there is soundfolding info and no NOSUGFILE item create the |
6103 * .sug file with the soundfolded word trie. | 6102 * .sug file with the soundfolded word trie. |
6166 char_u line[MAXWLEN * 2]; | 6165 char_u line[MAXWLEN * 2]; |
6167 long fpos, fpos_next = 0; | 6166 long fpos, fpos_next = 0; |
6168 int i; | 6167 int i; |
6169 char_u *spf; | 6168 char_u *spf; |
6170 | 6169 |
6171 if (idx == 0) /* use internal wordlist */ | 6170 if (idx == 0) // use internal wordlist |
6172 { | 6171 { |
6173 if (int_wordlist == NULL) | 6172 if (int_wordlist == NULL) |
6174 { | 6173 { |
6175 int_wordlist = vim_tempname('s', FALSE); | 6174 int_wordlist = vim_tempname('s', FALSE); |
6176 if (int_wordlist == NULL) | 6175 if (int_wordlist == NULL) |
6178 } | 6177 } |
6179 fname = int_wordlist; | 6178 fname = int_wordlist; |
6180 } | 6179 } |
6181 else | 6180 else |
6182 { | 6181 { |
6183 /* If 'spellfile' isn't set figure out a good default value. */ | 6182 // If 'spellfile' isn't set figure out a good default value. |
6184 if (*curwin->w_s->b_p_spf == NUL) | 6183 if (*curwin->w_s->b_p_spf == NUL) |
6185 { | 6184 { |
6186 init_spellfile(); | 6185 init_spellfile(); |
6187 new_spf = TRUE; | 6186 new_spf = TRUE; |
6188 } | 6187 } |
6207 vim_free(fnamebuf); | 6206 vim_free(fnamebuf); |
6208 return; | 6207 return; |
6209 } | 6208 } |
6210 } | 6209 } |
6211 | 6210 |
6212 /* Check that the user isn't editing the .add file somewhere. */ | 6211 // Check that the user isn't editing the .add file somewhere. |
6213 buf = buflist_findname_exp(fnamebuf); | 6212 buf = buflist_findname_exp(fnamebuf); |
6214 if (buf != NULL && buf->b_ml.ml_mfp == NULL) | 6213 if (buf != NULL && buf->b_ml.ml_mfp == NULL) |
6215 buf = NULL; | 6214 buf = NULL; |
6216 if (buf != NULL && bufIsChanged(buf)) | 6215 if (buf != NULL && bufIsChanged(buf)) |
6217 { | 6216 { |
6223 fname = fnamebuf; | 6222 fname = fnamebuf; |
6224 } | 6223 } |
6225 | 6224 |
6226 if (what == SPELL_ADD_BAD || undo) | 6225 if (what == SPELL_ADD_BAD || undo) |
6227 { | 6226 { |
6228 /* When the word appears as good word we need to remove that one, | 6227 // When the word appears as good word we need to remove that one, |
6229 * since its flags sort before the one with WF_BANNED. */ | 6228 // since its flags sort before the one with WF_BANNED. |
6230 fd = mch_fopen((char *)fname, "r"); | 6229 fd = mch_fopen((char *)fname, "r"); |
6231 if (fd != NULL) | 6230 if (fd != NULL) |
6232 { | 6231 { |
6233 while (!vim_fgets(line, MAXWLEN * 2, fd)) | 6232 while (!vim_fgets(line, MAXWLEN * 2, fd)) |
6234 { | 6233 { |
6235 fpos = fpos_next; | 6234 fpos = fpos_next; |
6236 fpos_next = ftell(fd); | 6235 fpos_next = ftell(fd); |
6237 if (STRNCMP(word, line, len) == 0 | 6236 if (STRNCMP(word, line, len) == 0 |
6238 && (line[len] == '/' || line[len] < ' ')) | 6237 && (line[len] == '/' || line[len] < ' ')) |
6239 { | 6238 { |
6240 /* Found duplicate word. Remove it by writing a '#' at | 6239 // Found duplicate word. Remove it by writing a '#' at |
6241 * the start of the line. Mixing reading and writing | 6240 // the start of the line. Mixing reading and writing |
6242 * doesn't work for all systems, close the file first. */ | 6241 // doesn't work for all systems, close the file first. |
6243 fclose(fd); | 6242 fclose(fd); |
6244 fd = mch_fopen((char *)fname, "r+"); | 6243 fd = mch_fopen((char *)fname, "r+"); |
6245 if (fd == NULL) | 6244 if (fd == NULL) |
6246 break; | 6245 break; |
6247 if (fseek(fd, fpos, SEEK_SET) == 0) | 6246 if (fseek(fd, fpos, SEEK_SET) == 0) |
6267 fd = mch_fopen((char *)fname, "a"); | 6266 fd = mch_fopen((char *)fname, "a"); |
6268 if (fd == NULL && new_spf) | 6267 if (fd == NULL && new_spf) |
6269 { | 6268 { |
6270 char_u *p; | 6269 char_u *p; |
6271 | 6270 |
6272 /* We just initialized the 'spellfile' option and can't open the | 6271 // We just initialized the 'spellfile' option and can't open the |
6273 * file. We may need to create the "spell" directory first. We | 6272 // file. We may need to create the "spell" directory first. We |
6274 * already checked the runtime directory is writable in | 6273 // already checked the runtime directory is writable in |
6275 * init_spellfile(). */ | 6274 // init_spellfile(). |
6276 if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) | 6275 if (!dir_of_file_exists(fname) && (p = gettail_sep(fname)) != fname) |
6277 { | 6276 { |
6278 int c = *p; | 6277 int c = *p; |
6279 | 6278 |
6280 /* The directory doesn't exist. Try creating it and opening | 6279 // The directory doesn't exist. Try creating it and opening |
6281 * the file again. */ | 6280 // the file again. |
6282 *p = NUL; | 6281 *p = NUL; |
6283 vim_mkdir(fname, 0755); | 6282 vim_mkdir(fname, 0755); |
6284 *p = c; | 6283 *p = c; |
6285 fd = mch_fopen((char *)fname, "a"); | 6284 fd = mch_fopen((char *)fname, "a"); |
6286 } | 6285 } |
6303 } | 6302 } |
6304 } | 6303 } |
6305 | 6304 |
6306 if (fd != NULL) | 6305 if (fd != NULL) |
6307 { | 6306 { |
6308 /* Update the .add.spl file. */ | 6307 // Update the .add.spl file. |
6309 mkspell(1, &fname, FALSE, TRUE, TRUE); | 6308 mkspell(1, &fname, FALSE, TRUE, TRUE); |
6310 | 6309 |
6311 /* If the .add file is edited somewhere, reload it. */ | 6310 // If the .add file is edited somewhere, reload it. |
6312 if (buf != NULL) | 6311 if (buf != NULL) |
6313 buf_reload(buf, buf->b_orig_mode); | 6312 buf_reload(buf, buf->b_orig_mode); |
6314 | 6313 |
6315 redraw_all_later(SOME_VALID); | 6314 redraw_all_later(SOME_VALID); |
6316 } | 6315 } |
6335 { | 6334 { |
6336 buf = alloc(MAXPATHL); | 6335 buf = alloc(MAXPATHL); |
6337 if (buf == NULL) | 6336 if (buf == NULL) |
6338 return; | 6337 return; |
6339 | 6338 |
6340 /* Find the end of the language name. Exclude the region. If there | 6339 // Find the end of the language name. Exclude the region. If there |
6341 * is a path separator remember the start of the tail. */ | 6340 // is a path separator remember the start of the tail. |
6342 for (lend = curwin->w_s->b_p_spl; *lend != NUL | 6341 for (lend = curwin->w_s->b_p_spl; *lend != NUL |
6343 && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) | 6342 && vim_strchr((char_u *)",._", *lend) == NULL; ++lend) |
6344 if (vim_ispathsep(*lend)) | 6343 if (vim_ispathsep(*lend)) |
6345 { | 6344 { |
6346 aspath = TRUE; | 6345 aspath = TRUE; |
6347 lstart = lend + 1; | 6346 lstart = lend + 1; |
6348 } | 6347 } |
6349 | 6348 |
6350 /* Loop over all entries in 'runtimepath'. Use the first one where we | 6349 // Loop over all entries in 'runtimepath'. Use the first one where we |
6351 * are allowed to write. */ | 6350 // are allowed to write. |
6352 rtp = p_rtp; | 6351 rtp = p_rtp; |
6353 while (*rtp != NUL) | 6352 while (*rtp != NUL) |
6354 { | 6353 { |
6355 if (aspath) | 6354 if (aspath) |
6356 /* Use directory of an entry with path, e.g., for | 6355 // Use directory of an entry with path, e.g., for |
6357 * "/dir/lg.utf-8.spl" use "/dir". */ | 6356 // "/dir/lg.utf-8.spl" use "/dir". |
6358 vim_strncpy(buf, curbuf->b_s.b_p_spl, | 6357 vim_strncpy(buf, curbuf->b_s.b_p_spl, |
6359 lstart - curbuf->b_s.b_p_spl - 1); | 6358 lstart - curbuf->b_s.b_p_spl - 1); |
6360 else | 6359 else |
6361 /* Copy the path from 'runtimepath' to buf[]. */ | 6360 // Copy the path from 'runtimepath' to buf[]. |
6362 copy_option_part(&rtp, buf, MAXPATHL, ","); | 6361 copy_option_part(&rtp, buf, MAXPATHL, ","); |
6363 if (filewritable(buf) == 2) | 6362 if (filewritable(buf) == 2) |
6364 { | 6363 { |
6365 /* Use the first language name from 'spelllang' and the | 6364 // Use the first language name from 'spelllang' and the |
6366 * encoding used in the first loaded .spl file. */ | 6365 // encoding used in the first loaded .spl file. |
6367 if (aspath) | 6366 if (aspath) |
6368 vim_strncpy(buf, curbuf->b_s.b_p_spl, | 6367 vim_strncpy(buf, curbuf->b_s.b_p_spl, |
6369 lend - curbuf->b_s.b_p_spl); | 6368 lend - curbuf->b_s.b_p_spl); |
6370 else | 6369 else |
6371 { | 6370 { |
6372 /* Create the "spell" directory if it doesn't exist yet. */ | 6371 // Create the "spell" directory if it doesn't exist yet. |
6373 l = (int)STRLEN(buf); | 6372 l = (int)STRLEN(buf); |
6374 vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); | 6373 vim_snprintf((char *)buf + l, MAXPATHL - l, "/spell"); |
6375 if (filewritable(buf) != 2) | 6374 if (filewritable(buf) != 2) |
6376 vim_mkdir(buf, 0755); | 6375 vim_mkdir(buf, 0755); |
6377 | 6376 |
6402 * Set the spell character tables from strings in the affix file. | 6401 * Set the spell character tables from strings in the affix file. |
6403 */ | 6402 */ |
6404 static int | 6403 static int |
6405 set_spell_chartab(char_u *fol, char_u *low, char_u *upp) | 6404 set_spell_chartab(char_u *fol, char_u *low, char_u *upp) |
6406 { | 6405 { |
6407 /* We build the new tables here first, so that we can compare with the | 6406 // We build the new tables here first, so that we can compare with the |
6408 * previous one. */ | 6407 // previous one. |
6409 spelltab_T new_st; | 6408 spelltab_T new_st; |
6410 char_u *pf = fol, *pl = low, *pu = upp; | 6409 char_u *pf = fol, *pl = low, *pu = upp; |
6411 int f, l, u; | 6410 int f, l, u; |
6412 | 6411 |
6413 clear_spell_chartab(&new_st); | 6412 clear_spell_chartab(&new_st); |
6421 } | 6420 } |
6422 f = mb_ptr2char_adv(&pf); | 6421 f = mb_ptr2char_adv(&pf); |
6423 l = mb_ptr2char_adv(&pl); | 6422 l = mb_ptr2char_adv(&pl); |
6424 u = mb_ptr2char_adv(&pu); | 6423 u = mb_ptr2char_adv(&pu); |
6425 | 6424 |
6426 /* Every character that appears is a word character. */ | 6425 // Every character that appears is a word character. |
6427 if (f < 256) | 6426 if (f < 256) |
6428 new_st.st_isw[f] = TRUE; | 6427 new_st.st_isw[f] = TRUE; |
6429 if (l < 256) | 6428 if (l < 256) |
6430 new_st.st_isw[l] = TRUE; | 6429 new_st.st_isw[l] = TRUE; |
6431 if (u < 256) | 6430 if (u < 256) |
6432 new_st.st_isw[u] = TRUE; | 6431 new_st.st_isw[u] = TRUE; |
6433 | 6432 |
6434 /* if "LOW" and "FOL" are not the same the "LOW" char needs | 6433 // if "LOW" and "FOL" are not the same the "LOW" char needs |
6435 * case-folding */ | 6434 // case-folding |
6436 if (l < 256 && l != f) | 6435 if (l < 256 && l != f) |
6437 { | 6436 { |
6438 if (f >= 256) | 6437 if (f >= 256) |
6439 { | 6438 { |
6440 emsg(_(e_affrange)); | 6439 emsg(_(e_affrange)); |
6441 return FAIL; | 6440 return FAIL; |
6442 } | 6441 } |
6443 new_st.st_fold[l] = f; | 6442 new_st.st_fold[l] = f; |
6444 } | 6443 } |
6445 | 6444 |
6446 /* if "UPP" and "FOL" are not the same the "UPP" char needs | 6445 // if "UPP" and "FOL" are not the same the "UPP" char needs |
6447 * case-folding, it's upper case and the "UPP" is the upper case of | 6446 // case-folding, it's upper case and the "UPP" is the upper case of |
6448 * "FOL" . */ | 6447 // "FOL" . |
6449 if (u < 256 && u != f) | 6448 if (u < 256 && u != f) |
6450 { | 6449 { |
6451 if (f >= 256) | 6450 if (f >= 256) |
6452 { | 6451 { |
6453 emsg(_(e_affrange)); | 6452 emsg(_(e_affrange)); |
6472 * Set the spell character tables from strings in the .spl file. | 6471 * Set the spell character tables from strings in the .spl file. |
6473 */ | 6472 */ |
6474 static void | 6473 static void |
6475 set_spell_charflags( | 6474 set_spell_charflags( |
6476 char_u *flags, | 6475 char_u *flags, |
6477 int cnt, /* length of "flags" */ | 6476 int cnt, // length of "flags" |
6478 char_u *fol) | 6477 char_u *fol) |
6479 { | 6478 { |
6480 /* We build the new tables here first, so that we can compare with the | 6479 // We build the new tables here first, so that we can compare with the |
6481 * previous one. */ | 6480 // previous one. |
6482 spelltab_T new_st; | 6481 spelltab_T new_st; |
6483 int i; | 6482 int i; |
6484 char_u *p = fol; | 6483 char_u *p = fol; |
6485 int c; | 6484 int c; |
6486 | 6485 |
6511 { | 6510 { |
6512 int i; | 6511 int i; |
6513 | 6512 |
6514 if (did_set_spelltab) | 6513 if (did_set_spelltab) |
6515 { | 6514 { |
6516 /* check that it's the same table */ | 6515 // check that it's the same table |
6517 for (i = 0; i < 256; ++i) | 6516 for (i = 0; i < 256; ++i) |
6518 { | 6517 { |
6519 if (spelltab.st_isw[i] != new_st->st_isw[i] | 6518 if (spelltab.st_isw[i] != new_st->st_isw[i] |
6520 || spelltab.st_isu[i] != new_st->st_isu[i] | 6519 || spelltab.st_isu[i] != new_st->st_isu[i] |
6521 || spelltab.st_fold[i] != new_st->st_fold[i] | 6520 || spelltab.st_fold[i] != new_st->st_fold[i] |
6526 } | 6525 } |
6527 } | 6526 } |
6528 } | 6527 } |
6529 else | 6528 else |
6530 { | 6529 { |
6531 /* copy the new spelltab into the one being used */ | 6530 // copy the new spelltab into the one being used |
6532 spelltab = *new_st; | 6531 spelltab = *new_st; |
6533 did_set_spelltab = TRUE; | 6532 did_set_spelltab = TRUE; |
6534 } | 6533 } |
6535 | 6534 |
6536 return OK; | 6535 return OK; |
6545 { | 6544 { |
6546 int i; | 6545 int i; |
6547 char_u *p; | 6546 char_u *p; |
6548 int len; | 6547 int len; |
6549 int totlen; | 6548 int totlen; |
6550 size_t x = 1; /* collect return value of fwrite() */ | 6549 size_t x = 1; // collect return value of fwrite() |
6551 | 6550 |
6552 if (fd != NULL) | 6551 if (fd != NULL) |
6553 put_bytes(fd, (long_u)gap->ga_len, 2); /* <prefcondcnt> */ | 6552 put_bytes(fd, (long_u)gap->ga_len, 2); // <prefcondcnt> |
6554 | 6553 |
6555 totlen = 2 + gap->ga_len; /* length of <prefcondcnt> and <condlen> bytes */ | 6554 totlen = 2 + gap->ga_len; // length of <prefcondcnt> and <condlen> bytes |
6556 | 6555 |
6557 for (i = 0; i < gap->ga_len; ++i) | 6556 for (i = 0; i < gap->ga_len; ++i) |
6558 { | 6557 { |
6559 /* <prefcond> : <condlen> <condstr> */ | 6558 // <prefcond> : <condlen> <condstr> |
6560 p = ((char_u **)gap->ga_data)[i]; | 6559 p = ((char_u **)gap->ga_data)[i]; |
6561 if (p != NULL) | 6560 if (p != NULL) |
6562 { | 6561 { |
6563 len = (int)STRLEN(p); | 6562 len = (int)STRLEN(p); |
6564 if (fd != NULL) | 6563 if (fd != NULL) |
6592 lp->sl_has_map = FALSE; | 6591 lp->sl_has_map = FALSE; |
6593 return; | 6592 return; |
6594 } | 6593 } |
6595 lp->sl_has_map = TRUE; | 6594 lp->sl_has_map = TRUE; |
6596 | 6595 |
6597 /* Init the array and hash tables empty. */ | 6596 // Init the array and hash tables empty. |
6598 for (i = 0; i < 256; ++i) | 6597 for (i = 0; i < 256; ++i) |
6599 lp->sl_map_array[i] = 0; | 6598 lp->sl_map_array[i] = 0; |
6600 hash_init(&lp->sl_map_hash); | 6599 hash_init(&lp->sl_map_hash); |
6601 | 6600 |
6602 /* | 6601 /* |
6612 else | 6611 else |
6613 { | 6612 { |
6614 if (headc == 0) | 6613 if (headc == 0) |
6615 headc = c; | 6614 headc = c; |
6616 | 6615 |
6617 /* Characters above 255 don't fit in sl_map_array[], put them in | 6616 // Characters above 255 don't fit in sl_map_array[], put them in |
6618 * the hash table. Each entry is the char, a NUL the headchar and | 6617 // the hash table. Each entry is the char, a NUL the headchar and |
6619 * a NUL. */ | 6618 // a NUL. |
6620 if (c >= 256) | 6619 if (c >= 256) |
6621 { | 6620 { |
6622 int cl = mb_char2len(c); | 6621 int cl = mb_char2len(c); |
6623 int headcl = mb_char2len(headc); | 6622 int headcl = mb_char2len(headc); |
6624 char_u *b; | 6623 char_u *b; |
6636 hi = hash_lookup(&lp->sl_map_hash, b, hash); | 6635 hi = hash_lookup(&lp->sl_map_hash, b, hash); |
6637 if (HASHITEM_EMPTY(hi)) | 6636 if (HASHITEM_EMPTY(hi)) |
6638 hash_add_item(&lp->sl_map_hash, hi, b, hash); | 6637 hash_add_item(&lp->sl_map_hash, hi, b, hash); |
6639 else | 6638 else |
6640 { | 6639 { |
6641 /* This should have been checked when generating the .spl | 6640 // This should have been checked when generating the .spl |
6642 * file. */ | 6641 // file. |
6643 emsg(_("E783: duplicate char in MAP entry")); | 6642 emsg(_("E783: duplicate char in MAP entry")); |
6644 vim_free(b); | 6643 vim_free(b); |
6645 } | 6644 } |
6646 } | 6645 } |
6647 else | 6646 else |
6649 } | 6648 } |
6650 } | 6649 } |
6651 } | 6650 } |
6652 | 6651 |
6653 | 6652 |
6654 #endif /* FEAT_SPELL */ | 6653 #endif // FEAT_SPELL |