1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <algorithm> 6 #include <iostream> 7 #include <string> 8 #include <vector> 9 10 #include "base/basictypes.h" 11 12 // Include once to get the type definitions 13 #include "chrome/common/all_messages.h" 14 #include "content/common/all_messages.h" 15 16 struct msginfo { 17 const char* name; 18 int id; 19 int in_count; 20 int out_count; 21 22 bool operator< (const msginfo& other) const { 23 return id < other.id; 24 } 25 }; 26 27 // Redefine macros to generate table 28 #include "ipc/ipc_message_null_macros.h" 29 #undef IPC_MESSAGE_DECL 30 #define IPC_MESSAGE_DECL(kind, type, name, in, out, ilist, olist) \ 31 { #name, IPC_MESSAGE_ID(), in, out }, 32 33 static msginfo msgtable[] = { 34 #include "chrome/common/all_messages.h" 35 #include "content/common/all_messages.h" 36 }; 37 #define MSGTABLE_SIZE (sizeof(msgtable)/sizeof(msgtable[0])) 38 COMPILE_ASSERT(MSGTABLE_SIZE, CHECK_YOUR_HEADERS_FOR_AN_EXTRA_SEMICOLON); 39 40 static bool check_msgtable() { 41 bool result = true; 42 int previous_class_id = 0; 43 int highest_class_id = 0; 44 std::vector<int> exemptions; 45 46 // Exclude test and other non-browser files from consideration. Do not 47 // include message files used inside the actual chrome browser in this list. 48 exemptions.push_back(TestMsgStart); 49 exemptions.push_back(FirefoxImporterUnittestMsgStart); 50 exemptions.push_back(ShellMsgStart); 51 52 for (size_t i = 0; i < MSGTABLE_SIZE; ++i) { 53 int class_id = IPC_MESSAGE_ID_CLASS(msgtable[i].id); 54 if (class_id >= LastIPCMsgStart) { 55 std::cout << "Invalid LastIPCMsgStart setting\n"; 56 result = false; 57 } 58 while (class_id > previous_class_id + 1) { 59 std::vector<int>::iterator iter; 60 iter = find(exemptions.begin(), exemptions.end(), previous_class_id+1); 61 if (iter == exemptions.end()) { 62 std::cout << "Missing message file: gap before " << class_id << "\n"; 63 result = false; 64 break; 65 } 66 ++previous_class_id; 67 } 68 previous_class_id = class_id; 69 if (class_id > highest_class_id) 70 highest_class_id = class_id; 71 } 72 73 while (LastIPCMsgStart > highest_class_id + 1) { 74 std::vector<int>::iterator iter; 75 iter = find(exemptions.begin(), exemptions.end(), highest_class_id+1); 76 if (iter == exemptions.end()) { 77 std::cout << "Missing message file: gap before LastIPCMsgStart\n"; 78 result = false; 79 break; 80 } 81 ++highest_class_id; 82 } 83 84 if (!result) 85 std::cout << "Please check {chrome,content}/common/all_messages.h.\n"; 86 87 return result; 88 } 89 90 static void dump_msgtable(bool show_args, bool show_ids, 91 bool show_comma, const char *prefix) { 92 bool first = true; 93 for (size_t i = 0; i < MSGTABLE_SIZE; ++i) { 94 if ((!prefix) || strstr(msgtable[i].name, prefix) == msgtable[i].name) { 95 if (show_comma) { 96 if (!first) 97 std::cout << ","; 98 first = false; 99 std::cout << msgtable[i].id; 100 } else { 101 if (show_ids) 102 std::cout << msgtable[i].id << " " << 103 IPC_MESSAGE_ID_CLASS(msgtable[i].id) << "," << 104 IPC_MESSAGE_ID_LINE(msgtable[i].id) << " "; 105 std::cout << msgtable[i].name; 106 if (show_args) { 107 std::cout << "(" << msgtable[i].in_count << " IN, " << 108 msgtable[i].out_count << " OUT)"; 109 } 110 std::cout << "\n"; 111 } 112 } 113 } 114 if (show_comma) 115 std::cout << "\n"; 116 } 117 118 int main(int argc, char **argv) { 119 bool show_args = false; 120 bool show_ids = false; 121 bool skip_check = false; 122 bool show_comma = false; 123 const char *filter = NULL; 124 125 while (--argc > 0) { 126 ++argv; 127 if (std::string("--args") == *argv) { 128 show_args = true; 129 } else if (std::string("--comma") == *argv) { 130 show_comma = true; 131 } else if (std::string("--filter") == *argv) { 132 filter = *(++argv); 133 --argc; 134 } else if (std::string("--ids") == *argv) { 135 show_ids = true; 136 } else if (std::string("--no-check") == *argv) { 137 skip_check = true; 138 } else { 139 std::cout << 140 "usage: ipclist [--args] [--ids] [--no-check] [--filter prefix] " 141 "[--comma]\n"; 142 return 1; 143 } 144 } 145 146 std::sort(msgtable, msgtable + MSGTABLE_SIZE); 147 148 if (!skip_check && check_msgtable() == false) 149 return 1; 150 151 dump_msgtable(show_args, show_ids, show_comma, filter); 152 return 0; 153 } 154 155