@@ -117,6 +117,62 @@ namespace /* anonymous */
117117
118118#endif /* __MINGW32__ */
119119
120+
121+ /* *
122+ * Look for a common symbol prefix.
123+ * Many APIs share a common prefix among their symbols.
124+ * If you want to load a specific symbol we can use this
125+ * later for a faster lookup.
126+ */
127+ std::string get_common_prefix (vproto_t &v_prototypes, vproto_t &v_objects)
128+ {
129+ vstring_t vec;
130+ size_t n;
131+
132+ /* copy symbol names */
133+ for (const auto &e : v_prototypes) {
134+ vec.push_back (e.symbol );
135+ }
136+
137+ for (const auto &e : v_objects) {
138+ vec.push_back (e.symbol );
139+ }
140+
141+ /* need at least 2 symbols */
142+ if (vec.size () < 2 ) {
143+ return {};
144+ }
145+
146+ /* get shortest symbol length */
147+ size_t shortest_sym_len = vec.front ().size ();
148+
149+ /* skip first entry */
150+ for (auto it = vec.begin () + 1 ; it != vec.end (); it++) {
151+ /* prevent `min()' macro expansion from Windows headers */
152+ shortest_sym_len = std::min<size_t >(shortest_sym_len, (*it).size ());
153+ }
154+
155+ /* compare each letter of every entry */
156+ for (n = 0 ; n < shortest_sym_len; n++) {
157+ /* skip first entry */
158+ for (auto it = vec.begin () + 1 ; it != vec.end (); it++) {
159+ if ((*it).empty ()) {
160+ return {};
161+ }
162+
163+ /* compare against first entry */
164+ if ((*it).at (n) != vec.front ().at (n)) {
165+ /* common prefix found (can be empty) */
166+ return vec.at (0 ).substr (0 , n);
167+ }
168+ }
169+ }
170+
171+ /* shortest symbol name equals prefix, i.e. if a symbol `foo'
172+ * and `foobar' exist the prefix is `foo' */
173+ return vec.at (0 ).substr (0 , n);
174+ }
175+
120176} /* end anonymous namespace */
121177
122178
@@ -409,16 +465,6 @@ void gendlopen::generate()
409465 bool is_cxx = false ;
410466 size_t lines = 0 ;
411467
412- /* whether to generate a symbol lookup macro and
413- * where to save it */
414- enum {
415- GEN_MACRO_NONE,
416- GEN_MACRO_HEADER,
417- GEN_MACRO_BODY
418- };
419-
420- int gen_macro = GEN_MACRO_NONE;
421-
422468 /* ************ lambda functions *************/
423469
424470 auto lf_print_lineno = [&, this ] () {
@@ -465,11 +511,6 @@ void gendlopen::generate()
465511 lines += save::extra_defines (m_defines);
466512 lines += save::includes (m_includes, is_cxx);
467513 lines += save::typedefs (m_typedefs);
468-
469- /* save macro in header */
470- if (gen_macro == GEN_MACRO_HEADER) {
471- lines += save::symbol_name_lookup (m_pfx_upper, m_prototypes, m_objects);
472- }
473514 };
474515
475516 auto lf_header_template_data = [&] () {
@@ -488,11 +529,6 @@ void gendlopen::generate()
488529 save::ofs << " #define " << m_pfx_upper << " _INCLUDED_IN_BODY\n " ;
489530 save::ofs << " #include \" " << header_name << " \"\n " ;
490531 save::ofs << ' \n ' ;
491-
492- /* save macro in body */
493- if (gen_macro == GEN_MACRO_BODY) {
494- save::symbol_name_lookup (m_pfx_upper, m_prototypes, m_objects);
495- }
496532 };
497533
498534 auto lf_body_template_data = [&] () {
@@ -516,11 +552,10 @@ void gendlopen::generate()
516552 switch (m_format)
517553 {
518554 case output::c:
519- gen_macro = m_separate ? GEN_MACRO_BODY : GEN_MACRO_HEADER;
555+ case output::plugin:
520556 break ;
521557
522558 case output::cxx:
523- gen_macro = GEN_MACRO_HEADER;
524559 is_cxx = true ;
525560 break ;
526561
@@ -533,9 +568,6 @@ void gendlopen::generate()
533568 is_cxx = true ;
534569 break ;
535570
536- case output::plugin:
537- break ;
538-
539571 [[unlikely]] case output::error:
540572 throw error (std::string (__func__) + " : m_format == output::error" );
541573 }
@@ -567,6 +599,10 @@ void gendlopen::generate()
567599 m_defines += " #define " + m_pfx_upper + " _HARDCODED_DEFAULT_LIBW " + lib_w + ' \n ' ;
568600 }
569601
602+ /* common symbol prefix (can be empty) */
603+ m_defines += " #define " + m_pfx_upper + " _COMMON_PREFIX "
604+ " \" " + get_common_prefix (m_prototypes, m_objects) + " \"\n " ;
605+
570606 /* create template data */
571607 create_template_lists (header_data, body_data);
572608
0 commit comments