The pointer vector maintaining `content` in `editor` already
keeps track of the number of lines and makes it available via
a call to `ptr_vector_len` (or one could look at th `len`
member of the ptr_vector struct...this is C, not some fancy
object oriented language with data hiding). Delete the `lines`
local variable and just use ptr_vector_len where necessary.
Sorry; I should have done that in the first sweep through that
code. My bad!
Signed-off-by: Dan Cross <patchdev@fat-dragon.org>
strcpy()/strcat() are inherently dangerous, even when
used with great care. strlcpy() and strlcat() are
much safer replacements, and are available from OpenBSD
under a very liberal license. Import them and start
using them.
Between pointer vectors, malloz, stralloc and now
strlcpy/strlcat, Magicka has much safer, simpler and
more performant infrastructure for dealing with
strings and dynamic collections of various kinds.
Signed-off-by: Dan Cross <patchdev@fat-dragon.org>
Recast more code in terms of the ptr_vector abstraction.
The mail_menu.c code also made a lot of unnecessary copies
of strings. For example, there was this code sequence:
for (i = z; i < lines - 1; i++) {
free(content[i]);
content[i] = strdup(content[i + 1]);
}
free(content[i]);
lines--;
content = (char **)realloc(content, sizeof(char *) * lines);
Here, `content` represents an array of lines of text.
This code is removing an element from somewhere in that
array (possibly in the middle), and then shifting the
remaining elements over one position.
But observe the calls to `free` and `strdup` in the loop
body: the content is already dynamically allocated. We
free whatever was in the selected position, and then make
*another copy* of the data in the next position to put
into the now-available slot in the array: repeat for the
remainder of the array's elements.
Instead, we could change this code to just shift things
down:
free(content[z]);
for (i = z; i < (lines - 1); ++i)
content[i] = content[i + 1];
--lines;
ncontent = realloc(content, sizeof(char *) * lines);
assert(ncontent == NULL);
content = ncontent;
However, the ptr_vector abstraction provides us a function,
`ptr_vector_del` that deletes an element from the array and
returns the pointer, so we can rewrite this as simply:
free(ptr_vector_del(&content, z));
No additional malloc()/free() required, which means less
pressure on the memory allocator and less copying of data.
Signed-off-by: Dan Cross <patchdev@fat-dragon.org>