/* make-dissectors.c * Tool to build the dissector registration arrays. * * Wireshark - Network traffic analyzer * By Gerald Combs * Copyright 1998 Gerald Combs * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #include #define ARRAY_RESERVED_SIZE 2048 #define STRING_RESERVED_SIZE (300 * 1024) #ifdef _WIN32 #define SEP "\r\n" #else #define SEP "\n" #endif GRegex *protos_regex, *handoffs_regex; static int compare_symbols(gconstpointer a, gconstpointer b) { return g_strcmp0(*(const char **)a, *(const char **)b); } static void scan_matches(GRegex *regex, const char *string, GPtrArray *dst) { GMatchInfo *match_info; char *match; g_regex_match(regex, string, G_REGEX_MATCH_NOTEMPTY, &match_info); while (g_match_info_matches(match_info)) { match = g_match_info_fetch(match_info, 1); g_ptr_array_add(dst, match); g_match_info_next(match_info, NULL); } g_match_info_free(match_info); } static void scan_file(const char *file, GPtrArray *protos, GPtrArray *handoffs) { char *contents; GError *err = NULL; if (!g_file_get_contents(file, &contents, NULL, &err)) { fprintf(stderr, "%s: %s\n", file, err->message); exit(1); } scan_matches(protos_regex, contents, protos); scan_matches(handoffs_regex, contents, handoffs); g_free(contents); } static void scan_list(const char *file, GPtrArray *protos, GPtrArray *handoffs) { char *contents, *arg; GError *err = NULL; if (!g_file_get_contents(file, &contents, NULL, NULL)) { fprintf(stderr, "%s: %s\n", file, err->message); exit(1); } for (arg = strtok(contents, SEP); arg != NULL; arg = strtok(NULL, SEP)) { scan_file(arg, protos, handoffs); } g_free(contents); } int main(int argc, char **argv) { GPtrArray *protos = NULL, *handoffs = NULL; GError *err = NULL; guint i; GString *s; const char *outfile; guint count_protos, count_handoffs; if (argc < 3) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } protos = g_ptr_array_new_full(ARRAY_RESERVED_SIZE, g_free); handoffs = g_ptr_array_new_full(ARRAY_RESERVED_SIZE, g_free); protos_regex = g_regex_new("void\\s+(proto_register_[[:alnum:]_]+)\\s*\\(\\s*void\\s*\\)\\s*{", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, &err); if (err) { fprintf(stderr, "GRegex: %s\n", err->message); exit(1); } handoffs_regex = g_regex_new("void\\s+(proto_reg_handoff_[[:alnum:]_]+)\\s*\\(\\s*void\\s*\\)\\s*{", G_REGEX_OPTIMIZE, G_REGEX_MATCH_NOTEMPTY, &err); if (err) { fprintf(stderr, "GRegex: %s\n", err->message); exit(1); } outfile = argv[1]; for (int arg = 2; arg < argc; arg++) { if (argv[arg][0] == '@') { scan_list(&argv[arg][1], protos, handoffs); } else { scan_file(argv[arg], protos, handoffs); } } if (protos->len == 0) { fprintf(stderr, "No protocol registrations found.\n"); exit(1); } g_ptr_array_sort(protos, compare_symbols); g_ptr_array_sort(handoffs, compare_symbols); s = g_string_sized_new(STRING_RESERVED_SIZE); g_string_append(s, "/*\n" " * Do not modify this file. Changes will be overwritten.\n" " *\n" " * Generated automatically by the \"dissectors.c\" target using\n" " * \"make-dissectors\".\n" " */\n" "\n" "#include \n" "\n"); g_string_append_printf(s, "const gulong dissector_reg_proto_count = %d;\n" "const gulong dissector_reg_handoff_count = %d;\n" "\n", protos->len, handoffs->len); for (i = 0; i < protos->len; i++) { g_string_append_printf(s, "void %s(void);\n", (char *)protos->pdata[i]); } g_string_append(s, "\n" "dissector_reg_t dissector_reg_proto[] = {\n"); for (i = 0; i < protos->len; i++) { g_string_append_printf(s, " { \"%s\", %s },\n", (char *)protos->pdata[i], (char *)protos->pdata[i]); } g_string_append(s, " { NULL, NULL }\n" "};\n" "\n"); for (i = 0; i < handoffs->len; i++) { g_string_append_printf(s, "void %s(void);\n", (char *)handoffs->pdata[i]); } g_string_append(s, "\n" "dissector_reg_t dissector_reg_handoff[] = {\n"); for (i = 0; i < handoffs->len; i++) { g_string_append_printf(s, " { \"%s\", %s },\n", (char *)handoffs->pdata[i], (char *)handoffs->pdata[i]); } g_string_append(s, " { NULL, NULL }\n" "};\n"); if (!g_file_set_contents(outfile, s->str, s->len, &err)) { fprintf(stderr, "%s: %s\n", outfile, err->message); exit(1); } count_protos = protos->len; count_handoffs = handoffs->len; g_string_free(s, TRUE); g_regex_unref(protos_regex); g_regex_unref(handoffs_regex); g_ptr_array_free(protos, TRUE); g_ptr_array_free(handoffs, TRUE); printf("Found %u registrations and %u handoffs.\n", count_protos, count_handoffs); } /* * Editor modelines * * Local Variables: * c-basic-offset: 4 * tab-width: 8 * indent-tabs-mode: nil * End: * * ex: set shiftwidth=4 tabstop=8 expandtab: * :indentSize=4:tabSize=8:noTabs=true: */