Home | History | Annotate | Download | only in ipclist
      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