Browse Source

ImStrv: standardized code doing format copy, optimized ImStrStr

ocornut 4 years ago
parent
commit
6adee92a1e
2 changed files with 58 additions and 34 deletions
  1. 10 13
      imgui.cpp
  2. 48 21
      imgui_widgets.cpp

+ 10 - 13
imgui.cpp

@@ -2182,22 +2182,19 @@ const char* ImStristr(const char* haystack, const char* haystack_end, const char
     return NULL;
     return NULL;
 }
 }
 
 
-// FIXME-IMSTR: probably unneeded.
 const char* ImStrstr(ImStrv haystack, ImStrv needle)
 const char* ImStrstr(ImStrv haystack, ImStrv needle)
 {
 {
     const char un0 = (char)*needle.Begin;
     const char un0 = (char)*needle.Begin;
-    while ((!haystack.End && *haystack.Begin) || (haystack.End && haystack.Begin < haystack.End))
-    {
-        if (*haystack.Begin == un0)
-        {
-            const char* b = needle.Begin + 1;
-            for (const char* a = haystack.Begin + 1; b < needle.End; a++, b++)
-                if (*a != *b)
-                    break;
-            if (b == needle.End)
-                return haystack.Begin;
-        }
-        haystack.Begin++;
+    const char* p = haystack.Begin;
+    const size_t needle_len_m1 = needle.length() - 1;
+    while (true)
+    {
+        p = (const char*)memchr(p, un0, haystack.End - p);
+        if (p == NULL || (size_t)(haystack.End - p) - 1u < needle_len_m1)
+            return NULL;
+        if (needle_len_m1 == 0 || memcmp(p + 1, needle.Begin + 1, needle_len_m1) == 0)
+            return p;
+        p += 1;
     }
     }
     return NULL;
     return NULL;
 }
 }

+ 48 - 21
imgui_widgets.cpp

@@ -2684,14 +2684,20 @@ bool ImGui::DragScalar(ImStrv label, ImGuiDataType data_type, void* p_data, floa
         return false;
         return false;
 
 
     // FIXME-IMSTR
     // FIXME-IMSTR
-    char format_0[64];  // format may not end with \0
-    const char* format = format_0;
-    IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
-    ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
-
-    // Default format string when passing NULL
+    const char* format;
+    char format_buf[64];
     if (!format_p)
     if (!format_p)
+    {
+        // Default format string when passing NULL
         format = DataTypeGetInfo(data_type)->PrintFmt;
         format = DataTypeGetInfo(data_type)->PrintFmt;
+    }
+    else
+    {
+        // Copy format string (format may not be zero-terminated)
+        format = format_buf;
+        IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_buf));
+        ImStrncpy(format_buf, format_p, IM_ARRAYSIZE(format_buf));
+    }
 
 
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
     bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
@@ -3296,13 +3302,20 @@ bool ImGui::SliderScalar(ImStrv label, ImGuiDataType data_type, void* p_data, co
         return false;
         return false;
 
 
     // FIXME-IMSTR
     // FIXME-IMSTR
-    char format_0[64];  // format may not end with \0
-    const char* format = format_0;
-    IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
-
-    // Default format string when passing NULL
+    const char* format;
+    char format_buf[64];
     if (!format_p)
     if (!format_p)
+    {
+        // Default format string when passing NULL
         format = DataTypeGetInfo(data_type)->PrintFmt;
         format = DataTypeGetInfo(data_type)->PrintFmt;
+    }
+    else
+    {
+        // Copy format string (format may not be zero-terminated)
+        format = format_buf;
+        IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_buf));
+        ImStrncpy(format_buf, format_p, IM_ARRAYSIZE(format_buf));
+    }
 
 
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
     bool temp_input_is_active = temp_input_allowed && TempInputIsActive(id);
@@ -3472,13 +3485,20 @@ bool ImGui::VSliderScalar(ImStrv label, const ImVec2& size, ImGuiDataType data_t
         return false;
         return false;
 
 
     // FIXME-IMSTR
     // FIXME-IMSTR
-    char format_0[64];  // format may not end with \0
-    const char* format = format_0;
-    IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
-
-    // Default format string when passing NULL
+    const char* format;
+    char format_buf[64];
     if (!format_p)
     if (!format_p)
+    {
+        // Default format string when passing NULL
         format = DataTypeGetInfo(data_type)->PrintFmt;
         format = DataTypeGetInfo(data_type)->PrintFmt;
+    }
+    else
+    {
+        // Copy format string (format may not be zero-terminated)
+        format = format_buf;
+        IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_buf));
+        ImStrncpy(format_buf, format_p, IM_ARRAYSIZE(format_buf));
+    }
 
 
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.ItemFlags);
     const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
     const bool clicked = hovered && IsMouseClicked(0, ImGuiInputFlags_None, id);
@@ -3764,13 +3784,20 @@ bool ImGui::InputScalar(ImStrv label, ImGuiDataType data_type, void* p_data, con
     IM_ASSERT((flags & ImGuiInputTextFlags_EnterReturnsTrue) == 0); // Not supported by InputScalar(). Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit()!
     IM_ASSERT((flags & ImGuiInputTextFlags_EnterReturnsTrue) == 0); // Not supported by InputScalar(). Please open an issue if you this would be useful to you. Otherwise use IsItemDeactivatedAfterEdit()!
 
 
     // FIXME-IMSTR
     // FIXME-IMSTR
-    char format_0[64];  // format may not end with \0
-    const char* format = format_0;
-    IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_0));
-    ImStrncpy(format_0, format_p, IM_ARRAYSIZE(format_0));
-
+    const char* format;
+    char format_buf[64];
     if (!format_p)
     if (!format_p)
+    {
+        // Default format string when passing NULL
         format = DataTypeGetInfo(data_type)->PrintFmt;
         format = DataTypeGetInfo(data_type)->PrintFmt;
+    }
+    else
+    {
+        // Copy format string (format may not be zero-terminated)
+        format = format_buf;
+        IM_ASSERT(format_p.End - format_p.Begin < IM_ARRAYSIZE(format_buf));
+        ImStrncpy(format_buf, format_p, IM_ARRAYSIZE(format_buf));
+    }
 
 
     void* p_data_default = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue;
     void* p_data_default = (g.NextItemData.HasFlags & ImGuiNextItemDataFlags_HasRefVal) ? &g.NextItemData.RefVal : &g.DataTypeZeroValue;