From d2745a59f830b1671c8951ba2a52c2f153191932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eliseo=20Marti=CC=81nez?= Date: Sun, 21 Dec 2014 12:36:16 +0100 Subject: [PATCH 1/3] Remove long_u: put_bytes(): Refactor. Remove all long_u instances due to put_bytes() function. First, function signature is changed this way: - nr : long_u --> uintmax_t uintmax_t is chosen so that invocations can use any unsigned integer type (including size_t) without needing to cast. - len : int --> unsigned int This is to pass the size in bytes of the previous param, thus an unsigned int is enough. All invocations use positive integer literals, so change is safe without the need for casts. Then, function implementation is adapted accordingly. Last, all invocation points are refactored this way: - Refactor types to minimize casts. - Inline declarations (C99 style) in containing function. All this changes were done with -Wconversion temporarily activated for spell.c and undo.c, so that we can assert changes are type-safe and do not introduce any warnings to that respect. --- src/nvim/misc2.c | 13 +-- src/nvim/spell.c | 264 ++++++++++++++++++++++------------------------- src/nvim/undo.c | 78 +++++++------- 3 files changed, 161 insertions(+), 194 deletions(-) diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index e6531ee1b2..d624f52879 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -501,15 +501,12 @@ char *read_string(FILE *fd, size_t cnt) return (char *)str; } -/* - * Write a number to file "fd", MSB first, in "len" bytes. - */ -int put_bytes(FILE *fd, long_u nr, int len) +/// Write a number to file "fd", MSB first, in "len" bytes. +/// @return OK/FAIL. +int put_bytes(FILE *fd, uintmax_t number, unsigned int len) { - int i; - - for (i = len - 1; i >= 0; --i) - if (putc((int)(nr >> (i * 8)), fd) == EOF) + for (unsigned int i = len - 1; i < len; --i) + if (putc((int)(number >> (i * 8)), fd) == EOF) return FAIL; return OK; } diff --git a/src/nvim/spell.c b/src/nvim/spell.c index 4759b4efa6..b8713909b8 100644 --- a/src/nvim/spell.c +++ b/src/nvim/spell.c @@ -287,6 +287,7 @@ #include #include #include +#include #include #include #include @@ -6594,25 +6595,13 @@ static int rep_compare(const void *s1, const void *s2) } // Write the Vim .spl file "fname". -// Return FAIL or OK; +// Return OK/FAIL. static int write_vim_spell(spellinfo_T *spin, char_u *fname) { - FILE *fd; - int regionmask; - int round; - wordnode_T *tree; - int nodecount; - int i; - int l; - garray_T *gap; - fromto_T *ftp; - char_u *p; - int rr; int retval = OK; - size_t fwv = 1; // collect return value of fwrite() to avoid - // warnings from picky compiler + int regionmask; - fd = mch_fopen((char *)fname, "w"); + FILE *fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return FAIL; @@ -6620,7 +6609,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) //
: // - fwv &= fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, (size_t)1, fd); + size_t fwv = fwrite(VIMSPELLMAGIC, VIMSPELLMAGICL, 1, fd); if (fwv != (size_t)1) // Catch first write error, don't try writing more. goto theend; @@ -6633,10 +6622,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_info != NULL) { putc(SN_INFO, fd); // putc(0, fd); // - - i = (int)STRLEN(spin->si_info); - put_bytes(fd, (long_u)i, 4); // - fwv &= fwrite(spin->si_info, (size_t)i, (size_t)1, fd); // + size_t i = STRLEN(spin->si_info); + put_bytes(fd, i, 4); // + fwv &= fwrite(spin->si_info, i, 1, fd); // } // SN_REGION: ... @@ -6644,9 +6632,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_region_count > 1) { putc(SN_REGION, fd); // putc(SNF_REQUIRED, fd); // - l = spin->si_region_count * 2; - put_bytes(fd, (long_u)l, 4); // - fwv &= fwrite(spin->si_region_name, (size_t)l, (size_t)1, fd); + size_t l = (size_t)spin->si_region_count * 2; + put_bytes(fd, l, 4); // + fwv &= fwrite(spin->si_region_name, l, 1, fd); // ... regionmask = (1 << spin->si_region_count) - 1; } else @@ -6669,17 +6657,17 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SNF_REQUIRED, fd); // // Form the string first, we need to know its length. - l = 0; - for (i = 128; i < 256; ++i) { + size_t l = 0; + for (size_t i = 128; i < 256; ++i) { if (has_mbyte) - l += mb_char2bytes(spelltab.st_fold[i], folchars + l); + l += (size_t)mb_char2bytes(spelltab.st_fold[i], folchars + l); else folchars[l++] = spelltab.st_fold[i]; } - put_bytes(fd, (long_u)(1 + 128 + 2 + l), 4); // + put_bytes(fd, 1 + 128 + 2 + l, 4); // fputc(128, fd); // - for (i = 128; i < 256; ++i) { + for (size_t i = 128; i < 256; ++i) { flags = 0; if (spelltab.st_isw[i]) flags |= CF_WORD; @@ -6688,8 +6676,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) fputc(flags, fd); // } - put_bytes(fd, (long_u)l, 2); // - fwv &= fwrite(folchars, (size_t)l, (size_t)1, fd); // + put_bytes(fd, l, 2); // + fwv &= fwrite(folchars, l, 1, fd); // } // SN_MIDWORD: @@ -6697,9 +6685,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_MIDWORD, fd); // putc(SNF_REQUIRED, fd); // - i = (int)STRLEN(spin->si_midword); - put_bytes(fd, (long_u)i, 4); // - fwv &= fwrite(spin->si_midword, (size_t)i, (size_t)1, fd); + size_t i = STRLEN(spin->si_midword); + put_bytes(fd, i, 4); // + fwv &= fwrite(spin->si_midword, i, 1, fd); // } @@ -6708,8 +6696,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_PREFCOND, fd); // putc(SNF_REQUIRED, fd); // - l = write_spell_prefcond(NULL, &spin->si_prefcond); - put_bytes(fd, (long_u)l, 4); // + size_t l = (size_t)write_spell_prefcond(NULL, &spin->si_prefcond); + put_bytes(fd, l, 4); // write_spell_prefcond(fd, &spin->si_prefcond); } @@ -6721,7 +6709,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // round 1: SN_REP section // round 2: SN_SAL section (unless SN_SOFO is used) // round 3: SN_REPSAL section - for (round = 1; round <= 3; ++round) { + for (unsigned int round = 1; round <= 3; ++round) { + garray_T *gap; if (round == 1) gap = &spin->si_rep; else if (round == 2) { @@ -6741,45 +6730,47 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(fromto_T), rep_compare); - i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); + int i = round == 1 ? SN_REP : (round == 2 ? SN_SAL : SN_REPSAL); putc(i, fd); // // This is for making suggestions, section is not required. putc(0, fd); // // Compute the length of what follows. - l = 2; // count or - for (int i = 0; i < gap->ga_len; ++i) { - ftp = &((fromto_T *)gap->ga_data)[i]; - l += 1 + (int)STRLEN(ftp->ft_from); // count <*fromlen> and <*from> - l += 1 + (int)STRLEN(ftp->ft_to); // count <*tolen> and <*to> + size_t l = 2; // count or + assert(gap->ga_len >= 0); + for (size_t i = 0; i < (size_t)gap->ga_len; ++i) { + fromto_T *ftp = &((fromto_T *)gap->ga_data)[i]; + l += 1 + STRLEN(ftp->ft_from); // count <*fromlen> and <*from> + l += 1 + STRLEN(ftp->ft_to); // count <*tolen> and <*to> } if (round == 2) - ++l; // count - put_bytes(fd, (long_u)l, 4); // + ++l; // count + put_bytes(fd, l, 4); // if (round == 2) { - i = 0; + int i = 0; if (spin->si_followup) i |= SAL_F0LLOWUP; if (spin->si_collapse) i |= SAL_COLLAPSE; if (spin->si_rem_accents) i |= SAL_REM_ACCENTS; - putc(i, fd); // + putc(i, fd); // } - put_bytes(fd, (long_u)gap->ga_len, 2); // or - for (int i = 0; i < gap->ga_len; ++i) { + put_bytes(fd, (uintmax_t)gap->ga_len, 2); // or + for (size_t i = 0; i < (size_t)gap->ga_len; ++i) { // : // : - ftp = &((fromto_T *)gap->ga_data)[i]; - for (rr = 1; rr <= 2; ++rr) { - p = rr == 1 ? ftp->ft_from : ftp->ft_to; - l = (int)STRLEN(p); - putc(l, fd); + fromto_T *ftp = &((fromto_T *)gap->ga_data)[i]; + for (unsigned int rr = 1; rr <= 2; ++rr) { + char_u *p = rr == 1 ? ftp->ft_from : ftp->ft_to; + l = STRLEN(p); + assert(l < INT_MAX); + putc((int)l, fd); if (l > 0) - fwv &= fwrite(p, l, (size_t)1, fd); + fwv &= fwrite(p, l, 1, fd); } } @@ -6791,16 +6782,15 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_SOFO, fd); // putc(0, fd); // - l = (int)STRLEN(spin->si_sofofr); - put_bytes(fd, (long_u)(l + STRLEN(spin->si_sofoto) + 4), 4); - // + size_t l = STRLEN(spin->si_sofofr); + put_bytes(fd, l + STRLEN(spin->si_sofoto) + 4, 4); // - put_bytes(fd, (long_u)l, 2); // - fwv &= fwrite(spin->si_sofofr, l, (size_t)1, fd); // + put_bytes(fd, l, 2); // + fwv &= fwrite(spin->si_sofofr, l, 1, fd); // - l = (int)STRLEN(spin->si_sofoto); - put_bytes(fd, (long_u)l, 2); // - fwv &= fwrite(spin->si_sofoto, l, (size_t)1, fd); // + l = STRLEN(spin->si_sofoto); + put_bytes(fd, l, 2); // + fwv &= fwrite(spin->si_sofoto, l, 1, fd); // } // SN_WORDS: ... @@ -6811,22 +6801,22 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // round 1: count the bytes // round 2: write the bytes - for (round = 1; round <= 2; ++round) { - int todo; - int len = 0; + for (unsigned int round = 1; round <= 2; ++round) { + size_t todo; + size_t len = 0; hashitem_T *hi; - todo = (int)spin->si_commonwords.ht_used; + todo = spin->si_commonwords.ht_used; for (hi = spin->si_commonwords.ht_array; todo > 0; ++hi) if (!HASHITEM_EMPTY(hi)) { - l = (int)STRLEN(hi->hi_key) + 1; + size_t l = STRLEN(hi->hi_key) + 1; len += l; if (round == 2) // - fwv &= fwrite(hi->hi_key, (size_t)l, (size_t)1, fd); + fwv &= fwrite(hi->hi_key, l, 1, fd); --todo; } if (round == 1) - put_bytes(fd, (long_u)len, 4); // + put_bytes(fd, len, 4); // } } @@ -6835,10 +6825,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (!GA_EMPTY(&spin->si_map)) { putc(SN_MAP, fd); // putc(0, fd); // - l = spin->si_map.ga_len; - put_bytes(fd, (long_u)l, 4); // - fwv &= fwrite(spin->si_map.ga_data, (size_t)l, (size_t)1, fd); - // + size_t l = (size_t)spin->si_map.ga_len; + put_bytes(fd, l, 4); // + fwv &= fwrite(spin->si_map.ga_data, l, 1, fd); // } // SN_SUGFILE: @@ -6851,7 +6840,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) || (spin->si_sofofr != NULL && spin->si_sofoto != NULL))) { putc(SN_SUGFILE, fd); // putc(0, fd); // - put_bytes(fd, (long_u)8, 4); // + put_bytes(fd, 8, 4); // // Set si_sugtime and write it to the file. spin->si_sugtime = time(NULL); @@ -6864,7 +6853,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) if (spin->si_nosplitsugs) { putc(SN_NOSPLITSUGS, fd); // putc(0, fd); // - put_bytes(fd, (long_u)0, 4); // + put_bytes(fd, 0, 4); // } // SN_COMPOUND: compound info. @@ -6874,28 +6863,27 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_COMPOUND, fd); // putc(0, fd); // - l = (int)STRLEN(spin->si_compflags); - for (int i = 0; i < spin->si_comppat.ga_len; ++i) { - l += (int)STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; + size_t l = STRLEN(spin->si_compflags); + assert(spin->si_comppat.ga_len >= 0); + for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) { + l += STRLEN(((char_u **)(spin->si_comppat.ga_data))[i]) + 1; } - put_bytes(fd, (long_u)(l + 7), 4); // + put_bytes(fd, l + 7, 4); // putc(spin->si_compmax, fd); // putc(spin->si_compminlen, fd); // putc(spin->si_compsylmax, fd); // putc(0, fd); // for Vim 7.0b compatibility putc(spin->si_compoptions, fd); // - put_bytes(fd, (long_u)spin->si_comppat.ga_len, 2); - // - for (int i = 0; i < spin->si_comppat.ga_len; ++i) { - p = ((char_u **)(spin->si_comppat.ga_data))[i]; + put_bytes(fd, (uintmax_t)spin->si_comppat.ga_len, 2); // + for (size_t i = 0; i < (size_t)spin->si_comppat.ga_len; ++i) { + char_u *p = ((char_u **)(spin->si_comppat.ga_data))[i]; + assert(STRLEN(p) < INT_MAX); putc((int)STRLEN(p), fd); // - fwv &= fwrite(p, (size_t)STRLEN(p), (size_t)1, fd); - // + fwv &= fwrite(p, STRLEN(p), 1, fd); // } // - fwv &= fwrite(spin->si_compflags, (size_t)STRLEN(spin->si_compflags), - (size_t)1, fd); + fwv &= fwrite(spin->si_compflags, STRLEN(spin->si_compflags), 1, fd); } // SN_NOBREAK: NOBREAK flag @@ -6904,7 +6892,7 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(0, fd); // // It's empty, the presence of the section flags the feature. - put_bytes(fd, (long_u)0, 4); // + put_bytes(fd, 0, 4); // } // SN_SYLLABLE: syllable info. @@ -6914,10 +6902,9 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) putc(SN_SYLLABLE, fd); // putc(0, fd); // - l = (int)STRLEN(spin->si_syllable); - put_bytes(fd, (long_u)l, 4); // - fwv &= fwrite(spin->si_syllable, (size_t)l, (size_t)1, fd); - // + size_t l = STRLEN(spin->si_syllable); + put_bytes(fd, l, 4); // + fwv &= fwrite(spin->si_syllable, l, 1, fd); // } // end of @@ -6926,7 +6913,8 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // spin->si_memtot = 0; - for (round = 1; round <= 3; ++round) { + for (unsigned int round = 1; round <= 3; ++round) { + wordnode_T *tree; if (round == 1) tree = spin->si_foldroot->wn_sibling; else if (round == 2) @@ -6940,11 +6928,12 @@ static int write_vim_spell(spellinfo_T *spin, char_u *fname) // Count the number of nodes. Needed to be able to allocate the // memory when reading the nodes. Also fills in index for shared // nodes. - nodecount = put_node(NULL, tree, 0, regionmask, round == 3); + size_t nodecount = (size_t)put_node(NULL, tree, 0, regionmask, round == 3); // number of nodes in 4 bytes - put_bytes(fd, (long_u)nodecount, 4); // - spin->si_memtot += nodecount + nodecount * sizeof(int); + put_bytes(fd, nodecount, 4); // + assert(nodecount + nodecount * sizeof(int) < INT_MAX); + spin->si_memtot += (int)(nodecount + nodecount * sizeof(int)); // Write the nodes. (void)put_node(fd, tree, 0, regionmask, round == 3); @@ -7002,11 +6991,6 @@ put_node ( bool prefixtree // true for PREFIXTREE ) { - int newindex = idx; - int siblingcount = 0; - wordnode_T *np; - int flags; - // If "node" is zero the tree is empty. if (node == NULL) return 0; @@ -7015,7 +6999,8 @@ put_node ( node->wn_u1.index = idx; // Count the number of siblings. - for (np = node; np != NULL; np = np->wn_sibling) + int siblingcount = 0; + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) ++siblingcount; // Write the sibling count. @@ -7023,7 +7008,7 @@ put_node ( putc(siblingcount, fd); // // Write each sibling byte and optionally extra info. - for (np = node; np != NULL; np = np->wn_sibling) { + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) { if (np->wn_byte == 0) { if (fd != NULL) { // For a NUL byte (end of word) write the flags etc. @@ -7039,10 +7024,10 @@ put_node ( putc(np->wn_flags, fd); // } putc(np->wn_affixID, fd); // - put_bytes(fd, (long_u)np->wn_region, 2); // + put_bytes(fd, (uintmax_t)np->wn_region, 2); // } else { // For word trees we write the flag/region items. - flags = np->wn_flags; + int flags = np->wn_flags; if (regionmask != 0 && np->wn_region != regionmask) flags |= WF_REGION; if (np->wn_affixID != 0) @@ -7054,7 +7039,7 @@ put_node ( if (np->wn_flags >= 0x100) { putc(BY_FLAGS2, fd); // putc(flags, fd); // - putc((unsigned)flags >> 8, fd); // + putc((int)((unsigned)flags >> 8), fd); // } else { putc(BY_FLAGS, fd); // putc(flags, fd); // @@ -7071,9 +7056,8 @@ put_node ( && np->wn_child->wn_u2.wnode != node) { // The child is written elsewhere, write the reference. if (fd != NULL) { - putc(BY_INDEX, fd); // - // - put_bytes(fd, (long_u)np->wn_child->wn_u1.index, 3); + putc(BY_INDEX, fd); // + put_bytes(fd, (uintmax_t)np->wn_child->wn_u1.index, 3); // } } else if (np->wn_child->wn_u2.wnode == NULL) // We will write the child below and give it an index. @@ -7089,10 +7073,10 @@ put_node ( // Space used in the array when reading: one for each sibling and one for // the count. - newindex += siblingcount + 1; + int newindex = idx + siblingcount + 1; // Recursively dump the children of each sibling. - for (np = node; np != NULL; np = np->wn_sibling) + for (wordnode_T *np = node; np != NULL; np = np->wn_sibling) if (np->wn_byte != 0 && np->wn_child->wn_u2.wnode == node) newindex = put_node(fd, np->wn_child, newindex, regionmask, prefixtree); @@ -7440,16 +7424,8 @@ static int bytes2offset(char_u **pp) // Write the .sug file in "fname". static void sug_write(spellinfo_T *spin, char_u *fname) { - FILE *fd; - wordnode_T *tree; - int nodecount; - int wcount; - char_u *line; - linenr_T lnum; - int len; - // Create the file. Note that an existing file is silently overwritten! - fd = mch_fopen((char *)fname, "w"); + FILE *fd = mch_fopen((char *)fname, "w"); if (fd == NULL) { EMSG2(_(e_notopen), fname); return; @@ -7471,7 +7447,7 @@ static void sug_write(spellinfo_T *spin, char_u *fname) // spin->si_memtot = 0; - tree = spin->si_foldroot->wn_sibling; + wordnode_T *tree = spin->si_foldroot->wn_sibling; // Clear the index and wnode fields in the tree. clear_node(tree); @@ -7479,28 +7455,31 @@ static void sug_write(spellinfo_T *spin, char_u *fname) // Count the number of nodes. Needed to be able to allocate the // memory when reading the nodes. Also fills in index for shared // nodes. - nodecount = put_node(NULL, tree, 0, 0, false); + size_t nodecount = (size_t)put_node(NULL, tree, 0, 0, false); // number of nodes in 4 bytes - put_bytes(fd, (long_u)nodecount, 4); // - spin->si_memtot += nodecount + nodecount * sizeof(int); + put_bytes(fd, nodecount, 4); // + assert(nodecount + nodecount * sizeof(int) < INT_MAX); + spin->si_memtot += (int)(nodecount + nodecount * sizeof(int)); // Write the nodes. (void)put_node(fd, tree, 0, 0, false); // : ... - wcount = spin->si_spellbuf->b_ml.ml_line_count; - put_bytes(fd, (long_u)wcount, 4); // + linenr_T wcount = spin->si_spellbuf->b_ml.ml_line_count; + assert(wcount >= 0); + put_bytes(fd, (uintmax_t)wcount, 4); // - for (lnum = 1; lnum <= (linenr_T)wcount; ++lnum) { + for (linenr_T lnum = 1; lnum <= wcount; ++lnum) { // : ... NUL - line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); - len = (int)STRLEN(line) + 1; - if (fwrite(line, (size_t)len, (size_t)1, fd) == 0) { + char_u *line = ml_get_buf(spin->si_spellbuf, lnum, FALSE); + size_t len = STRLEN(line) + 1; + if (fwrite(line, len, 1, fd) == 0) { EMSG(_(e_write)); goto theend; } - spin->si_memtot += len; + assert((size_t)spin->si_memtot + len <= INT_MAX); + spin->si_memtot += (int)len; } // Write another byte to check for errors. @@ -8286,31 +8265,30 @@ static bool spell_iswordp_w(int *p, win_T *wp) // When "fd" is NULL only count the length of what is written. static int write_spell_prefcond(FILE *fd, garray_T *gap) { - char_u *p; - int len; - int totlen; - size_t x = 1; // collect return value of fwrite() + assert(gap->ga_len >= 0); if (fd != NULL) - put_bytes(fd, (long_u)gap->ga_len, 2); // - - totlen = 2 + gap->ga_len; // length of and bytes + put_bytes(fd, (uintmax_t)gap->ga_len, 2); // + size_t totlen = 2 + (size_t)gap->ga_len; // and bytes + size_t x = 1; // collect return value of fwrite() for (int i = 0; i < gap->ga_len; ++i) { // : - p = ((char_u **)gap->ga_data)[i]; + char_u *p = ((char_u **)gap->ga_data)[i]; if (p != NULL) { - len = (int)STRLEN(p); + size_t len = STRLEN(p); if (fd != NULL) { - fputc(len, fd); - x &= fwrite(p, (size_t)len, (size_t)1, fd); + assert(len <= INT_MAX); + fputc((int)len, fd); + x &= fwrite(p, len, 1, fd); } totlen += len; } else if (fd != NULL) fputc(0, fd); } - return totlen; + assert(totlen <= INT_MAX); + return (int)totlen; } // Case-fold "str[len]" into "buf[buflen]". The result is NUL terminated. diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 9a3da5bcdb..0dddfe703e 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -715,42 +715,40 @@ static void u_free_uhp(u_header_T *uhp) static int serialize_header(FILE *fp, buf_T *buf, char_u *hash) { - int len; - /* Start writing, first the magic marker and undo info version. */ - if (fwrite(UF_START_MAGIC, (size_t)UF_START_MAGIC_LEN, (size_t)1, fp) != 1) + if (fwrite(UF_START_MAGIC, UF_START_MAGIC_LEN, 1, fp) != 1) return FAIL; - put_bytes(fp, (long_u)UF_VERSION, 2); + put_bytes(fp, UF_VERSION, 2); /* Write a hash of the buffer text, so that we can verify it is still the * same when reading the buffer text. */ - if (fwrite(hash, (size_t)UNDO_HASH_SIZE, (size_t)1, fp) != 1) + if (fwrite(hash, UNDO_HASH_SIZE, 1, fp) != 1) return FAIL; /* buffer-specific data */ - put_bytes(fp, (long_u)buf->b_ml.ml_line_count, 4); - len = buf->b_u_line_ptr != NULL ? (int)STRLEN(buf->b_u_line_ptr) : 0; - put_bytes(fp, (long_u)len, 4); + put_bytes(fp, (uintmax_t)buf->b_ml.ml_line_count, 4); + size_t len = buf->b_u_line_ptr ? STRLEN(buf->b_u_line_ptr) : 0; + put_bytes(fp, len, 4); if (len > 0 && fwrite(buf->b_u_line_ptr, len, 1, fp) != 1) return FAIL; - put_bytes(fp, (long_u)buf->b_u_line_lnum, 4); - put_bytes(fp, (long_u)buf->b_u_line_colnr, 4); + put_bytes(fp, (uintmax_t)buf->b_u_line_lnum, 4); + put_bytes(fp, (uintmax_t)buf->b_u_line_colnr, 4); /* Undo structures header data */ put_header_ptr(fp, buf->b_u_oldhead); put_header_ptr(fp, buf->b_u_newhead); put_header_ptr(fp, buf->b_u_curhead); - put_bytes(fp, (long_u)buf->b_u_numhead, 4); - put_bytes(fp, (long_u)buf->b_u_seq_last, 4); - put_bytes(fp, (long_u)buf->b_u_seq_cur, 4); + put_bytes(fp, (uintmax_t)buf->b_u_numhead, 4); + put_bytes(fp, (uintmax_t)buf->b_u_seq_last, 4); + put_bytes(fp, (uintmax_t)buf->b_u_seq_cur, 4); put_time(fp, buf->b_u_time_cur); /* Optional fields. */ putc(4, fp); putc(UF_LAST_SAVE_NR, fp); - put_bytes(fp, (long_u)buf->b_u_save_nr_last, 4); + put_bytes(fp, (uintmax_t)buf->b_u_save_nr_last, 4); putc(0, fp); /* end marker */ @@ -759,22 +757,19 @@ static int serialize_header(FILE *fp, buf_T *buf, char_u *hash) static int serialize_uhp(FILE *fp, buf_T *buf, u_header_T *uhp) { - int i; - u_entry_T *uep; - - if (put_bytes(fp, (long_u)UF_HEADER_MAGIC, 2) == FAIL) + if (put_bytes(fp, UF_HEADER_MAGIC, 2) == FAIL) return FAIL; put_header_ptr(fp, uhp->uh_next.ptr); put_header_ptr(fp, uhp->uh_prev.ptr); put_header_ptr(fp, uhp->uh_alt_next.ptr); put_header_ptr(fp, uhp->uh_alt_prev.ptr); - put_bytes(fp, uhp->uh_seq, 4); + put_bytes(fp, (uintmax_t)uhp->uh_seq, 4); serialize_pos(uhp->uh_cursor, fp); - put_bytes(fp, (long_u)uhp->uh_cursor_vcol, 4); - put_bytes(fp, (long_u)uhp->uh_flags, 2); + put_bytes(fp, (uintmax_t)uhp->uh_cursor_vcol, 4); + put_bytes(fp, (uintmax_t)uhp->uh_flags, 2); /* Assume NMARKS will stay the same. */ - for (i = 0; i < NMARKS; ++i) + for (size_t i = 0; i < NMARKS; ++i) serialize_pos(uhp->uh_namedm[i], fp); serialize_visualinfo(&uhp->uh_visual, fp); put_time(fp, uhp->uh_time); @@ -782,17 +777,17 @@ static int serialize_uhp(FILE *fp, buf_T *buf, u_header_T *uhp) /* Optional fields. */ putc(4, fp); putc(UHP_SAVE_NR, fp); - put_bytes(fp, (long_u)uhp->uh_save_nr, 4); + put_bytes(fp, (uintmax_t)uhp->uh_save_nr, 4); putc(0, fp); /* end marker */ /* Write all the entries. */ - for (uep = uhp->uh_entry; uep != NULL; uep = uep->ue_next) { - put_bytes(fp, (long_u)UF_ENTRY_MAGIC, 2); + for (u_entry_T *uep = uhp->uh_entry; uep; uep = uep->ue_next) { + put_bytes(fp, UF_ENTRY_MAGIC, 2); if (serialize_uep(fp, buf, uep) == FAIL) return FAIL; } - put_bytes(fp, (long_u)UF_ENTRY_END_MAGIC, 2); + put_bytes(fp, UF_ENTRY_END_MAGIC, 2); return OK; } @@ -875,16 +870,13 @@ static u_header_T *unserialize_uhp(FILE *fp, char_u *file_name) */ static int serialize_uep(FILE *fp, buf_T *buf, u_entry_T *uep) { - int i; - size_t len; - - put_bytes(fp, (long_u)uep->ue_top, 4); - put_bytes(fp, (long_u)uep->ue_bot, 4); - put_bytes(fp, (long_u)uep->ue_lcount, 4); - put_bytes(fp, (long_u)uep->ue_size, 4); - for (i = 0; i < uep->ue_size; ++i) { - len = STRLEN(uep->ue_array[i]); - if (put_bytes(fp, (long_u)len, 4) == FAIL) + put_bytes(fp, (uintmax_t)uep->ue_top, 4); + put_bytes(fp, (uintmax_t)uep->ue_bot, 4); + put_bytes(fp, (uintmax_t)uep->ue_lcount, 4); + put_bytes(fp, (uintmax_t)uep->ue_size, 4); + for (size_t i = 0; i < (size_t)uep->ue_size; ++i) { + size_t len = STRLEN(uep->ue_array[i]); + if (put_bytes(fp, len, 4) == FAIL) return FAIL; if (len > 0 && fwrite(uep->ue_array[i], len, 1, fp) != 1) return FAIL; @@ -938,9 +930,9 @@ static u_entry_T *unserialize_uep(FILE *fp, int *error, char_u *file_name) */ static void serialize_pos(pos_T pos, FILE *fp) { - put_bytes(fp, (long_u)pos.lnum, 4); - put_bytes(fp, (long_u)pos.col, 4); - put_bytes(fp, (long_u)pos.coladd, 4); + put_bytes(fp, (uintmax_t)pos.lnum, 4); + put_bytes(fp, (uintmax_t)pos.col, 4); + put_bytes(fp, (uintmax_t)pos.coladd, 4); } /* @@ -966,8 +958,8 @@ static void serialize_visualinfo(visualinfo_T *info, FILE *fp) { serialize_pos(info->vi_start, fp); serialize_pos(info->vi_end, fp); - put_bytes(fp, (long_u)info->vi_mode, 4); - put_bytes(fp, (long_u)info->vi_curswant, 4); + put_bytes(fp, (uintmax_t)info->vi_mode, 4); + put_bytes(fp, (uintmax_t)info->vi_curswant, 4); } /* @@ -987,7 +979,7 @@ static void unserialize_visualinfo(visualinfo_T *info, FILE *fp) * pointers when reading. */ static void put_header_ptr(FILE *fp, u_header_T *uhp) { - put_bytes(fp, (long_u)(uhp != NULL ? uhp->uh_seq : 0), 4); + put_bytes(fp, (uintmax_t)(uhp != NULL ? uhp->uh_seq : 0), 4); } /* @@ -1178,7 +1170,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) uhp = uhp->uh_next.ptr; } - if (put_bytes(fp, (long_u)UF_HEADER_END_MAGIC, 2) == OK) + if (put_bytes(fp, UF_HEADER_END_MAGIC, 2) == OK) write_ok = true; #ifdef U_DEBUG if (headers_written != buf->b_u_numhead) { From ec09f4488f0114a1a557642cf5ada64608d357bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eliseo=20Marti=CC=81nez?= Date: Sun, 21 Dec 2014 22:29:24 +0100 Subject: [PATCH 2/3] Remove long_u: Passing-by: undo.c: Add to -Wconversion. Previous commit dropped many -Wconversion warnings in both spell.c and undo.c. spell.c still has a lot of them (200+). But in undo.c, only a handful of them remain. Take the chance to eliminate those, too, and add undo.c to -Wconversion checked files. --- src/nvim/CMakeLists.txt | 1 - src/nvim/undo.c | 31 ++++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 8c0979026a..c688c3d330 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -87,7 +87,6 @@ set(CONV_SOURCES tag.c term.c ui.c - undo.c version.c window.c) diff --git a/src/nvim/undo.c b/src/nvim/undo.c index 0dddfe703e..59920cfbe1 100644 --- a/src/nvim/undo.c +++ b/src/nvim/undo.c @@ -82,6 +82,7 @@ #include #include +#include #include #include #include @@ -569,7 +570,7 @@ int u_savecommon(linenr_T top, linenr_T bot, linenr_T newbot, int reload) } if (size > 0) { - uep->ue_array = xmalloc(sizeof(char_u *) * size); + uep->ue_array = xmalloc(sizeof(char_u *) * (size_t)size); for (i = 0, lnum = top + 1; i < size; ++i) { fast_breakcheck(); if (got_int) { @@ -638,7 +639,6 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) char_u dir_name[IOSIZE + 1]; char_u *munged_name = NULL; char_u *undo_file_name = NULL; - int dir_len; char_u *p; char_u *ffname = buf_ffname; #ifdef HAVE_READLINK @@ -659,11 +659,11 @@ char_u *u_get_undo_file_name(char_u *buf_ffname, int reading) * When not reading use the first directory that exists or ".". */ dirp = p_udir; while (*dirp != NUL) { - dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); + size_t dir_len = copy_option_part(&dirp, dir_name, IOSIZE, ","); if (dir_len == 1 && dir_name[0] == '.') { /* Use same directory as the ffname, * "dir/name" -> "dir/.name.un~" */ - undo_file_name = vim_strnsave(ffname, (int)(STRLEN(ffname) + 5)); + undo_file_name = vim_strnsave(ffname, STRLEN(ffname) + 5); p = path_tail(undo_file_name); memmove(p + 1, p, STRLEN(p) + 1); *p = '.'; @@ -902,8 +902,8 @@ static u_entry_T *unserialize_uep(FILE *fp, int *error, char_u *file_name) uep->ue_lcount = get4c(fp); uep->ue_size = get4c(fp); if (uep->ue_size > 0) { - array = xmalloc(sizeof(char_u *) * uep->ue_size); - memset(array, 0, sizeof(char_u *) * uep->ue_size); + array = xmalloc(sizeof(char_u *) * (size_t)uep->ue_size); + memset(array, 0, sizeof(char_u *) * (size_t)uep->ue_size); } else array = NULL; uep->ue_array = array; @@ -1053,9 +1053,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) goto theend; } else { char_u mbuf[UF_START_MAGIC_LEN]; - int len; - - len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN); + ssize_t len = read_eintr(fd, mbuf, UF_START_MAGIC_LEN); close(fd); if (len < UF_START_MAGIC_LEN || memcmp(mbuf, UF_START_MAGIC, UF_START_MAGIC_LEN) != 0) { @@ -1113,7 +1111,7 @@ void u_write_undo(char_u *name, int forceit, buf_T *buf, char_u *hash) && os_fileinfo((char *)buf->b_ffname, &file_info_old) && os_fileinfo((char *)file_name, &file_info_new) && file_info_old.stat.st_gid != file_info_new.stat.st_gid - && os_fchown(fd, -1, file_info_old.stat.st_gid) != 0) { + && os_fchown(fd, (uv_uid_t)-1, (uv_gid_t)file_info_old.stat.st_gid)) { os_setperm(file_name, (perm & 0707) | ((perm & 07) << 3)); } # ifdef HAVE_SELINUX @@ -1350,7 +1348,7 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name) * sequence numbers of the headers. * When there are no headers uhp_table is NULL. */ if (num_head > 0) { - uhp_table = xmalloc(num_head * sizeof(u_header_T *)); + uhp_table = xmalloc((size_t)num_head * sizeof(u_header_T *)); } while ((c = get2c(fp)) == UF_HEADER_MAGIC) { @@ -1425,15 +1423,18 @@ void u_read_undo(char_u *name, char_u *hash, char_u *orig_name) break; } if (old_header_seq > 0 && old_idx < 0 && uhp->uh_seq == old_header_seq) { - old_idx = i; + assert(i <= SHRT_MAX); + old_idx = (short)i; SET_FLAG(i); } if (new_header_seq > 0 && new_idx < 0 && uhp->uh_seq == new_header_seq) { - new_idx = i; + assert(i <= SHRT_MAX); + new_idx = (short)i; SET_FLAG(i); } if (cur_header_seq > 0 && cur_idx < 0 && uhp->uh_seq == cur_header_seq) { - cur_idx = i; + assert(i <= SHRT_MAX); + cur_idx = (short)i; SET_FLAG(i); } } @@ -1985,7 +1986,7 @@ static void u_undoredo(int undo) /* delete the lines between top and bot and save them in newarray */ if (oldsize > 0) { - newarray = xmalloc(sizeof(char_u *) * oldsize); + newarray = xmalloc(sizeof(char_u *) * (size_t)oldsize); /* delete backwards, it goes faster in most cases */ for (lnum = bot - 1, i = oldsize; --i >= 0; --lnum) { /* what can we do when we run out of memory? */ From 516405b6012e0c99d8bc073a7dead3c3206a184e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eliseo=20Marti=CC=81nez?= Date: Sun, 21 Dec 2014 22:51:03 +0100 Subject: [PATCH 3/3] Remove long_u: Passing-by: put_time(): Refactor implementation. put_time() had a complicated implementation, because of having to shift an 8-byte value in a portable way with old means. That can be greatly simplified now, using a C99 fixed-size type. --- config/CMakeLists.txt | 1 - config/config.h.in | 1 - src/nvim/misc2.c | 34 ++++++---------------------------- 3 files changed, 6 insertions(+), 30 deletions(-) diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index 0f5dd7d984..aab4b5c23d 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -5,7 +5,6 @@ include(CheckIncludeFiles) check_type_size("int" SIZEOF_INT) check_type_size("long" SIZEOF_LONG) -check_type_size("time_t" SIZEOF_TIME_T) check_type_size("off_t" SIZEOF_OFF_T) check_type_size("void *" SIZEOF_VOID_PTR) diff --git a/config/config.h.in b/config/config.h.in index 79dabc61e4..005eb1ccb0 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -11,7 +11,6 @@ #define SIZEOF_INT @SIZEOF_INT@ #define SIZEOF_LONG @SIZEOF_LONG@ -#define SIZEOF_TIME_T @SIZEOF_TIME_T@ #define SIZEOF_OFF_T @SIZEOF_OFF_T@ #if @SIZEOF_VOID_PTR@ == 8 diff --git a/src/nvim/misc2.c b/src/nvim/misc2.c index d624f52879..1407dcf04b 100644 --- a/src/nvim/misc2.c +++ b/src/nvim/misc2.c @@ -511,34 +511,12 @@ int put_bytes(FILE *fd, uintmax_t number, unsigned int len) return OK; } - -/* - * Write time_t to file "fd" in 8 bytes. - */ -void put_time(FILE *fd, time_t the_time) +/// Write time_t to file "fd" in 8 bytes. +void put_time(FILE *fd, time_t time_) { - int c; - int i; - time_t wtime = the_time; - - /* time_t can be up to 8 bytes in size, more than long_u, thus we - * can't use put_bytes() here. - * Another problem is that ">>" may do an arithmetic shift that keeps the - * sign. This happens for large values of wtime. A cast to long_u may - * truncate if time_t is 8 bytes. So only use a cast when it is 4 bytes, - * it's safe to assume that long_u is 4 bytes or more and when using 8 - * bytes the top bit won't be set. */ - for (i = 7; i >= 0; --i) { - if (i + 1 > (int)sizeof(time_t)) - /* ">>" doesn't work well when shifting more bits than avail */ - putc(0, fd); - else { -#if defined(SIZEOF_TIME_T) && SIZEOF_TIME_T > 4 - c = (int)(wtime >> (i * 8)); -#else - c = (int)((long_u)wtime >> (i * 8)); -#endif - putc(c, fd); - } + // time_t can be up to 8 bytes in size, more than uintmax_t in 32 bits + // systems, thus we can't use put_bytes() here. + for (unsigned int i = 7; i < 8; --i) { + putc((int)((uint64_t)time_ >> (i * 8)), fd); } }