+/* Helper function to check for a generic list of prefixes. GDBARCH
+ is the current gdbarch being used. S is the expression being
+ analyzed. If R is not NULL, it will be used to return the found
+ prefix. PREFIXES is the list of expected prefixes.
+
+ This function does a case-insensitive match.
+
+ Return true if any prefix has been found, false otherwise. */
+
+static bool
+stap_is_generic_prefix (struct gdbarch *gdbarch, const char *s,
+ const char **r, const char *const *prefixes)
+{
+ const char *const *p;
+
+ if (prefixes == NULL)
+ {
+ if (r != NULL)
+ *r = "";
+
+ return true;
+ }
+
+ for (p = prefixes; *p != NULL; ++p)
+ if (strncasecmp (s, *p, strlen (*p)) == 0)
+ {
+ if (r != NULL)
+ *r = *p;
+
+ return true;
+ }
+
+ return false;
+}
+
+/* Return true if S points to a register prefix, false otherwise. For
+ a description of the arguments, look at stap_is_generic_prefix. */
+
+static bool
+stap_is_register_prefix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *t = gdbarch_stap_register_prefixes (gdbarch);
+
+ return stap_is_generic_prefix (gdbarch, s, r, t);
+}
+
+/* Return true if S points to a register indirection prefix, false
+ otherwise. For a description of the arguments, look at
+ stap_is_generic_prefix. */
+
+static bool
+stap_is_register_indirection_prefix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *t = gdbarch_stap_register_indirection_prefixes (gdbarch);
+
+ return stap_is_generic_prefix (gdbarch, s, r, t);
+}
+
+/* Return true if S points to an integer prefix, false otherwise. For
+ a description of the arguments, look at stap_is_generic_prefix.
+
+ This function takes care of analyzing whether we are dealing with
+ an expected integer prefix, or, if there is no integer prefix to be
+ expected, whether we are dealing with a digit. It does a
+ case-insensitive match. */
+
+static bool
+stap_is_integer_prefix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *t = gdbarch_stap_integer_prefixes (gdbarch);
+ const char *const *p;
+
+ if (t == NULL)
+ {
+ /* A NULL value here means that integers do not have a prefix.
+ We just check for a digit then. */
+ if (r != NULL)
+ *r = "";
+
+ return isdigit (*s) > 0;
+ }
+
+ for (p = t; *p != NULL; ++p)
+ {
+ size_t len = strlen (*p);
+
+ if ((len == 0 && isdigit (*s))
+ || (len > 0 && strncasecmp (s, *p, len) == 0))
+ {
+ /* Integers may or may not have a prefix. The "len == 0"
+ check covers the case when integers do not have a prefix
+ (therefore, we just check if we have a digit). The call
+ to "strncasecmp" covers the case when they have a
+ prefix. */
+ if (r != NULL)
+ *r = *p;
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* Helper function to check for a generic list of suffixes. If we are
+ not expecting any suffixes, then it just returns 1. If we are
+ expecting at least one suffix, then it returns true if a suffix has
+ been found, false otherwise. GDBARCH is the current gdbarch being
+ used. S is the expression being analyzed. If R is not NULL, it
+ will be used to return the found suffix. SUFFIXES is the list of
+ expected suffixes. This function does a case-insensitive
+ match. */
+
+static bool
+stap_generic_check_suffix (struct gdbarch *gdbarch, const char *s,
+ const char **r, const char *const *suffixes)
+{
+ const char *const *p;
+ bool found = false;
+
+ if (suffixes == NULL)
+ {
+ if (r != NULL)
+ *r = "";
+
+ return true;
+ }
+
+ for (p = suffixes; *p != NULL; ++p)
+ if (strncasecmp (s, *p, strlen (*p)) == 0)
+ {
+ if (r != NULL)
+ *r = *p;
+
+ found = true;
+ break;
+ }
+
+ return found;
+}
+
+/* Return true if S points to an integer suffix, false otherwise. For
+ a description of the arguments, look at
+ stap_generic_check_suffix. */
+
+static bool
+stap_check_integer_suffix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *p = gdbarch_stap_integer_suffixes (gdbarch);
+
+ return stap_generic_check_suffix (gdbarch, s, r, p);
+}
+
+/* Return true if S points to a register suffix, false otherwise. For
+ a description of the arguments, look at
+ stap_generic_check_suffix. */
+
+static bool
+stap_check_register_suffix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *p = gdbarch_stap_register_suffixes (gdbarch);
+
+ return stap_generic_check_suffix (gdbarch, s, r, p);
+}
+
+/* Return true if S points to a register indirection suffix, false
+ otherwise. For a description of the arguments, look at
+ stap_generic_check_suffix. */
+
+static bool
+stap_check_register_indirection_suffix (struct gdbarch *gdbarch, const char *s,
+ const char **r)
+{
+ const char *const *p = gdbarch_stap_register_indirection_suffixes (gdbarch);
+
+ return stap_generic_check_suffix (gdbarch, s, r, p);
+}
+