gbranden pushed a commit to branch master
in repository groff.
commit d667fb0b0f10e0504b3f8fab33fa088c9e4ef3d5
Author: G. Branden Robinson <[email protected]>
AuthorDate: Sat Jun 6 09:31:43 2026 -0500
Refactor groff's bespoke `string` class.
...to use `size_t` instead of `int` to track array sizes and indices.
* src/include/stringclass.h: Update declarations and `inline` function
definitions.
* src/libs/libgroff/string.cpp: Update definitions and local variables.
Drop now tautologically true assert(3)ions.
(string::remove_spaces): This function searches for spaces backward
from the end of the string contents. Alter loop invariant from a
non-negative array index (now impossible) to one that is less than the
array length. Discard now-unreachable logic branch.
* src/preproc/eqn/lex.cpp (add_quoted_context):
* src/preproc/preconv/preconv.cpp (get_tag_lines):
* src/preproc/refer/label.ypp (format_serial)
(alternative_expr::evaluate)
(substitute_expr::evaluate)
(int_set::set)
(int_set::get):
* src/preproc/refer/ref.cpp (reference::canonicalize_authors):
* src/preproc/tbl/table.cpp (table::add_entry): Retype variables
populated by or compared to applicable `string` member functions from
`int` to `size_t`.
---
ChangeLog | 27 +++++++++++++
src/devices/grohtml/post-html.cpp | 2 +-
src/include/stringclass.h | 43 +++++++++++----------
src/libs/libgroff/string.cpp | 80 +++++++++++++++++----------------------
src/preproc/eqn/lex.cpp | 2 +-
src/preproc/preconv/preconv.cpp | 2 +-
src/preproc/refer/label.ypp | 12 +++---
src/preproc/refer/ref.cpp | 2 +-
src/preproc/tbl/table.cpp | 2 +-
9 files changed, 94 insertions(+), 78 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c1494ed7b..f8d30c8e0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,30 @@
+2026-06-06 G. Branden Robinson <[email protected]>
+
+ Refactor groff's bespoke `string` class to use `size_t` instead
+ of `int` to track array sizes and indices.
+
+ * src/include/stringclass.h: Update declarations and `inline`
+ function definitions.
+ * src/libs/libgroff/string.cpp: Update definitions and local
+ variables. Drop now tautologically true assert(3)ions.
+ (string::remove_spaces): This function searches for spaces
+ backward from the end of the string contents. Alter loop
+ invariant from a non-negative array index (now impossible) to
+ one that is less than the array length. Discard now-unreachable
+ logic branch.
+
+ * src/preproc/eqn/lex.cpp (add_quoted_context):
+ * src/preproc/preconv/preconv.cpp (get_tag_lines):
+ * src/preproc/refer/label.ypp (format_serial)
+ (alternative_expr::evaluate)
+ (substitute_expr::evaluate)
+ (int_set::set)
+ (int_set::get):
+ * src/preproc/refer/ref.cpp (reference::canonicalize_authors):
+ * src/preproc/tbl/table.cpp (table::add_entry): Retype variables
+ populated by or compared to applicable `string` member functions
+ from `int` to `size_t`.
+
2026-06-06 G. Branden Robinson <[email protected]>
* src/libs/libgroff/string.cpp: Drop unnecessary prototypes of
diff --git a/src/devices/grohtml/post-html.cpp
b/src/devices/grohtml/post-html.cpp
index a5e5e8bc8..2cc72c314 100644
--- a/src/devices/grohtml/post-html.cpp
+++ b/src/devices/grohtml/post-html.cpp
@@ -2862,7 +2862,7 @@ void html_printer::write_header (void)
void html_printer::determine_header_level (int level)
{
if (0 == level) {
- int i;
+ size_t i;
for (i = 0; ((i<header.header_buffer.length())
&& (('.' == header.header_buffer[i])
diff --git a/src/include/stringclass.h b/src/include/stringclass.h
index 93ecc2934..0df2363dd 100644
--- a/src/include/stringclass.h
+++ b/src/include/stringclass.h
@@ -42,7 +42,7 @@ public:
string();
string(const string &);
string(const char *);
- string(const char *, int);
+ string(const char *, size_t);
string(char);
~string();
@@ -54,22 +54,22 @@ public:
string &operator+=(const string &);
string &operator+=(const char *);
string &operator+=(char);
- void append(const char *, int);
+ void append(const char *, size_t);
- int length() const;
+ size_t length() const;
bool empty() const;
- int operator*() const;
+ size_t operator*() const;
- string substring(int i, int n) const;
+ string substring(size_t i, size_t n) const;
- char &operator[](int);
- char operator[](int) const;
+ char &operator[](size_t);
+ char operator[](size_t) const;
- void set_length(int i);
+ void set_length(size_t i);
const char *contents() const;
int search(const char) const;
bool contains(const char) const;
- int find(const char *) const;
+ size_t find(const char *) const;
char *extract() const;
size_t json_length() const;
const char *json_extract() const;
@@ -93,27 +93,28 @@ public:
private:
char *ptr;
- int len;
- int sz;
+ size_t len;
+ size_t sz;
- string(const char *, int, const char *, int); // for use by operator+
+ // for use by operator+
+ string(const char *, size_t, const char *, size_t);
void grow1();
};
-inline char &string::operator[](int i)
+inline char &string::operator[](size_t i)
{
- assert((i >= 0) && (i < len));
+ assert(i < len);
return ptr[i];
}
-inline char string::operator[](int i) const
+inline char string::operator[](size_t i) const
{
- assert((i >= 0) && (i < len));
+ assert(i < len);
return ptr[i];
}
-inline int string::length() const
+inline size_t string::length() const
{
return len;
}
@@ -123,7 +124,7 @@ inline bool string::empty() const
return (len == 0);
}
-inline int string::operator*() const
+inline size_t string::operator*() const
{
return len;
}
@@ -172,9 +173,9 @@ inline bool operator!=(const string &s1, const string &s2)
|| (s1.len != 0 && memcmp(s1.ptr, s2.ptr, s1.len) != 0));
}
-inline string string::substring(int i, int n) const
+inline string string::substring(size_t i, size_t n) const
{
- assert((i >= 0) && ((i + n) <= len));
+ assert((i + n) <= len);
return string(ptr + i, n);
}
@@ -188,7 +189,7 @@ inline string &string::operator+=(char c)
void put_string(const string &, FILE *);
-string as_string(int);
+string as_string(size_t);
#endif // GROFF_STRINGCLASS_H
diff --git a/src/libs/libgroff/string.cpp b/src/libs/libgroff/string.cpp
index 06e2586c5..cd821fbf5 100644
--- a/src/libs/libgroff/string.cpp
+++ b/src/libs/libgroff/string.cpp
@@ -39,7 +39,7 @@ along with this program. If not, see
<http://www.gnu.org/licenses/>. */
// TODO 1: Replace all this memory management stuff with vector<char>.
// TODO 2: Replace this entire class. See Savannah #67735.
-static char *salloc(int len, int *sizep)
+static char *salloc(size_t len, size_t *sizep)
{
if (0 == len) {
*sizep = 0;
@@ -59,12 +59,13 @@ static char *salloc(int len, int *sizep)
return p;
}
-static void sfree(char *ptr, int)
+static void sfree(char *ptr, size_t)
{
delete[] ptr;
}
-static char *sfree_alloc(char *ptr, int oldsz, int len, int *sizep)
+static char *sfree_alloc(char *ptr, size_t oldsz, size_t len,
+ size_t *sizep)
{
if (oldsz >= len) {
*sizep = oldsz;
@@ -89,8 +90,8 @@ static char *sfree_alloc(char *ptr, int oldsz, int len, int
*sizep)
return p;
}
-static char *srealloc(char *ptr, int oldsz, int oldlen, int newlen,
- int *sizep)
+static char *srealloc(char *ptr, size_t oldsz, size_t oldlen,
+ size_t newlen, size_t *sizep)
{
if (oldsz >= newlen) {
*sizep = oldsz;
@@ -124,9 +125,8 @@ string::string() : ptr(0 /* nullptr */), len(0), sz(0)
{
}
-string::string(const char *p, int n) : len(n)
+string::string(const char *p, size_t n) : len(n)
{
- assert(n >= 0);
ptr = salloc(n, &sz);
if (sz > 0)
memset(ptr, 0, sz);
@@ -225,7 +225,7 @@ string &string::operator+=(const char *p)
{
if (p != 0 /* nullptr */) {
size_t n = strlen(p);
- int newlen = len + n;
+ size_t newlen = len + n;
if (newlen > sz)
ptr = srealloc(ptr, sz, len, newlen, &sz);
memcpy(ptr + len, p, n);
@@ -237,7 +237,7 @@ string &string::operator+=(const char *p)
string &string::operator+=(const string &s)
{
if (s.len != 0) {
- int newlen = len + s.len;
+ size_t newlen = len + s.len;
if (newlen > sz)
ptr = srealloc(ptr, sz, len, newlen, &sz);
memcpy(ptr + len, s.ptr, s.len);
@@ -246,10 +246,10 @@ string &string::operator+=(const string &s)
return *this;
}
-void string::append(const char *p, int n)
+void string::append(const char *p, size_t n)
{
if (n > 0) {
- int newlen = len + n;
+ size_t newlen = len + n;
if (newlen > sz)
ptr = srealloc(ptr, sz, len, newlen, &sz);
memcpy(ptr + len, p, n);
@@ -257,9 +257,8 @@ void string::append(const char *p, int n)
}
}
-string::string(const char *s1, int n1, const char *s2, int n2)
+string::string(const char *s1, size_t n1, const char *s2, size_t n2)
{
- assert((n1 >= 0) && (n2 >= 0));
len = n1 + n2;
if (0 == len) {
sz = 0;
@@ -305,9 +304,8 @@ bool operator>(const string &s1, const string &s2)
: ((s1.len != 0) && (memcmp(s1.ptr, s2.ptr, s1.len) > 0)));
}
-void string::set_length(int i)
+void string::set_length(size_t i)
{
- assert(i >= 0);
if (i > sz)
ptr = srealloc(ptr, sz, len, i, &sz);
len = i;
@@ -334,7 +332,7 @@ bool string::contains(const char c) const
}
// Return index of substring `c` in string, -1 if not found.
-int string::find(const char *c) const
+size_t string::find(const char *c) const
{
const char *p = ptr
? static_cast<const char *>(memmem(ptr, len, c,
@@ -349,9 +347,9 @@ int string::find(const char *c) const
char *string::extract() const
{
char *p = ptr;
- int n = len;
+ size_t n = len;
int nnuls = 0;
- int i;
+ size_t i;
for (i = 0; i < n; i++)
if (p[i] == '\0')
nnuls++;
@@ -438,8 +436,8 @@ void string::json_dump() const
void string::remove_spaces()
{
- int l = len - 1;
- while ((l >= 0) && (ptr[l] == ' '))
+ size_t l = len - 1;
+ while ((l < len) && (ptr[l] == ' '))
l--;
char *p = ptr;
if (l > 0)
@@ -448,45 +446,35 @@ void string::remove_spaces()
l--;
}
if (len - 1 != l) {
- if (l >= 0) {
- len = l + 1;
- char *tmp = 0 /* nullptr */;
- assert(sz > 0);
- try {
- tmp = new char[sz];
- }
- catch (const std::bad_alloc &exc) {
- fatal("cannot allocate %1 bytes for removal of spaces",
- " from string", sz);
- }
- memset(tmp, 0, sz);
- memcpy(tmp, p, len);
- delete[] ptr;
- ptr = tmp;
+ len = l + 1;
+ char *tmp = 0 /* nullptr */;
+ assert(sz > 0);
+ try {
+ tmp = new char[sz];
}
- else {
- len = 0;
- if (ptr) {
- delete[] ptr;
- ptr = 0 /* nullptr */;
- sz = 0;
- }
+ catch (const std::bad_alloc &exc) {
+ fatal("cannot allocate %1 bytes for removal of spaces",
+ " from string", sz);
}
+ memset(tmp, 0, sz);
+ memcpy(tmp, p, len);
+ delete[] ptr;
+ ptr = tmp;
}
}
void put_string(const string &s, FILE *fp)
{
- int len = s.length();
+ size_t len = s.length();
const char *ptr = s.contents();
- for (int i = 0; i < len; i++)
+ for (size_t i = 0; i < len; i++)
putc(ptr[i], fp);
}
-string as_string(int i)
+string as_string(size_t i)
{
static char buf[INT_DIGITS + 2];
- sprintf(buf, "%d", i);
+ sprintf(buf, "%lu", i);
return string(buf);
}
diff --git a/src/preproc/eqn/lex.cpp b/src/preproc/eqn/lex.cpp
index 4e2370a1d..4f53b904e 100644
--- a/src/preproc/eqn/lex.cpp
+++ b/src/preproc/eqn/lex.cpp
@@ -689,7 +689,7 @@ static void add_quoted_context(const string &s)
{
string &r = context_ring[context_index];
r = '"';
- for (int i = 0; i < s.length(); i++)
+ for (size_t i = 0; i < s.length(); i++)
if (s[i] == '"')
r += "\\\"";
else
diff --git a/src/preproc/preconv/preconv.cpp b/src/preproc/preconv/preconv.cpp
index 05263125a..cd13b5070 100644
--- a/src/preproc/preconv/preconv.cpp
+++ b/src/preproc/preconv/preconv.cpp
@@ -854,7 +854,7 @@ get_tag_lines(FILE *fp, string &data)
int newline_count = 0;
int c, prev = -1;
// Handle CR, LF, and CRLF as line separators.
- for (int i = 0; i < data.length(); i++) {
+ for (size_t i = 0; i < data.length(); i++) {
c = data[i];
if (c == '\n' || c == '\r')
newline_count++;
diff --git a/src/preproc/refer/label.ypp b/src/preproc/refer/label.ypp
index 7c8774340..a29eb84bd 100644
--- a/src/preproc/refer/label.ypp
+++ b/src/preproc/refer/label.ypp
@@ -34,7 +34,7 @@ static const char *format_serial(char c, int n);
struct label_info {
int start;
- int length;
+ size_t length;
int count;
int total;
label_info(const string &);
@@ -785,7 +785,7 @@ void truncate_expr::evaluate(int tentative, const reference
&ref,
void alternative_expr::evaluate(int tentative, const reference &ref,
string &result, substring_position &pos)
{
- int start_length = result.length();
+ size_t start_length = result.length();
if (expr1)
expr1->evaluate(tentative, ref, result, pos);
if (result.length() == start_length && expr2)
@@ -804,7 +804,7 @@ void list_expr::evaluate(int tentative, const reference
&ref,
void substitute_expr::evaluate(int tentative, const reference &ref,
string &result, substring_position &pos)
{
- int start_length = result.length();
+ size_t start_length = result.length();
if (expr1)
expr1->evaluate(tentative, ref, result, pos);
if (result.length() > start_length && result[result.length() - 1] == '-') {
@@ -1111,11 +1111,11 @@ int same_author_name(const reference &r1, const
reference &r2, int n)
void int_set::set(int i)
{
assert(i >= 0);
- int bytei = i >> 3;
+ size_t bytei = i >> 3;
if (bytei >= v.length()) {
int old_length = v.length();
v.set_length(bytei + 1);
- for (int j = old_length; j <= bytei; j++)
+ for (size_t j = old_length; j <= bytei; j++)
v[j] = 0;
}
v[bytei] |= 1 << (i & 7);
@@ -1124,7 +1124,7 @@ void int_set::set(int i)
int int_set::get(int i) const
{
assert(i >= 0);
- int bytei = i >> 3;
+ size_t bytei = i >> 3;
return bytei >= v.length() ? 0 : (v[bytei] & (1 << (i & 7))) != 0;
}
diff --git a/src/preproc/refer/ref.cpp b/src/preproc/refer/ref.cpp
index 778af6f22..95917c8ef 100644
--- a/src/preproc/refer/ref.cpp
+++ b/src/preproc/refer/ref.cpp
@@ -471,7 +471,7 @@ void reference::sortify_authors(int n, string &result) const
void reference::canonicalize_authors(string &result) const
{
- int len = result.length();
+ size_t len = result.length();
sortify_authors(INT_MAX, result);
if (result.length() > len)
result += SORT_SUB_SEP;
diff --git a/src/preproc/tbl/table.cpp b/src/preproc/tbl/table.cpp
index fdceaa5b4..7fbbb26d5 100644
--- a/src/preproc/tbl/table.cpp
+++ b/src/preproc/tbl/table.cpp
@@ -1538,7 +1538,7 @@ void table::add_entry(int r, int c, const string &str,
{
allocate(r);
table_entry *e = 0 /* nullptr */;
- int len = str.length();
+ size_t len = str.length();
char *s = str.extract();
// Diagnose escape sequences that can wreak havoc in generated output.
if (len > 1) {
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit