+++ ./protoc-gen-c/c_helpers.h @@ -65,6 +65,7 @@ #define PROTOBUF_C_PROTOC_GEN_C_C_HELPERS_H__ #include +#include #include #include @@ -196,6 +197,19 @@ # define GOOGLE_LOG ABSL_LOG #endif +// std::string_view versions of above functions +static inline std::string CEscape(const std::string_view& src) { return CEscape(std::string{src}); } +static inline std::string CamelToUpper(const std::string_view &class_name) { return CamelToUpper(std::string{class_name}); } +static inline std::string CamelToLower(const std::string_view &class_name) { return CamelToLower(std::string{class_name}); } +static inline std::string ToCamel(const std::string_view &name) { return ToCamel(std::string{name}); } +static inline std::string ToLower(const std::string_view &class_name) { return ToLower(std::string{class_name}); } +static inline std::string ToUpper(const std::string_view &class_name) { return ToUpper(std::string{class_name}); } +static inline std::string FullNameToLower(const std::string_view &full_name, const google::protobuf::FileDescriptor *file) { return FullNameToLower(std::string{full_name}, file); } +static inline std::string FullNameToUpper(const std::string_view &full_name, const google::protobuf::FileDescriptor *file) { return FullNameToUpper(std::string{full_name}, file); } +static inline std::string FullNameToC(const std::string_view &class_name, const google::protobuf::FileDescriptor *file) { return FullNameToC(std::string{class_name}, file); } +static inline std::string StripProto(const std::string_view& filename) { return StripProto(std::string{filename}); } +static inline std::string FilenameIdentifier(const std::string_view& filename) { return FilenameIdentifier(std::string{filename}); } + } // namespace protobuf_c #endif // PROTOBUF_C_PROTOC_GEN_C_C_HELPERS_H__ +++ ./protoc-gen-c/c_enum_field.cc @@ -78,7 +78,7 @@ (*variables)["type"] = FullNameToC(descriptor->enum_type()->full_name(), descriptor->enum_type()->file()); const google::protobuf::EnumValueDescriptor* default_value = descriptor->default_value_enum(); (*variables)["default"] = FullNameToUpper(default_value->type()->full_name(), default_value->type()->file()) - + "__" + default_value->name(); + + "__" + std::string{default_value->name()}; (*variables)["deprecated"] = FieldDeprecated(descriptor); } +++ ./protoc-gen-c/c_enum.cc @@ -152,7 +152,7 @@ descriptor_->file()->options().optimize_for() == google::protobuf::FileOptions_OptimizeMode_CODE_SIZE; vars["enum_value_name"] = vd->name(); - vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + vd->name(); + vars["c_enum_value_name"] = FullNameToUpper(descriptor_->full_name(), descriptor_->file()) + "__" + std::string{vd->name()}; vars["value"] = SimpleItoa(vd->number()); if (optimize_code_size) printer->Print(vars, " { NULL, NULL, $value$ }, /* CODE_SIZE */\n"); @@ -194,18 +194,29 @@ // Sort by name and value, dropping duplicate values if they appear later. // TODO: use a c++ paradigm for this! - NameIndex *name_index = new NameIndex[descriptor_->value_count()]; - ValueIndex *value_index = new ValueIndex[descriptor_->value_count()]; + struct _ValueIndex { + int value; + unsigned index; + unsigned final_index; /* index in uniqified array of values */ + const google::protobuf::EnumValueDescriptor *vd; + }; + _ValueIndex *value_index = new _ValueIndex[descriptor_->value_count()]; for (int j = 0; j < descriptor_->value_count(); j++) { - const google::protobuf::EnumValueDescriptor *vd = descriptor_->value(j); - name_index[j].index = j; - name_index[j].name = vd->name().c_str(); + value_index[j].vd = descriptor_->value(j); value_index[j].index = j; - value_index[j].value = vd->number(); - value_index[j].name = vd->name().c_str(); + value_index[j].value = value_index[j].vd->number(); } qsort(value_index, descriptor_->value_count(), - sizeof(ValueIndex), compare_value_indices_by_value_then_index); + sizeof(_ValueIndex), [](const void *a, const void *b) -> int { + const _ValueIndex *vi_a = static_cast(a); + const _ValueIndex *vi_b = static_cast(b); + + if (vi_a->value < vi_b->value) return -1; + if (vi_a->value > vi_b->value) return +1; + if (vi_a->index < vi_b->index) return -1; + if (vi_a->index > vi_b->index) return +1; + return 0; + }); // only record unique values int n_unique_values; @@ -276,13 +287,17 @@ if (!optimize_code_size) { qsort(value_index, descriptor_->value_count(), - sizeof(ValueIndex), compare_value_indices_by_name); + sizeof(_ValueIndex), [](const void *a, const void *b) -> int { + const _ValueIndex *vi_a = static_cast(a); + const _ValueIndex *vi_b = static_cast(b); + return strncmp(vi_a->vd->name().data(), vi_b->vd->name().data(), std::min(vi_a->vd->name().size(), vi_b->vd->name().size())); + }); printer->Print(vars, "static const ProtobufCEnumValueIndex $lcclassname$__enum_values_by_name[$value_count$] =\n" "{\n"); for (int j = 0; j < descriptor_->value_count(); j++) { vars["index"] = SimpleItoa(value_index[j].final_index); - vars["name"] = value_index[j].name; + vars["name"] = std::string{value_index[j].vd->name()}; printer->Print (vars, " { \"$name$\", $index$ },\n"); } printer->Print(vars, "};\n"); @@ -321,7 +336,6 @@ } delete[] value_index; - delete[] name_index; } } // namespace protobuf_c +++ ./protoc-gen-c/c_message.cc @@ -581,17 +581,25 @@ printer->Print(vars, "};\n"); if (!optimize_code_size) { - NameIndex *field_indices = new NameIndex [descriptor_->field_count()]; + struct _NameIndex { + unsigned index; + const google::protobuf::FieldDescriptor* field; + }; + _NameIndex *field_indices = new _NameIndex [descriptor_->field_count()]; for (int i = 0; i < descriptor_->field_count(); i++) { - field_indices[i].name = sorted_fields[i]->name().c_str(); + field_indices[i].field = sorted_fields[i]; field_indices[i].index = i; } - qsort (field_indices, descriptor_->field_count(), sizeof (NameIndex), - compare_name_indices_by_name); + qsort (field_indices, descriptor_->field_count(), sizeof (_NameIndex), + [](const void *a, const void *b) -> int { + const _NameIndex *vi_a = static_cast(a); + const _NameIndex *vi_b = static_cast(b); + return strncmp(vi_a->field->name().data(), vi_b->field->name().data(), std::min(vi_a->field->name().size(), vi_b->field->name().size())); + }); printer->Print(vars, "static const unsigned $lcclassname$__field_indices_by_name[] = {\n"); for (int i = 0; i < descriptor_->field_count(); i++) { vars["index"] = SimpleItoa(field_indices[i].index); - vars["name"] = field_indices[i].name; + vars["name"] = std::string{field_indices[i].field->name()}; printer->Print(vars, " $index$, /* field[$index$] = $name$ */\n"); } printer->Print("};\n"); +++ ./protoc-gen-c/c_service.cc @@ -184,13 +184,13 @@ "}\n"); } -struct MethodIndexAndName { unsigned i; const char *name; }; +struct MethodIndexAndName { unsigned i; const google::protobuf::MethodDescriptor* method; }; static int compare_method_index_and_name_by_name (const void *a, const void *b) { const MethodIndexAndName *ma = (const MethodIndexAndName *) a; const MethodIndexAndName *mb = (const MethodIndexAndName *) b; - return strcmp (ma->name, mb->name); + return strncmp (ma->method->name().data(), mb->method->name().data(), std::min(ma->method->name().size(), ma->method->name().size())); } void ServiceGenerator::GenerateServiceDescriptor(google::protobuf::io::Printer* printer) @@ -218,7 +218,7 @@ " { \"$method$\", $input_descriptor$, $output_descriptor$ },\n"); } mi_array[i].i = i; - mi_array[i].name = method->name().c_str(); + mi_array[i].method = method; } printer->Print(vars_, "};\n"); @@ -228,7 +228,7 @@ printer->Print(vars_, "const unsigned $lcfullname$__method_indices_by_name[] = {\n"); for (int i = 0; i < n_methods; i++) { vars_["i"] = SimpleItoa(mi_array[i].i); - vars_["name"] = mi_array[i].name; + vars_["name"] = std::string{mi_array[i].method->name()}; vars_["comma"] = (i + 1 < n_methods) ? "," : " "; printer->Print(vars_, " $i$$comma$ /* $name$ */\n"); }