[gnome-builder/wip/gtk4-port] libide/sourceview: add line number helper



commit 2fdd4c17e55e713c799b6790b1008591e71fee89
Author: Christian Hergert <chergert redhat com>
Date:   Mon Apr 11 14:37:15 2022 -0700

    libide/sourceview: add line number helper
    
    This will eventually get used in our omni-gutter-renderer.

 src/libide/sourceview/ide-text-util.c | 77 +++++++++++++++++++++++++++++++++++
 src/libide/sourceview/ide-text-util.h | 11 +++--
 2 files changed, 84 insertions(+), 4 deletions(-)
---
diff --git a/src/libide/sourceview/ide-text-util.c b/src/libide/sourceview/ide-text-util.c
index f166a1191..7b7f163d2 100644
--- a/src/libide/sourceview/ide-text-util.c
+++ b/src/libide/sourceview/ide-text-util.c
@@ -181,3 +181,80 @@ ide_text_util_remove_common_prefix (GtkTextIter *begin,
       *begin = rm_begin;
     }
 }
+
+/*
+ * ide_text_util_int_to_string:
+ * @value: the integer to convert to a string
+ * @outstr: (out): a location for a pointer to the result string
+ *
+ * The following implementation uses an internal cache to speed up the
+ * conversion of integers to strings by comparing the value to the
+ * previous value that was calculated.
+ *
+ * If we detect a simple increment, we can alter the previous string directly
+ * and then carry the number to each of the previous chars sequentually. If we
+ * still have a carry bit at the end of the loop, we need to move the whole
+ * string over 1 place to take account for the new "1" at the start.
+ *
+ * This function is not thread-safe, as the resulting string is stored in
+ * static data.
+ *
+ * Returns: the number of characters in the resulting string
+ */
+int
+ide_text_util_int_to_string (guint        value,
+                             const char **outstr)
+{
+  static struct {
+    guint value;
+    int len;
+    char str[12];
+  } fi;
+
+  *outstr = fi.str;
+
+  if G_LIKELY (value == fi.value + 1)
+    {
+      guint carry = 1;
+
+      for (int i = fi.len - 1; i >= 0; i--)
+        {
+          fi.str[i] += carry;
+          carry = fi.str[i] == ':';
+
+          if (carry)
+            fi.str[i] = '0';
+          else
+            break;
+        }
+
+      if G_UNLIKELY (carry)
+        {
+          for (int i = fi.len; i > 0; i--)
+            fi.str[i] = fi.str[i-1];
+
+          fi.len++;
+          fi.str[0] = '1';
+          fi.str[fi.len] = 0;
+        }
+
+      fi.value++;
+
+      return fi.len;
+    }
+  else if (value == fi.value)
+    {
+      return fi.len;
+    }
+
+#ifdef G_OS_WIN32
+  fi.len = g_snprintf (fi.str, sizeof fi.str - 1, "%u", value);
+#else
+  /* Use snprintf() directly when possible to reduce overhead */
+  fi.len = snprintf (fi.str, sizeof fi.str - 1, "%u", value);
+#endif
+  fi.str[fi.len] = 0;
+  fi.value = value;
+
+  return fi.len;
+}
diff --git a/src/libide/sourceview/ide-text-util.h b/src/libide/sourceview/ide-text-util.h
index 2080ce3a5..786899bb7 100644
--- a/src/libide/sourceview/ide-text-util.h
+++ b/src/libide/sourceview/ide-text-util.h
@@ -31,10 +31,13 @@
 G_BEGIN_DECLS
 
 IDE_AVAILABLE_IN_ALL
-void ide_text_util_delete_line          (GtkTextView *text_view,
-                                         int         count);
+void ide_text_util_delete_line          (GtkTextView  *text_view,
+                                         int           count);
 IDE_AVAILABLE_IN_ALL
-void ide_text_util_remove_common_prefix (GtkTextIter *begin,
-                                         const gchar *prefix);
+void ide_text_util_remove_common_prefix (GtkTextIter  *begin,
+                                         const char   *prefix);
+IDE_AVAILABLE_IN_ALL
+int  ide_text_util_int_to_string        (guint         value,
+                                         const char  **outstr);
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]