Add unit testing to CLD. In addition, remove files from cld/base which are not required, yet were creating compile errors when building unit_tests.
BUG=none TEST=none Review URL: http://codereview.chromium.org/132032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@19190 0039d316-1c4b-4281-b951-d872f2087c98
Esse commit está contido em:
@@ -3314,6 +3314,14 @@
|
||||
'include_dirs': [
|
||||
'..',
|
||||
],
|
||||
'defines': [
|
||||
'CLD_WINDOWS',
|
||||
],
|
||||
'direct_dependent_settings': {
|
||||
'defines': [
|
||||
'CLD_WINDOWS',
|
||||
],
|
||||
},
|
||||
'sources': [
|
||||
'app/breakpad_mac_stubs.mm',
|
||||
# *NO* files in chrome/app have unit tests (except keystone_glue)!!!
|
||||
@@ -3539,6 +3547,7 @@
|
||||
'test/test_notification_tracker.h',
|
||||
'test/v8_unit_test.cc',
|
||||
'test/v8_unit_test.h',
|
||||
'../third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/compact_lang_det_unittest_small.cc',
|
||||
|
||||
'../views/controls/label_unittest.cc',
|
||||
'../views/controls/table/table_view_unittest.cc',
|
||||
@@ -3561,6 +3570,8 @@
|
||||
# might want to write our own tests for the download manager
|
||||
# on linux, though.
|
||||
'browser/download/download_manager_unittest.cc',
|
||||
# Compact Language Detection (cld) is not supported in linux yet.
|
||||
'../third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/compact_lang_det_unittest_small.cc',
|
||||
],
|
||||
}],
|
||||
['OS=="linux" and toolkit_views==1', {
|
||||
@@ -3588,6 +3599,9 @@
|
||||
'test/test_notification_tracker.cc',
|
||||
'test/test_notification_tracker.h',
|
||||
'third_party/hunspell/google/hunspell_tests.cc',
|
||||
|
||||
# Compact Language Detection (cld) is not supported in mac yet.
|
||||
'../third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/compact_lang_det_unittest_small.cc',
|
||||
],
|
||||
# TODO(mark): We really want this for all non-static library targets,
|
||||
# but when we tried to pull it up to the common.gypi level, it broke
|
||||
|
||||
externo
+391
@@ -0,0 +1,391 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Unit test compact language detector
|
||||
//
|
||||
// Small version, covering these languages only:
|
||||
// Arabic Bulgarian Catalan Chinese ChineseT Croatian Czech Danish Dutch
|
||||
// English Estonian Finnish French German Greek Hebrew Hindi Hungarian
|
||||
// Icelandic Indonesian Italian Japanese Korean Latvian Lithuanian Norwegian
|
||||
// Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish
|
||||
// Swedish Tagalog Thai Turkish Ukrainian Vietnamese
|
||||
|
||||
// Additional single-language scripts recognized for free:
|
||||
// Armenian Cherokee Dhivehi Georgian Gujarati Inuktitut Kannada Khmer
|
||||
// Laothian Malayalam Oriya Punjabi Sinhalese Syriac Telugu Tamil
|
||||
//
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/compact_lang_det.h"
|
||||
#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/ext_lang_enc.h"
|
||||
#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/unittest_data.h"
|
||||
|
||||
#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/win/cld_commandlineflags.h"
|
||||
#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/win/cld_google.h"
|
||||
|
||||
//DEFINE_bool(html, false, "Print language spans in HTML on stderr");
|
||||
//DEFINE_bool(detail, false, "Print incoming text to stderr");
|
||||
//DEFINE_bool(skipbig, false, "Skip BigInputTests");
|
||||
|
||||
// Test strings.
|
||||
// These are all included here to make the unit test self-contained.
|
||||
const char* kTeststr_en =
|
||||
"confiscation of goods is assigned as the penalty part most of the courts "
|
||||
"consist of members and when it is necessary to bring public cases before a "
|
||||
"jury of members two courts combine for the purpose the most important cases "
|
||||
"of all are brought jurors or";
|
||||
|
||||
|
||||
// UTF8 constants. Use a UTF-8 aware editor for this file
|
||||
const char* kTeststr_ks =
|
||||
"नेपाल एसिया "
|
||||
"मंज अख मुलुक"
|
||||
" राजधानी काठ"
|
||||
"माडौं नेपाल "
|
||||
"अधिराज्य पेर"
|
||||
"ेग्वाय "
|
||||
"दक्षिण अमेरि"
|
||||
"का महाद्वीपे"
|
||||
" मध् यक्षेत्"
|
||||
"रे एक देश अस"
|
||||
"् ति फणीश्वर"
|
||||
" नाथ रेणु "
|
||||
"फिजी छु दक्ष"
|
||||
"िण प्रशान् त"
|
||||
" महासागर मंज"
|
||||
" अख देश बहाम"
|
||||
"ास छु केरेबि"
|
||||
"यन मंज "
|
||||
"अख मुलुख राज"
|
||||
"धानी नसौ सम्"
|
||||
" बद्घ विषय ब"
|
||||
"ुरुंडी अफ्री"
|
||||
"का महाद्वीपे"
|
||||
" मध् "
|
||||
"यक्षेत्रे दे"
|
||||
"श अस् ति सम्"
|
||||
" बद्घ विषय";
|
||||
|
||||
// const char* kTeststr_ks =
|
||||
// \u0928\u0947\u092A\u093E\u0932\u0020\u090F\u0938\u093F\u092F\u093E\u0020
|
||||
// \u092E\u0902\u091C\u0020\u0905\u0916\u0020\u092E\u0941\u0932\u0941\u0915
|
||||
// \u0020\u0930\u093E\u091C\u0927\u093E\u0928\u0940\u0020\u0915\u093E\u0920
|
||||
// \u092E\u093E\u0921\u094C\u0902\u0020\u0928\u0947\u092A\u093E\u0932\u0020
|
||||
// \u0905\u0927\u093F\u0930\u093E\u091C\u094D\u092F\u0020\u092A\u0947\u0930
|
||||
// \u0947\u0917\u094D\u0935\u093E\u092F\u0020
|
||||
// \u0926\u0915\u094D\u0937\u093F\u0923\u0020\u0905\u092E\u0947\u0930\u093F
|
||||
// \u0915\u093E\u0020\u092E\u0939\u093E\u0926\u094D\u0935\u0940\u092A\u0947
|
||||
// \u0020\u092E\u0927\u094D\u0020\u092F\u0915\u094D\u0937\u0947\u0924\u094D
|
||||
// \u0930\u0947\u0020\u090F\u0915\u0020\u0926\u0947\u0936\u0020\u0905\u0938
|
||||
// \u094D\u0020\u0924\u093F\u0020\u092B\u0923\u0940\u0936\u094D\u0935\u0930
|
||||
// \u0020\u0928\u093E\u0925\u0020\u0930\u0947\u0923\u0941\u0020
|
||||
// \u092B\u093F\u091C\u0940\u0020\u091B\u0941\u0020\u0926\u0915\u094D\u0937
|
||||
// \u093F\u0923\u0020\u092A\u094D\u0930\u0936\u093E\u0928\u094D\u0020\u0924
|
||||
// \u0020\u092E\u0939\u093E\u0938\u093E\u0917\u0930\u0020\u092E\u0902\u091C
|
||||
// \u0020\u0905\u0916\u0020\u0926\u0947\u0936\u0020\u092C\u0939\u093E\u092E
|
||||
// \u093E\u0938\u0020\u091B\u0941\u0020\u0915\u0947\u0930\u0947\u092C\u093F
|
||||
// \u092F\u0928\u0020\u092E\u0902\u091C\u0020
|
||||
// \u0905\u0916\u0020\u092E\u0941\u0932\u0941\u0916\u0020\u0930\u093E\u091C
|
||||
// \u0927\u093E\u0928\u0940\u0020\u0928\u0938\u094C\u0020\u0938\u092E\u094D
|
||||
// \u0020\u092C\u0926\u094D\u0918\u0020\u0935\u093F\u0937\u092F\u0020\u092C
|
||||
// \u0941\u0930\u0941\u0902\u0921\u0940\u0020\u0905\u092B\u094D\u0930\u0940
|
||||
// \u0915\u093E\u0020\u092E\u0939\u093E\u0926\u094D\u0935\u0940\u092A\u0947
|
||||
// \u0020\u092E\u0927\u094D\u0020
|
||||
// \u092F\u0915\u094D\u0937\u0947\u0924\u094D\u0930\u0947\u0020\u0926\u0947
|
||||
// \u0936\u0020\u0905\u0938\u094D\u0020\u0924\u093F\u0020\u0938\u092E\u094D
|
||||
// \u0020\u092C\u0926\u094D\u0918\u0020\u0935\u093F\u0937\u092F
|
||||
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class CompactLangDetTest : public testing::Test {
|
||||
protected:
|
||||
// Objects declared here can be used by all tests in the test case for Foo.
|
||||
|
||||
// Detect language of plaintext src
|
||||
Language TestCompactLangDetPlain(const char* src) {
|
||||
bool is_plain_text = true;
|
||||
bool is_reliable;
|
||||
|
||||
Language lang = CompactLangDet::DetectLanguage(src, strlen(src),
|
||||
is_plain_text,
|
||||
&is_reliable);
|
||||
return lang;
|
||||
}
|
||||
|
||||
|
||||
// Detect extended language of plaintext src
|
||||
Language TestExtCompactLangDetPlain(const char* src) {
|
||||
bool is_plain_text = true;
|
||||
Language language3[3];
|
||||
int percent3[3];
|
||||
int text_bytes;
|
||||
bool is_reliable;
|
||||
|
||||
Language lang = CompactLangDet::ExtDetectLanguageSummary(src, strlen(src),
|
||||
is_plain_text,
|
||||
language3,
|
||||
percent3,
|
||||
&text_bytes,
|
||||
&is_reliable);
|
||||
return lang;
|
||||
}
|
||||
}; // End class CompactLangDetTest.
|
||||
|
||||
} // End namespace.
|
||||
|
||||
TEST_F(CompactLangDetTest, EasyTests) {
|
||||
EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_en));
|
||||
EXPECT_EQ(HINDI, TestCompactLangDetPlain(kTeststr_hi_Deva));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(CompactLangDetTest, FullTests) {
|
||||
// Do all the languages in all their scripts
|
||||
//// EXPECT_EQ(AFAR, TestCompactLangDetPlain(kTeststr_aa_Latn));
|
||||
//// EXPECT_EQ(ABKHAZIAN, TestCompactLangDetPlain(kTeststr_ab_Cyrl));
|
||||
//// EXPECT_EQ(AFRIKAANS, TestCompactLangDetPlain(kTeststr_af_Latn));
|
||||
//// EXPECT_EQ(AMHARIC, TestCompactLangDetPlain(kTeststr_am_Ethi));
|
||||
EXPECT_EQ(ARABIC, TestCompactLangDetPlain(kTeststr_ar_Arab));
|
||||
//// EXPECT_EQ(ASSAMESE, TestCompactLangDetPlain(kTeststr_as_Beng));
|
||||
//// EXPECT_EQ(AYMARA, TestCompactLangDetPlain(kTeststr_ay_Latn));
|
||||
// AZERBAIJANI Arab & Cyrl removed 2008.05.27. Just AZERBAIJANI Latn left
|
||||
// EXPECT_EQ(AZERBAIJANI, TestCompactLangDetPlain(kTeststr_az_Arab));
|
||||
// Missing data: az-Cyrl
|
||||
//// EXPECT_EQ(AZERBAIJANI, TestCompactLangDetPlain(kTeststr_az_Latn));
|
||||
|
||||
//// EXPECT_EQ(BASHKIR, TestCompactLangDetPlain(kTeststr_ba_Cyrl));
|
||||
//// EXPECT_EQ(BELARUSIAN, TestCompactLangDetPlain(kTeststr_be_Cyrl));
|
||||
EXPECT_EQ(BULGARIAN, TestCompactLangDetPlain(kTeststr_bg_Cyrl));
|
||||
//// EXPECT_EQ(BIHARI, TestCompactLangDetPlain(kTeststr_bh_Deva));
|
||||
//// EXPECT_EQ(BISLAMA, TestCompactLangDetPlain(kTeststr_bi_Latn));
|
||||
//// EXPECT_EQ(BENGALI, TestCompactLangDetPlain(kTeststr_bn_Beng));
|
||||
//// EXPECT_EQ(TIBETAN, TestCompactLangDetPlain(kTeststr_bo_Tibt));
|
||||
//// EXPECT_EQ(BRETON, TestCompactLangDetPlain(kTeststr_br_Latn));
|
||||
EXPECT_EQ(SERBIAN, TestCompactLangDetPlain(kTeststr_bs_Cyrl)); // NOTE: Not BOSNIAN
|
||||
EXPECT_EQ(CROATIAN, TestCompactLangDetPlain(kTeststr_bs_Latn)); // NOTE: Not BOSNIAN
|
||||
|
||||
EXPECT_EQ(CATALAN, TestCompactLangDetPlain(kTeststr_ca_Latn));
|
||||
EXPECT_EQ(CHEROKEE, TestCompactLangDetPlain(kTeststr_chr_Cher));
|
||||
//// EXPECT_EQ(CORSICAN, TestCompactLangDetPlain(kTeststr_co_Latn));
|
||||
// No CREOLES_AND_PIDGINS_ENGLISH_BASED
|
||||
// No CREOLES_AND_PIDGINS_FRENCH_BASED
|
||||
// No CREOLES_AND_PIDGINS_OTHER
|
||||
// No CREOLES_AND_PIDGINS_PORTUGUESE_BASED
|
||||
EXPECT_EQ(CZECH, TestCompactLangDetPlain(kTeststr_cs_Latn));
|
||||
//// EXPECT_EQ(WELSH, TestCompactLangDetPlain(kTeststr_cy_Latn));
|
||||
|
||||
EXPECT_EQ(DANISH, TestCompactLangDetPlain(kTeststr_da_Latn));
|
||||
EXPECT_EQ(GERMAN, TestCompactLangDetPlain(kTeststr_de_Latn));
|
||||
EXPECT_EQ(DHIVEHI, TestCompactLangDetPlain(kTeststr_dv_Thaa));
|
||||
//// EXPECT_EQ(DZONGKHA, TestCompactLangDetPlain(kTeststr_dz_Tibt));
|
||||
|
||||
EXPECT_EQ(GREEK, TestCompactLangDetPlain(kTeststr_el_Grek));
|
||||
EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_en_Latn));
|
||||
//// EXPECT_EQ(ESPERANTO, TestCompactLangDetPlain(kTeststr_eo_Latn));
|
||||
EXPECT_EQ(SPANISH, TestCompactLangDetPlain(kTeststr_es_Latn));
|
||||
EXPECT_EQ(ESTONIAN, TestCompactLangDetPlain(kTeststr_et_Latn));
|
||||
//// EXPECT_EQ(BASQUE, TestCompactLangDetPlain(kTeststr_eu_Latn));
|
||||
|
||||
//// EXPECT_EQ(PERSIAN, TestCompactLangDetPlain(kTeststr_fa_Arab));
|
||||
EXPECT_EQ(FINNISH, TestCompactLangDetPlain(kTeststr_fi_Latn));
|
||||
//// EXPECT_EQ(FIJIAN, TestCompactLangDetPlain(kTeststr_fj_Latn));
|
||||
//// EXPECT_EQ(FAROESE, TestCompactLangDetPlain(kTeststr_fo_Latn));
|
||||
EXPECT_EQ(FRENCH, TestCompactLangDetPlain(kTeststr_fr_Latn));
|
||||
//// EXPECT_EQ(FRISIAN, TestCompactLangDetPlain(kTeststr_fy_Latn));
|
||||
|
||||
//// EXPECT_EQ(IRISH, TestCompactLangDetPlain(kTeststr_ga_Latn));
|
||||
//// EXPECT_EQ(SCOTS_GAELIC, TestCompactLangDetPlain(kTeststr_gd_Latn));
|
||||
//// EXPECT_EQ(GALICIAN, TestCompactLangDetPlain(kTeststr_gl_Latn));
|
||||
//// EXPECT_EQ(GUARANI, TestCompactLangDetPlain(kTeststr_gn_Latn));
|
||||
EXPECT_EQ(GUJARATI, TestCompactLangDetPlain(kTeststr_gu_Gujr));
|
||||
//// EXPECT_EQ(MANX, TestCompactLangDetPlain(kTeststr_gv_Latn));
|
||||
|
||||
//// EXPECT_EQ(HAUSA, TestCompactLangDetPlain(kTeststr_ha_Latn));
|
||||
EXPECT_EQ(HINDI, TestCompactLangDetPlain(kTeststr_hi_Deva));
|
||||
EXPECT_EQ(CROATIAN, TestCompactLangDetPlain(kTeststr_hr_Latn)); // NOTE: now CROATIAN
|
||||
//// EXPECT_EQ(HAITIAN_CREOLE, TestCompactLangDetPlain(kTeststr_ht_Latn));
|
||||
EXPECT_EQ(HUNGARIAN, TestCompactLangDetPlain(kTeststr_hu_Latn));
|
||||
EXPECT_EQ(ARMENIAN, TestCompactLangDetPlain(kTeststr_hy_Armn));
|
||||
|
||||
//// EXPECT_EQ(INTERLINGUA, TestCompactLangDetPlain(kTeststr_ia_Latn));
|
||||
EXPECT_EQ(INDONESIAN, TestCompactLangDetPlain(kTeststr_id_Latn));
|
||||
//// EXPECT_EQ(INTERLINGUE, TestCompactLangDetPlain(kTeststr_ie_Latn));
|
||||
//// EXPECT_EQ(INUPIAK, TestCompactLangDetPlain(kTeststr_ik_Latn));
|
||||
EXPECT_EQ(ICELANDIC, TestCompactLangDetPlain(kTeststr_is_Latn));
|
||||
EXPECT_EQ(ITALIAN, TestCompactLangDetPlain(kTeststr_it_Latn));
|
||||
EXPECT_EQ(INUKTITUT, TestCompactLangDetPlain(kTeststr_iu_Cans));
|
||||
EXPECT_EQ(HEBREW, TestCompactLangDetPlain(kTeststr_iw_Hebr));
|
||||
|
||||
EXPECT_EQ(JAPANESE, TestCompactLangDetPlain(kTeststr_ja_Hani));
|
||||
//// EXPECT_EQ(JAVANESE, TestCompactLangDetPlain(kTeststr_jw_Latn));
|
||||
|
||||
EXPECT_EQ(GEORGIAN, TestCompactLangDetPlain(kTeststr_ka_Geor));
|
||||
//// EXPECT_EQ(KHASI, TestCompactLangDetPlain(kTeststr_kha_Latn));
|
||||
//// EXPECT_EQ(KAZAKH, TestCompactLangDetPlain(kTeststr_kk_Arab));
|
||||
//// EXPECT_EQ(KAZAKH, TestCompactLangDetPlain(kTeststr_kk_Cyrl));
|
||||
//// EXPECT_EQ(KAZAKH, TestCompactLangDetPlain(kTeststr_kk_Latn));
|
||||
//// EXPECT_EQ(GREENLANDIC, TestCompactLangDetPlain(kTeststr_kl_Latn));
|
||||
EXPECT_EQ(KHMER, TestCompactLangDetPlain(kTeststr_km_Khmr));
|
||||
EXPECT_EQ(KANNADA, TestCompactLangDetPlain(kTeststr_kn_Knda));
|
||||
EXPECT_EQ(KOREAN, TestCompactLangDetPlain(kTeststr_ko_Hani));
|
||||
//// EXPECT_EQ(KASHMIRI, TestCompactLangDetPlain(kTeststr_ks_Deva));
|
||||
// KURDISH Latn removed 2008.05.27. Just KURDISH Arab left
|
||||
//// EXPECT_EQ(KURDISH, TestCompactLangDetPlain(kTeststr_ku_Arab));
|
||||
// EXPECT_EQ(KURDISH, TestCompactLangDetPlain(kTeststr_ku_Latn));
|
||||
//// EXPECT_EQ(KYRGYZ, TestCompactLangDetPlain(kTeststr_ky_Arab));
|
||||
//// EXPECT_EQ(KYRGYZ, TestCompactLangDetPlain(kTeststr_ky_Cyrl));
|
||||
|
||||
//// EXPECT_EQ(LATIN, TestCompactLangDetPlain(kTeststr_la_Latn));
|
||||
//// EXPECT_EQ(LUXEMBOURGISH, TestCompactLangDetPlain(kTeststr_lb_Latn));
|
||||
//// EXPECT_EQ(GANDA, TestCompactLangDetPlain(kTeststr_lg_Latn));
|
||||
//// EXPECT_EQ(LINGALA, TestCompactLangDetPlain(kTeststr_ln_Latn));
|
||||
EXPECT_EQ(LAOTHIAN, TestCompactLangDetPlain(kTeststr_lo_Laoo));
|
||||
EXPECT_EQ(LITHUANIAN, TestCompactLangDetPlain(kTeststr_lt_Latn));
|
||||
EXPECT_EQ(LATVIAN, TestCompactLangDetPlain(kTeststr_lv_Latn));
|
||||
|
||||
//// EXPECT_EQ(MALAGASY, TestCompactLangDetPlain(kTeststr_mg_Latn));
|
||||
//// EXPECT_EQ(MAORI, TestCompactLangDetPlain(kTeststr_mi_Latn));
|
||||
//// EXPECT_EQ(MACEDONIAN, TestCompactLangDetPlain(kTeststr_mk_Cyrl));
|
||||
EXPECT_EQ(MALAYALAM, TestCompactLangDetPlain(kTeststr_ml_Mlym));
|
||||
//// EXPECT_EQ(MONGOLIAN, TestCompactLangDetPlain(kTeststr_mn_Cyrl));
|
||||
//// EXPECT_EQ(MOLDAVIAN, TestCompactLangDetPlain(kTeststr_mo_Cyrl));
|
||||
//// EXPECT_EQ(MARATHI, TestCompactLangDetPlain(kTeststr_mr_Deva));
|
||||
//// EXPECT_EQ(MALAY, TestCompactLangDetPlain(kTeststr_ms_Latn));
|
||||
//// EXPECT_EQ(MALAY, TestCompactLangDetPlain(kTeststr_ms_Latn2));
|
||||
//// EXPECT_EQ(MALAY, TestCompactLangDetPlain(kTeststr_ms_Latn3));
|
||||
//// EXPECT_EQ(MALTESE, TestCompactLangDetPlain(kTeststr_mt_Latn));
|
||||
//// EXPECT_EQ(BURMESE, TestCompactLangDetPlain(kTeststr_my_Latn));
|
||||
//// EXPECT_EQ(BURMESE, TestCompactLangDetPlain(kTeststr_my_Mymr));
|
||||
|
||||
//// EXPECT_EQ(NAURU, TestCompactLangDetPlain(kTeststr_na_Latn));
|
||||
//// EXPECT_EQ(NEPALI, TestCompactLangDetPlain(kTeststr_ne_Deva));
|
||||
EXPECT_EQ(DUTCH, TestCompactLangDetPlain(kTeststr_nl_Latn));
|
||||
//// EXPECT_EQ(NORWEGIAN_N, TestCompactLangDetPlain(kTeststr_nn_Latn));
|
||||
EXPECT_EQ(NORWEGIAN, TestCompactLangDetPlain(kTeststr_no_Latn));
|
||||
|
||||
//// EXPECT_EQ(OCCITAN, TestCompactLangDetPlain(kTeststr_oc_Latn));
|
||||
//// EXPECT_EQ(OROMO, TestCompactLangDetPlain(kTeststr_om_Latn));
|
||||
EXPECT_EQ(ORIYA, TestCompactLangDetPlain(kTeststr_or_Orya));
|
||||
|
||||
EXPECT_EQ(PUNJABI, TestCompactLangDetPlain(kTeststr_pa_Guru));
|
||||
EXPECT_EQ(POLISH, TestCompactLangDetPlain(kTeststr_pl_Latn));
|
||||
//// EXPECT_EQ(PASHTO, TestCompactLangDetPlain(kTeststr_ps_Arab));
|
||||
EXPECT_EQ(PORTUGUESE, TestCompactLangDetPlain(kTeststr_pt_BR)); // NOTE: not PORTUGUESE_B
|
||||
// nor PORTUGUESE_P
|
||||
|
||||
//// EXPECT_EQ(QUECHUA, TestCompactLangDetPlain(kTeststr_qu_Latn));
|
||||
|
||||
//// EXPECT_EQ(RHAETO_ROMANCE, TestCompactLangDetPlain(kTeststr_rm_Latn));
|
||||
//// EXPECT_EQ(RUNDI, TestCompactLangDetPlain(kTeststr_rn_Latn));
|
||||
EXPECT_EQ(ROMANIAN, TestCompactLangDetPlain(kTeststr_ro_Latn));
|
||||
EXPECT_EQ(RUSSIAN, TestCompactLangDetPlain(kTeststr_ru_Cyrl));
|
||||
//// EXPECT_EQ(KINYARWANDA, TestCompactLangDetPlain(kTeststr_rw_Latn));
|
||||
|
||||
//// EXPECT_EQ(SANSKRIT, TestCompactLangDetPlain(kTeststr_sa_Deva));
|
||||
//// EXPECT_EQ(SANSKRIT, TestCompactLangDetPlain(kTeststr_sa_Latn));
|
||||
//// EXPECT_EQ(SCOTS, TestCompactLangDetPlain(kTeststr_sco_Latn));
|
||||
//// EXPECT_EQ(SINDHI, TestCompactLangDetPlain(kTeststr_sd_Arab));
|
||||
//// EXPECT_EQ(SANGO, TestCompactLangDetPlain(kTeststr_sg_Latn));
|
||||
// No SERBO_CROATIAN (sh)
|
||||
EXPECT_EQ(SINHALESE, TestCompactLangDetPlain(kTeststr_si_Sinh));
|
||||
//// EXPECT_EQ(LIMBU, TestCompactLangDetPlain(kTeststr_sit_NP));
|
||||
EXPECT_EQ(SLOVAK, TestCompactLangDetPlain(kTeststr_sk_Latn));
|
||||
EXPECT_EQ(SLOVENIAN, TestCompactLangDetPlain(kTeststr_sl_Latn));
|
||||
//// EXPECT_EQ(SAMOAN, TestCompactLangDetPlain(kTeststr_sm_Latn));
|
||||
//// EXPECT_EQ(SHONA, TestCompactLangDetPlain(kTeststr_sn_Latn));
|
||||
//// EXPECT_EQ(SOMALI, TestCompactLangDetPlain(kTeststr_so_Latn));
|
||||
//// EXPECT_EQ(ALBANIAN, TestCompactLangDetPlain(kTeststr_sq_Latn));
|
||||
EXPECT_EQ(SERBIAN, TestCompactLangDetPlain(kTeststr_sr_Cyrl)); // NOTE: now SERBIAN
|
||||
EXPECT_EQ(CROATIAN, TestCompactLangDetPlain(kTeststr_sr_Latn)); // NOTE: Not SERBIAN
|
||||
EXPECT_EQ(CROATIAN, TestCompactLangDetPlain(kTeststr_sr_ME_Latn)); // NOTE: not SERBIAN nor MONTENEGRIN
|
||||
//// EXPECT_EQ(SISWANT, TestCompactLangDetPlain(kTeststr_ss_Latn));
|
||||
//// EXPECT_EQ(SESOTHO, TestCompactLangDetPlain(kTeststr_st_Latn));
|
||||
//// EXPECT_EQ(SUNDANESE, TestCompactLangDetPlain(kTeststr_su_Latn));
|
||||
EXPECT_EQ(SWEDISH, TestCompactLangDetPlain(kTeststr_sv_Latn));
|
||||
//// EXPECT_EQ(SWAHILI, TestCompactLangDetPlain(kTeststr_sw_Latn));
|
||||
EXPECT_EQ(SYRIAC, TestCompactLangDetPlain(kTeststr_syr_Syrc));
|
||||
|
||||
EXPECT_EQ(TAMIL, TestCompactLangDetPlain(kTeststr_ta_Taml));
|
||||
EXPECT_EQ(TELUGU, TestCompactLangDetPlain(kTeststr_te_Telu));
|
||||
// Tajik Arab removed 2008.05.27. Just Tajik Cyrl left
|
||||
// EXPECT_EQ(TAJIK, TestCompactLangDetPlain(kTeststr_tg_Arab));
|
||||
//// EXPECT_EQ(TAJIK, TestCompactLangDetPlain(kTeststr_tg_Cyrl));
|
||||
EXPECT_EQ(THAI, TestCompactLangDetPlain(kTeststr_th_Thai));
|
||||
//// EXPECT_EQ(TIGRINYA, TestCompactLangDetPlain(kTeststr_ti_Ethi));
|
||||
//// EXPECT_EQ(TURKMEN, TestCompactLangDetPlain(kTeststr_tk_Cyrl));
|
||||
//// EXPECT_EQ(TURKMEN, TestCompactLangDetPlain(kTeststr_tk_Latn));
|
||||
EXPECT_EQ(TAGALOG, TestCompactLangDetPlain(kTeststr_tl_Latn));
|
||||
//// EXPECT_EQ(TSWANA, TestCompactLangDetPlain(kTeststr_tn_Latn));
|
||||
//// EXPECT_EQ(TONGA, TestCompactLangDetPlain(kTeststr_to_Latn));
|
||||
EXPECT_EQ(TURKISH, TestCompactLangDetPlain(kTeststr_tr_Latn));
|
||||
//// EXPECT_EQ(TSONGA, TestCompactLangDetPlain(kTeststr_ts_Latn));
|
||||
//// EXPECT_EQ(TATAR, TestCompactLangDetPlain(kTeststr_tt_Cyrl));
|
||||
//// EXPECT_EQ(TATAR, TestCompactLangDetPlain(kTeststr_tt_Latn));
|
||||
//// EXPECT_EQ(TWI, TestCompactLangDetPlain(kTeststr_tw_Latn));
|
||||
|
||||
//// EXPECT_EQ(UIGHUR, TestCompactLangDetPlain(kTeststr_ug_Arab));
|
||||
//// EXPECT_EQ(UIGHUR, TestCompactLangDetPlain(kTeststr_ug_Cyrl));
|
||||
//// EXPECT_EQ(UIGHUR, TestCompactLangDetPlain(kTeststr_ug_Latn));
|
||||
EXPECT_EQ(UKRAINIAN, TestCompactLangDetPlain(kTeststr_uk_Cyrl));
|
||||
//// EXPECT_EQ(URDU, TestCompactLangDetPlain(kTeststr_ur_Arab));
|
||||
//// EXPECT_EQ(UZBEK, TestCompactLangDetPlain(kTeststr_uz_Arab));
|
||||
//// EXPECT_EQ(UZBEK, TestCompactLangDetPlain(kTeststr_uz_Cyrl));
|
||||
//// EXPECT_EQ(UZBEK, TestCompactLangDetPlain(kTeststr_uz_Latn));
|
||||
|
||||
EXPECT_EQ(VIETNAMESE, TestCompactLangDetPlain(kTeststr_vi_Latn));
|
||||
//// EXPECT_EQ(VOLAPUK, TestCompactLangDetPlain(kTeststr_vo_Latn));
|
||||
|
||||
//// EXPECT_EQ(WOLOF, TestCompactLangDetPlain(kTeststr_wo_Latn));
|
||||
|
||||
//// EXPECT_EQ(XHOSA, TestCompactLangDetPlain(kTeststr_xh_Latn));
|
||||
|
||||
//// EXPECT_EQ(YIDDISH, TestCompactLangDetPlain(kTeststr_yi_Hebr));
|
||||
//// EXPECT_EQ(YORUBA, TestCompactLangDetPlain(kTeststr_yo_Latn));
|
||||
|
||||
// Zhuang Hani removed 2008.05.13. Just Zhuang Latn left
|
||||
// EXPECT_EQ(ZHUANG, TestCompactLangDetPlain(kTeststr_za_Hani));
|
||||
//// EXPECT_EQ(ZHUANG, TestCompactLangDetPlain(kTeststr_za_Latn));
|
||||
EXPECT_EQ(CHINESE, TestCompactLangDetPlain(kTeststr_zh_Hani));
|
||||
EXPECT_EQ(CHINESE_T, TestCompactLangDetPlain(kTeststr_zh_TW));
|
||||
//// EXPECT_EQ(ZULU, TestCompactLangDetPlain(kTeststr_zu_Latn));
|
||||
// No TG_UNKNOWN_LANGUAGE
|
||||
// No UNKNOWN_LANGUAGE
|
||||
}
|
||||
|
||||
|
||||
TEST_F(CompactLangDetTest, ExtendedTests) {
|
||||
// Do the extended languages, with them not-allowed then allowed
|
||||
// These turn out to be extraordinarily sensitive forms of garbage bytes
|
||||
//// EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_tlh_Latn));
|
||||
//// EXPECT_EQ(X_KLINGON, TestExtCompactLangDetPlain(kTeststr_tlh_Latn));
|
||||
|
||||
//// EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_zzp_Latn));
|
||||
//// EXPECT_EQ(X_PIG_LATIN, TestExtCompactLangDetPlain(kTeststr_zzp_Latn));
|
||||
|
||||
//// EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_xx_Bugi));
|
||||
//// EXPECT_EQ(X_BUGINESE, TestExtCompactLangDetPlain(kTeststr_xx_Bugi));
|
||||
|
||||
//// EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_xx_Goth));
|
||||
//// EXPECT_EQ(X_GOTHIC, TestExtCompactLangDetPlain(kTeststr_xx_Goth));
|
||||
|
||||
// Next three now removed permanently from probability tables (May 2008)
|
||||
// (used to be X_BORK_BORK_BORK, X_ELMER_FUDD, X_HACKER).
|
||||
//
|
||||
// Small changes in probability tables may cause these non-texts to
|
||||
// change detection result. If that happens, cross-check that
|
||||
// the new result is not because of a bug, then change the expected values.
|
||||
EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_zzb_Latn));
|
||||
EXPECT_EQ(ENGLISH, TestExtCompactLangDetPlain(kTeststr_zzb_Latn));
|
||||
|
||||
EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_zze_Latn));
|
||||
EXPECT_EQ(ENGLISH, TestExtCompactLangDetPlain(kTeststr_zze_Latn));
|
||||
|
||||
EXPECT_EQ(ENGLISH, TestCompactLangDetPlain(kTeststr_zzh_Latn));
|
||||
EXPECT_EQ(ENGLISH, TestExtCompactLangDetPlain(kTeststr_zzh_Latn));
|
||||
}
|
||||
+7
-1
@@ -5,6 +5,12 @@
|
||||
#ifndef BAR_TOOLBAR_CLD_I18N_ENCODINGS_COMPACT_LANG_DET_WIN_CLD_GOOGLE_H_
|
||||
#define BAR_TOOLBAR_CLD_I18N_ENCODINGS_COMPACT_LANG_DET_WIN_CLD_GOOGLE_H_
|
||||
|
||||
// Nothing to be included for windows version.
|
||||
// For now, comment out CLD_WINDOWS since it is leading to some problems
|
||||
// with unit testing, because google.h has been removed from the trunk.
|
||||
// When linux/mac versions are implemented, google.h (and associated files)
|
||||
// can be checked in as required.
|
||||
/*
|
||||
#if !defined(CLD_WINDOWS)
|
||||
|
||||
#include "third_party/cld/base/google.h"
|
||||
@@ -14,5 +20,5 @@
|
||||
// Include nothing
|
||||
|
||||
#endif
|
||||
|
||||
*/
|
||||
#endif // BAR_TOOLBAR_CLD_I18N_ENCODINGS_COMPACT_LANG_DET_WIN_CLD_GOOGLE_H_
|
||||
|
||||
externo
-308
@@ -1,308 +0,0 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Callback classes provides a generic interface for classes requiring
|
||||
// callback from other classes.
|
||||
// We support callbacks with 0, 1, 2, 3, and 4 arguments.
|
||||
// Closure -- provides "void Run()"
|
||||
// Callback1<T1> -- provides "void Run(T1)"
|
||||
// Callback2<T1,T2> -- provides "void Run(T1, T2)"
|
||||
// Callback3<T1,T2,T3> -- provides "void Run(T1, T2, T3)"
|
||||
// Callback4<T1,T2,T3,T4> -- provides "void Run(T1, T2, T3, T4)"
|
||||
//
|
||||
// In addition, ResultCallback classes provide a generic interface for
|
||||
// callbacks that return a value.
|
||||
// ResultCallback<R> -- provides "R Run()"
|
||||
// ResultCallback1<R,T1> -- provides "R Run(T1)"
|
||||
// ResultCallback2<R,T1,T2> -- provides "R Run(T1, T2)"
|
||||
// ResultCallback3<R,T1,T2,T3> -- provides "R Run(T1, T2, T3)"
|
||||
// ResultCallback4<R,T1,T2,T3,T4> -- provides "R Run(T1, T2, T3, T4)"
|
||||
|
||||
// We provide a convenient mechanism, NewCallback, for generating one of these
|
||||
// callbacks given an object pointer, a pointer to a member
|
||||
// function with the appropriate signature in that object's class,
|
||||
// and some optional arguments that can be bound into the callback
|
||||
// object. The mechanism also works with just a function pointer.
|
||||
//
|
||||
// Note: there are two types of arguments passed to the callback method:
|
||||
// * "pre-bound arguments" - supplied when the callback object is created
|
||||
// * "call-time arguments" - supplied when the callback object is invoked
|
||||
//
|
||||
// These two types correspond to "early binding" and "late
|
||||
// binding". An argument whose value is known when the callback is
|
||||
// created ("early") can be pre-bound (a.k.a. "Curried"), You can
|
||||
// combine pre-bound and call-time arguments in different ways. For
|
||||
// example, invoking a callback with 3 pre-bound arguments and 1
|
||||
// call-time argument will have the same effect as invoking a callback
|
||||
// with 2 pre-bound arguments and 2 call-time arguments, or 4
|
||||
// pre-bound arguments and no call-time arguments. This last case is
|
||||
// often useful; a callback with no call-time arguments is a Closure;
|
||||
// these are used in many places in the Google libraries, e.g., "done"
|
||||
// closures. See the examples below.
|
||||
//
|
||||
// WARNING: In the current implementation (or perhaps with the current
|
||||
// compiler) NewCallback() is pickier about the types of pre-bound arguments
|
||||
// than you might expect. The types must match exactly, rather than merely
|
||||
// being compatible.
|
||||
// For example, if you pre-bind an argument with the "const" specifier,
|
||||
// make sure that the actual parameter passed to NewCallback also has the
|
||||
// const specifier. If you don't you'll get an error about
|
||||
// passing a your function "as argument 1 of NewCallback(void (*)())".
|
||||
// Using a method or function that has reference arguments among its pre-bound
|
||||
// arguments may not always work.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// void Call0(Closure* cb) { cb->Run(); }
|
||||
// void Call1(Callback1<int>* cb, int a) { cb->Run(a); }
|
||||
// void Call2(Callback2<int, float>* cb, int a, float f) { cb->Run(a, f); }
|
||||
// float Call3(ResultCallback1<float, int>* cb, int a) { return cb->Run(a); }
|
||||
//
|
||||
// class Foo {
|
||||
// public:
|
||||
// void A(int a);
|
||||
// void B(int a, float f);
|
||||
// void C(const char* label, int a, float f);
|
||||
// float D(int a);
|
||||
// };
|
||||
// void F0(int a);
|
||||
// void F1(int a, float f);
|
||||
// void F2(const char *label, int a, float f);
|
||||
// float F3(int a);
|
||||
// float v;
|
||||
//
|
||||
// // Run stuff immediately
|
||||
// // calling a method
|
||||
// Foo* foo = new Foo;
|
||||
//
|
||||
// NewCallback(foo, &Foo::A) ->Run(10); // 0 [pre-bound] + 1 [call-time]
|
||||
// == NewCallback(foo, &Foo::A, 10) ->Run(); // 1 + 0
|
||||
// == foo->A(10);
|
||||
//
|
||||
// NewCallback(foo, &Foo::B) ->Run(10, 3.0f); // 0 + 2
|
||||
// == NewCallback(foo, &Foo::B, 10) ->Run(3.0f); // 1 + 1
|
||||
// == NewCallback(foo, &Foo::B, 10, 3.0f) ->Run(); // 2 + 0
|
||||
// == foo->B(10, 3.0f);
|
||||
//
|
||||
// NewCallback(foo, &Foo::C) ->Run("Y", 10, 3.0f); // 0 + 3
|
||||
// == NewCallback(foo, &Foo::C, "Y") ->Run(10, 3.0f); // 1 + 2
|
||||
// == NewCallback(foo, &Foo::C, "Y", 10) ->Run(3.0f); // 2 + 1
|
||||
// == NewCallback(foo, &Foo::C, "Y", 10, 3.0f) ->Run(); // 3 + 0
|
||||
// == foo->C("Y", 10, 3.0f);
|
||||
//
|
||||
// v = NewCallback(foo, &Foo::D) ->Run(10); == v = foo->D(10)
|
||||
//
|
||||
// // calling a function
|
||||
// NewCallback(F0) ->Run(10); // == F0(10) // 0 + 1
|
||||
// NewCallback(F0, 10) ->Run(); // == F0(10) // 1 + 0
|
||||
// NewCallback(F1) ->Run(10, 3.0f); // == F1(10, 3.0f)
|
||||
// NewCallback(F2, "X") ->Run(10, 3.0f); // == F2("X", 10, 3.0f)
|
||||
// NewCallback(F2, "Y") ->Run(10, 3.0f); // == F2("Y", 10, 3.0f)
|
||||
// v = NewCallback(F3) ->Run(10); // == v = F3(10)
|
||||
//
|
||||
//
|
||||
// // Pass callback object to somebody else, who runs it.
|
||||
// // Calling a method:
|
||||
// Call1(NewCallback(foo, &Foo::A), 10); // 0 + 1
|
||||
// == Call0(NewCallback(foo, &Foo::A, 10) ); // 1 + 0
|
||||
// == foo->A(10)
|
||||
//
|
||||
// Call2(NewCallback(foo, &Foo::B), 10, 3.0f); // 0 + 2
|
||||
// == Call1(NewCallback(foo, &Foo::B, 10), 3.0f); // 1 + 1
|
||||
// == Call0(NewCallback(foo, &Foo::B, 10, 30.f) ); // 2 + 0
|
||||
// == foo->B(10, 3.0f)
|
||||
//
|
||||
// Call2(NewCallback(foo, &Foo::C, "X"), 10, 3.0f); == foo->C("X", 10, 3.0f)
|
||||
// Call2(NewCallback(foo, &Foo::C, "Y"), 10, 3.0f); == foo->C("Y", 10, 3.0f)
|
||||
//
|
||||
// // Calling a function:
|
||||
// Call1(NewCallback(F0), 10); // 0 + 1
|
||||
// == Call0(NewCallback(F0, 10) ); // 1 + 0
|
||||
// == F0(10);
|
||||
//
|
||||
// Call2(NewCallback(F1), 10, 3.0f); // == F1(10, 3.0f)
|
||||
// Call2(NewCallback(F2, "X"), 10, 3.0f); // == F2("X", 10, 3.0f)
|
||||
// Call2(NewCallback(F2, "Y"), 10, 3.0f); // == F2("Y", 10, 3.0f)
|
||||
// v = Call3(NewCallback(F3), 10); // == v = F3(10)
|
||||
//
|
||||
// Example of a "done" closure:
|
||||
//
|
||||
// SelectServer ss;
|
||||
// Closure* done = NewCallback(&ss, &SelectServer::MakeLoopExit);
|
||||
// ProcessMyControlFlow(..., done);
|
||||
// ss.Loop();
|
||||
// ...
|
||||
//
|
||||
// The following WILL NOT WORK:
|
||||
// NewCallback(F2, (char *) "Y") ->Run(10, 3.0f);
|
||||
// It gets the error:
|
||||
// passing `void (*)(const char *, int, float)' as argument 1 of
|
||||
// `NewCallback(void (*)())'
|
||||
// The problem is that "char *" is not an _exact_ match for
|
||||
// "const char *", even though it's normally a legal implicit
|
||||
// conversion.
|
||||
//
|
||||
//
|
||||
// The callback objects generated by NewCallback are self-deleting:
|
||||
// i.e., they call the member function, and then delete themselves.
|
||||
// If you want a callback that does not delete itself every time
|
||||
// it runs, use "NewPermanentCallback" instead of "NewCallback".
|
||||
//
|
||||
// All the callback/closure classes also provide
|
||||
// virtual void CheckIsRepeatable() const;
|
||||
// It crashes if (we know for sure that) the callback's Run method
|
||||
// can not be called an arbitrary number of times (including 0).
|
||||
// It crashes for all NewCallback() generated callbacks,
|
||||
// does not crash for NewPermanentCallback() generated callbacks,
|
||||
// and although by default it does not crash for all callback-derived classes,
|
||||
// for these new types of callbacks, the callback writer is encouraged to
|
||||
// redefine this method appropriately.
|
||||
//
|
||||
// CAVEAT: Interfaces that accept callback pointers should clearly document
|
||||
// if they might call Run methods of those callbacks multiple times
|
||||
// (and use "c->CheckIsRepeatable();" as an active precondition check),
|
||||
// or if they call the callbacks exactly once or potentially not at all,
|
||||
// as well as if they take ownership of the passed callbacks
|
||||
// (i.e. might manually deallocate them without calling their Run methods).
|
||||
// The clients can then provide properly allocated and behaving callbacks
|
||||
// (e.g. choose between NewCallback, NewPermanentCallback, or a custom object).
|
||||
// Obviously, one should also be careful to ensure that the data a callback
|
||||
// points to and needs for its Run method is still live when
|
||||
// the Run method might be called.
|
||||
//
|
||||
// MOTIVATION FOR CALLBACK OBJECTS
|
||||
// -------------------------------
|
||||
// It frees service providers from depending on service requestors by
|
||||
// calling a generic callback other than a callback which depends on
|
||||
// the service requestor (typically its member function). As a
|
||||
// result, service provider classes can be developed independently.
|
||||
//
|
||||
// Typical usage: Suppose class A wants class B to do something and
|
||||
// notify A when it is done. As part of the notification, it wants
|
||||
// to be given a boolean that says what happened.
|
||||
//
|
||||
// class A {
|
||||
// public:
|
||||
// void RequestService(B* server) {
|
||||
// ...
|
||||
// server->StartService(NewCallback(this, &A::ServiceDone), other_args));
|
||||
// // the new callback deletes itself after it runs
|
||||
// }
|
||||
// void ServiceDone(bool status) {...}
|
||||
// };
|
||||
//
|
||||
// Class B {
|
||||
// public:
|
||||
// void StartService(Callback1<bool>* cb, other_args) : cb_(cb) { ...}
|
||||
// void FinishService(bool result) { ...; cb_->Run(result); }
|
||||
// private:
|
||||
// Callback1<bool>* cb_;
|
||||
// };
|
||||
//
|
||||
// As can be seen, B is completely independent of A. (Of course, they
|
||||
// have to agree on callback data type.)
|
||||
//
|
||||
// The result of NewCallback() is thread-compatible. The result of
|
||||
// NewPermanentCallback() is thread-safe if the call its Run() method
|
||||
// represents is thread-safe and thread-compatible otherwise.
|
||||
//
|
||||
// Other modules associated with callbacks may be found in //util/callback
|
||||
//
|
||||
// USING CALLBACKS WITH TRACECONTEXT
|
||||
// ---------------------------------
|
||||
// Callbacks generated by NewCallback() automatically propagate trace
|
||||
// context. Callbacks generated by NewPermanentCallback() do not. For
|
||||
// manually-derived subclasses of Closure and CallbackN, you may decide
|
||||
// to propagate TraceContext as follows.
|
||||
//
|
||||
// struct MyClosure : public Closure {
|
||||
// MyClosure()
|
||||
// : Closure(TraceContext::THREAD) { }
|
||||
//
|
||||
// void Run() {
|
||||
// TraceContext *tc = TraceContext::Thread();
|
||||
// tc->Swap(&trace_context_);
|
||||
// DoMyOperation()
|
||||
// tc->Swap(&trace_context_);
|
||||
// delete this;
|
||||
// }
|
||||
// };
|
||||
|
||||
#ifndef _CALLBACK_H_
|
||||
#define _CALLBACK_H_
|
||||
|
||||
#include <functional>
|
||||
|
||||
// The actual callback classes and various NewCallback() implementations
|
||||
// are automatically generated by base/generate-callback-specializations.py.
|
||||
// We include that output here.
|
||||
#include "base/callback-specializations.h"
|
||||
|
||||
// A new barrier closure executes another closure after it has been
|
||||
// invoked N times, and then deletes itself.
|
||||
//
|
||||
// If "N" is zero, the supplied closure is executed immediately.
|
||||
// Barrier closures are thread-safe. They use an atomic operation to
|
||||
// guarantee a correct count.
|
||||
//
|
||||
// REQUIRES N >= 0.
|
||||
extern Closure* NewBarrierClosure(int N, Closure* done_closure);
|
||||
|
||||
// Function that does nothing; can be used to make new no-op closures:
|
||||
// NewCallback(&DoNothing)
|
||||
// NewPermanentCallback(&DoNothing)
|
||||
// This is a replacement for the formerly available TheNoopClosure() primitive.
|
||||
extern void DoNothing();
|
||||
|
||||
// AutoClosureRunner executes a closure upon deletion. This class
|
||||
// is similar to scoped_ptr: it is typically stack-allocated and can be
|
||||
// used to perform some type of cleanup upon exiting a block.
|
||||
//
|
||||
// Note: use of AutoClosureRunner with Closures that must be executed at
|
||||
// specific points is discouraged, since the point at which the Closure
|
||||
// executes is not explicitly marked. For example, consider a Closure
|
||||
// that should execute after a mutex has been released. The following
|
||||
// code looks correct, but executes the Closure too early (before release):
|
||||
// {
|
||||
// MutexLock l(...);
|
||||
// AutoClosureRunner r(run_after_unlock);
|
||||
// ...
|
||||
// }
|
||||
// AutoClosureRunner is primarily intended for cleanup operations that
|
||||
// are relatively independent from other code.
|
||||
//
|
||||
// The Reset() method replaces the callback with a new callback. The new
|
||||
// callback can be supplied as NULL to disable the AutoClosureRunner. This is
|
||||
// intended as part of a strategy to execute a callback at all exit points of a
|
||||
// method except where Reset() was called. This method must be used only with
|
||||
// non-permanent callbacks. The Release() method disables and returns the
|
||||
// callback, instead of deleting it.
|
||||
class AutoClosureRunner {
|
||||
private:
|
||||
Closure* closure_;
|
||||
public:
|
||||
explicit AutoClosureRunner(Closure* c) : closure_(c) {}
|
||||
~AutoClosureRunner() { if (closure_) closure_->Run(); }
|
||||
void Reset(Closure *c) { delete closure_; closure_ = c; }
|
||||
Closure* Release() { Closure* c = closure_; closure_ = NULL; return c; }
|
||||
private:
|
||||
DISALLOW_EVIL_CONSTRUCTORS(AutoClosureRunner);
|
||||
};
|
||||
|
||||
// DeletePointerClosure can be used to create a closure that calls delete
|
||||
// on a pointer. Here is an example:
|
||||
//
|
||||
// thread->Add(DeletePointerClosure(expensive_to_delete));
|
||||
//
|
||||
template<typename T>
|
||||
void DeletePointer(T* p) {
|
||||
delete p;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Closure* DeletePointerClosure(T* p) {
|
||||
return NewCallback(&DeletePointer<T>, p);
|
||||
}
|
||||
|
||||
#endif /* _CALLBACK_H_ */
|
||||
externo
-12
@@ -1,12 +0,0 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef _CLOSURE_H
|
||||
#define _CLOSURE_H
|
||||
|
||||
// The Closure class is described in "base/callback.h".
|
||||
|
||||
#include "third_party/cld/base/callback.h"
|
||||
|
||||
#endif /* _CLOSURE_H */
|
||||
externo
-212
@@ -1,212 +0,0 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This file contains a very small number of declarations that should be
|
||||
// included in most programs.
|
||||
//
|
||||
// Sets the usage message to "*usage", parses the command-line flags,
|
||||
// and initializes various other pieces of global state. If running
|
||||
// as root, this routine attempts to setuid to FLAGS_uid, which defaults
|
||||
// to "nobody".
|
||||
//
|
||||
// It also logs all the program's command-line flags to the INFO log file.
|
||||
//
|
||||
// If the global variable FLAGS_uid is not equal to the empty string,
|
||||
// then InitGoogle also does an 'su' to the user specified in
|
||||
// FLAGS_uid, and sets the group equal to FLAGS_gid.
|
||||
//
|
||||
// The functions in here are thread-safe unless specified otherwise,
|
||||
// but they must be called after InitGoogle() (or the
|
||||
// InitGoogleExceptChangeRootAndUser/ChangeRootAndUser pair).
|
||||
|
||||
#ifndef _GOOGLE_H_
|
||||
#define _GOOGLE_H_
|
||||
|
||||
#include <iosfwd> // to forward declare ostream
|
||||
#include "base/basictypes.h"
|
||||
#include "third_party/cld/base/closure.h"
|
||||
#include "third_party/cld/base/googleinit.h"
|
||||
|
||||
class Closure;
|
||||
|
||||
// A more-convenient way to access gethostname()
|
||||
const char* Hostname();
|
||||
// Return kernel version string in /proc/version
|
||||
const char* GetKernelVersionString();
|
||||
// Return true and set kernel version (x.y.z), patch level and revision (#p.r),
|
||||
// false, if not known.
|
||||
struct KernelVersion {
|
||||
int major; // Major release
|
||||
int minor; // Minor release
|
||||
int micro; // Whatever the third no. is called ...
|
||||
int patch; // Patch level
|
||||
int revision; // Patch revision
|
||||
};
|
||||
bool GetKernelVersion(KernelVersion* kv);
|
||||
// A string saying when InitGoogle() was called -- probably program start
|
||||
const char* GetStartTime();
|
||||
// time in ms since InitGoogle() was called --
|
||||
int64 GetUptime();
|
||||
// the pid for the startup thread
|
||||
int32 GetMainThreadPid();
|
||||
|
||||
// the resource limit for core size when InitGoogle() was called.
|
||||
const struct rlimit* GetSavedCoreLimit();
|
||||
|
||||
// Restore the core size limit saved in InitGoogle(). This is a no-op if
|
||||
// FLAGS_allow_kernel_coredumps is true.
|
||||
int32 RestoreSavedCoreLimit();
|
||||
|
||||
// Return true if we have determined that all CPUs have the same timing
|
||||
// (same model, clock rate, stepping). Returns true if there is only one
|
||||
// CPU. Returns false if we cannot read or parse /proc/cpuinfo.
|
||||
bool CPUsHaveSameTiming(
|
||||
const char *cpuinfo = "/proc/cpuinfo",
|
||||
const char *cpuinfo_max_freq = "/sys/devices/system/cpu/cpu%d/"
|
||||
"cpufreq/cpuinfo_max_freq");
|
||||
|
||||
// FlagsParsed is called once for every run VLOG() call site.
|
||||
// Returns true if command line flags have been parsed
|
||||
bool FlagsParsed();
|
||||
|
||||
// A place-holder module initializer to declare initialization ordering
|
||||
// with respect to it to make chosen initalizers run before command line flag
|
||||
// parsing (see googleinit.h for more details).
|
||||
DECLARE_MODULE_INITIALIZER(command_line_flags_parsing);
|
||||
|
||||
// Checks (only in debug mode) if main() has been started and crashes if not
|
||||
// i.e. makes sure that we are out of the global constructor execution stage.
|
||||
// Intended to for checking that some code should not be executed during
|
||||
// global object construction (only specially crafted code might be safe
|
||||
// to execute at that time).
|
||||
void AssertMainHasStarted();
|
||||
|
||||
// Call this from main() if AssertMainHasStarted() is incorrectly failing
|
||||
// for your code (its current implmentation relies on a call to InitGoogle()
|
||||
// as the signal that we have reached main(), hence it is not 100% accurate).
|
||||
void SetMainHasStarted();
|
||||
|
||||
// Checks (only in debug mode) if InitGoogle() has been fully executed
|
||||
// and crashes if it has not been.
|
||||
// Indtended for checking that code that depends on complete execution
|
||||
// of InitGoogle() for its proper functioning is safe to execute.
|
||||
void AssertInitGoogleIsDone();
|
||||
|
||||
// Initializes misc google-related things in the binary.
|
||||
// In particular it does REQUIRE_MODULE_INITIALIZED(command_line_flags_parsing)
|
||||
// parses command line flags and does RUN_MODULE_INITIALIZERS() (in that order).
|
||||
// If a flag is defined more than once in the command line or flag
|
||||
// file, the last definition is used.
|
||||
// Typically called early on in main() and must be called before other
|
||||
// threads start using functions from this file.
|
||||
//
|
||||
// 'usage' provides a short usage message passed to SetUsageMessage().
|
||||
// 'argc' and 'argv' are the command line flags to parse.
|
||||
// If 'remove_flags' then parsed flags are removed.
|
||||
void InitGoogle(const char* usage, int* argc, char*** argv, bool remove_flags);
|
||||
|
||||
// Normally, InitGoogle will chroot (if requested with the --chroot flag)
|
||||
// and setuid to --uid and --gid (default nobody).
|
||||
// This version will not, and you will be responsible for calling
|
||||
// ChangeRootAndUser
|
||||
// This option is provided for applications that need to read files outside
|
||||
// the chroot before chrooting.
|
||||
void InitGoogleExceptChangeRootAndUser(const char* usage, int* argc,
|
||||
char*** argv, bool remove_flags);
|
||||
// Thread-hostile.
|
||||
void ChangeRootAndUser();
|
||||
|
||||
// if you need to flush InitGoogle's resources from a sighandler
|
||||
void SigHandlerFlushInitGoogleResources();
|
||||
|
||||
// Alter behavior of error to not dump core on an error.
|
||||
// Simply cleanup and exit. Thread-hostile.
|
||||
void SetNoCoreOnError();
|
||||
|
||||
// limit the amount of physical memory used by this process to a
|
||||
// fraction of the available physical memory. The process is killed if
|
||||
// it tries to go beyond this limit. If randomize is set, we reduce
|
||||
// the fraction a little in a sort-of-random way. randomize is meant
|
||||
// to be used for applications which run many copies -- by randomizing
|
||||
// the limit, we can avoid having all copies of the application hit
|
||||
// the limit (and die) at the same time.
|
||||
void LimitPhysicalMemory(double fraction, bool randomize);
|
||||
|
||||
// Return the limit set on physical memory, zero if error or no limit set.
|
||||
uint64 GetPhysicalMemoryLimit();
|
||||
|
||||
// Add specified closure to the set of closures which are executed
|
||||
// when the program dies a horrible death (signal, etc.)
|
||||
//
|
||||
// Note: These are not particularly efficient. Use sparingly.
|
||||
// Note: you can't just use atexit() because functions registered with
|
||||
// atexit() are supposedly only called on normal program exit, and we
|
||||
// want to do things like flush logs on failures.
|
||||
void RunOnFailure(Closure* closure);
|
||||
|
||||
// Remove specified closure references from the set created by RunOnFailure.
|
||||
void CancelRunOnFailure(Closure* closure);
|
||||
|
||||
// Adds specified Callback2 instances to a set of callbacks that are
|
||||
// executed when the program crashes. Two values: signo and ucontext_t*
|
||||
// will be passed into these callback functions. We use void* to avoid the
|
||||
// use of ucontext_t on non-POSIX systems.
|
||||
//
|
||||
// Note: it is recommended that these callbacks are signal-handler
|
||||
// safe. Also, the calls of these callbacks are not protected by
|
||||
// a mutex, so they are better to be multithread-safe.
|
||||
void RunOnFailureCallback2(Callback2<int, void*>* callback);
|
||||
void CancelRunOnFailureCallback2(Callback2<int, void*>* callback);
|
||||
|
||||
// Return true if the google default signal handler is running, false
|
||||
// otherwise. Sometimes callbacks specified with
|
||||
// RunOnFailure{,Callback2} are not called because the process hangs
|
||||
// or takes too long to symbolize callstacks. Users may want to
|
||||
// augment the RunOnFailure mechanism with a dedicated thread which
|
||||
// polls the below function periodically (say, every second) and runs
|
||||
// their failure closures when it returns true.
|
||||
bool IsFailureSignalHandlerRunning();
|
||||
|
||||
// Type of function used for printing in stack trace dumping, etc.
|
||||
// We avoid closures to keep things simple.
|
||||
typedef void DebugWriter(const char*, void*);
|
||||
|
||||
// A few useful DebugWriters
|
||||
DebugWriter DebugWriteToStderr;
|
||||
DebugWriter DebugWriteToStream;
|
||||
DebugWriter DebugWriteToFile;
|
||||
DebugWriter DebugWriteToString;
|
||||
|
||||
// Dump current stack trace omitting the topmost 'skip_count' stack frames.
|
||||
void DumpStackTrace(int skip_count, DebugWriter *w, void* arg);
|
||||
|
||||
// Dump given pc and stack trace.
|
||||
void DumpPCAndStackTrace(void *pc, void *stack[], int depth,
|
||||
DebugWriter *writerfn, void *arg);
|
||||
|
||||
// Returns the program counter from signal context, NULL if unknown.
|
||||
// vuc is a ucontext_t *. We use void* to avoid the use
|
||||
// of ucontext_t on non-POSIX systems.
|
||||
void* GetPC(void* vuc);
|
||||
|
||||
// Dump current address map.
|
||||
void DumpAddressMap(DebugWriter *w, void* arg);
|
||||
|
||||
// Dump information about currently allocated memory.
|
||||
void DumpMallocStats(DebugWriter *w, void* arg);
|
||||
|
||||
// Return true if currently executing in the google failure signal
|
||||
// handler. If this returns true you should:
|
||||
//
|
||||
// - avoid allocating anything via malloc/new
|
||||
// - assume that your stack limit is SIGSTKSZ
|
||||
// - assume that no other thread can be executing in the failure handler
|
||||
bool InFailureSignalHandler();
|
||||
|
||||
// Return the alternate signal stack size (in bytes) needed in order to
|
||||
// safely run the failure signal handlers. The returned value will
|
||||
// always be a multiple of the system page size.
|
||||
int32 GetRequiredAlternateSignalStackSize();
|
||||
|
||||
#endif // _GOOGLE_H_
|
||||
-384
@@ -1,384 +0,0 @@
|
||||
// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef BASE_GOOGLEINIT_H_
|
||||
#define BASE_GOOGLEINIT_H_
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Initialization sequence in C++ and Google.
|
||||
//
|
||||
// This library provides helpers to arrange pieces of initialization code
|
||||
// for some global objects/state to be executed at well-defined
|
||||
// moment in time and in a well-defined order.
|
||||
//
|
||||
// This library is flexible enough and should be used to do all
|
||||
// initialization for global/static objects
|
||||
// except maybe for a few very-low level libraries (mainly inside //base).
|
||||
// Comments in googleinit.cc discuss the reasons for this.
|
||||
//
|
||||
// For the default *MODULE* macros provided below,
|
||||
// the initialization happens automatically
|
||||
// during execution of InitGoogle() -- see google.h,
|
||||
// a call to which should normally be the first statement of main().
|
||||
//
|
||||
// A module can register code to be executed by InitGoogle().
|
||||
// For example, one could place the following in common/hostname.cc:
|
||||
//
|
||||
// static const char* my_hostname = NULL;
|
||||
// REGISTER_MODULE_INITIALIZER(hostname, {
|
||||
// // Code to initialize "my_hostname"
|
||||
// });
|
||||
//
|
||||
// (Note that, due to preprocessor weirdness, there may be issues with
|
||||
// the use of commas in your initialization code. If you run into them,
|
||||
// try using parens around the commas, or use a helper function as follows:
|
||||
//
|
||||
// static const char* my_hostname = NULL;
|
||||
// static void InitMyHostname() {
|
||||
// // Code to initialize "my_hostname"
|
||||
// }
|
||||
// REGISTER_MODULE_INITIALIZER(my_hostname, InitMyHostname());
|
||||
//
|
||||
// This also helps the compiler to accurately attribute compilation errors
|
||||
// to pieces of your initialization code.
|
||||
//
|
||||
// Note that each piece of registered initialized code is tagged
|
||||
// with an identifier ('my_hostname' in the previous example). This
|
||||
// is useful to control the order of initialization. For example,
|
||||
// if we want file initialization to occur after hostname
|
||||
// initialization, we can place the following in file/base/file.cc:
|
||||
//
|
||||
// REGISTER_MODULE_INITIALIZER(file, {
|
||||
// // File initialization goes here
|
||||
// });
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE(my_hostname, file);
|
||||
// // requires my_hostname's initializer to run before file's
|
||||
//
|
||||
// Alternatively the following *deprecated* method is also supported
|
||||
// to accomplish the same ordering of initialization:
|
||||
//
|
||||
// REGISTER_MODULE_INITIALIZER(file, {
|
||||
// REQUIRE_MODULE_INITIALIZED(my_hostname);
|
||||
// // File initialization goes here
|
||||
// });
|
||||
//
|
||||
// REQUIRE_MODULE_INITIALIZED should really be used only when
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE can not be e.g. to explicitly make
|
||||
// a subset of initializers executed from some non-initializer code or
|
||||
// to define run-time-dependent module dependencies.
|
||||
//
|
||||
// For either of the above to compile we should also place the following
|
||||
// into common/hostname.h and #include that file into file/base/file.cc:
|
||||
//
|
||||
// DECLARE_MODULE_INITIALIZER(my_hostname);
|
||||
//
|
||||
// Initialization dependencies defined via REGISTER_MODULE_INITIALIZER_SEQUENCE
|
||||
// are more flexible: unlike with REQUIRE_MODULE_INITIALIZED, one can also
|
||||
// require that the initialization code defined in the current .cc file
|
||||
// be executed before some other initializer, e.g.:
|
||||
//
|
||||
// In foo_factory.h:
|
||||
// DECLARE_MODULE_INITIALIZER(foo_factory_init);
|
||||
// DECLARE_MODULE_INITIALIZER(foo_factory);
|
||||
//
|
||||
// In foo_factory.cc:
|
||||
// static FooFactory* foo_factory = NULL
|
||||
// REGISTER_MODULE_INITIALIZER(foo_factory_init, {
|
||||
// foo_factory = new FooFactory(...);
|
||||
// });
|
||||
// REGISTER_MODULE_INITIALIZER(foo_factory, {
|
||||
// // e.g. code for some final assimilation of all things registered
|
||||
// // with foo_factory can go here
|
||||
// });
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE(foo_factory_init, foo_factory);
|
||||
//
|
||||
// In my_foo_maker.cc:
|
||||
// REGISTER_MODULE_INITIALIZER(my_registerer, {
|
||||
// // registration of some my_method with foo_factory goes here
|
||||
// });
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE_3(
|
||||
// foo_factory_init, my_registerer, foo_factory);
|
||||
// // my_registerer runs after foo_factory_init, but before foo_factory
|
||||
//
|
||||
// In foo_factory_user.cc:
|
||||
// REGISTER_MODULE_INITIALIZER(foo_user, {
|
||||
// // use of foo_factory goes here
|
||||
// });
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE(foo_factory, foo_user);
|
||||
//
|
||||
// In the above example the initializer execution order will be
|
||||
// foo_factory_init, my_registerer, foo_factory, foo_user
|
||||
// even though both foo_factory.cc and foo_factory_user.cc do not have
|
||||
// explicit dependencies on my_foo_maker.cc (they do not have to know/care
|
||||
// if it exists).
|
||||
//
|
||||
// It is an error to introduce cycles in the initialization
|
||||
// dependencies. The program will die with an error message
|
||||
// if the initialization code encounters cyclic dependencies.
|
||||
//
|
||||
// Normally all the registered initializers are executed after
|
||||
// command-line flags have been parsed.
|
||||
// If you need your initializer to run before parsing of the command-line flags,
|
||||
// e.g. to adjust the (default) value of certain flags, then include google.h
|
||||
// and add a directive like this to your .cc file:
|
||||
//
|
||||
// REGISTER_MODULE_INITIALIZER_SEQUENCE(
|
||||
// my_foo_init, command_line_flags_parsing);
|
||||
//
|
||||
// Note that you can't instead call
|
||||
// REQUIRE_MODULE_INITIALIZED(command_line_flags_parsing);
|
||||
// in the code of your initializer: actual command-line parsing
|
||||
// is executed by InitGoogle() not in a registered initializer.
|
||||
//
|
||||
// A piece of code can declare a dependency on a module using the
|
||||
// REQUIRE_MODULE macro. This macro creates a link time dependency
|
||||
// between the .o which the macro is compiled in and the specified
|
||||
// module. This can be useful in making link time dependencies
|
||||
// explicit in the code instead of relying on the correctness of the
|
||||
// BUILD files. For example, foo.cc can declare (see
|
||||
// file/base/file.h for the REQUIRE_FILE_MODULE definition):
|
||||
//
|
||||
// REQUIRE_FILE_MODULE(localfile);
|
||||
//
|
||||
// Similarly to other uses, DECLARE_FILE_INITIALIZER(localfile)
|
||||
// should be #include-d for the above to compile.
|
||||
// The above will guarantee that the localfile module will be linked into
|
||||
// an application which foo.cc is linked into. Specifically, a link
|
||||
// error will occur if the localfile module is not linked in. The
|
||||
// preferred usage of REQUIRE_*_MODULE is for the module writer to
|
||||
// provide an external .h which contains the REQUIRE_* macro. In the
|
||||
// above example, the localfile module writer would provide localfile.h:
|
||||
//
|
||||
// #ifndef FILE_LOCALFILE_H_
|
||||
// #define FILE_LOCALFILE_H_
|
||||
//
|
||||
// #include "file/base/file.h"
|
||||
//
|
||||
// DECLARE_FILE_INITIALIZER(localfile);
|
||||
// REQUIRE_FILE_MODULE(localfile);
|
||||
//
|
||||
// #endif // FILE_LOCALFILE_H_
|
||||
//
|
||||
// Now a user of localfile can declare their dependence on it by
|
||||
// #including "localfile.h".
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// The following code is mostly ugly details about how the
|
||||
// initialization is implemented, and can be safely ignored
|
||||
// by users of the initialization facility.
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
|
||||
// A static instance of 'GoogleInitializer' is declared for every
|
||||
// piece of initialization code. The constructor registers the
|
||||
// code in the initialization table. This class is thread-safe.
|
||||
class GoogleInitializer {
|
||||
public:
|
||||
typedef void (*Initializer)();
|
||||
|
||||
// Register the specified initialization "function" as the
|
||||
// initialization code for "name". The "type" parameter controls
|
||||
// which initializer set this initializer will added to. Note that
|
||||
// an initializer might end up being run from a different set if it
|
||||
// is required using the REQUIRE_GOOGLE_INITIALIZED macro. Normally
|
||||
// the type parameter is "module". Its existence allows the
|
||||
// specification of other "initializer sets." See file/base/file.h
|
||||
// and File::Init() for an example of such a set. It's unlikely this
|
||||
// additional functionality will be used very often.
|
||||
GoogleInitializer(const char* type, const char* name, Initializer function);
|
||||
|
||||
// Invoke all registered initializers that have not yet been
|
||||
// executed. The "type" parameter specifies which set of
|
||||
// initializers to run. The initializers are invoked in
|
||||
// lexicographically increasing order by name, except as necessary
|
||||
// to satisfy dependencies. This routine is invoked by InitGoogle(),
|
||||
// so application code should not call it except in special
|
||||
// circumstances.
|
||||
static void RunInitializers(const char* type);
|
||||
|
||||
// If this initialization has not yet been executed, runs it
|
||||
// right after running all the initializers registered to come before it,
|
||||
// these initializers are invoked in lexicographically increasing order
|
||||
// by name, except as necessary to satisfy dependencies.
|
||||
// It is an error to call this method if the corresponding
|
||||
// initializer method is currently active (i.e., we do not
|
||||
// allow cycles in the requirement graph).
|
||||
void Require();
|
||||
|
||||
// Helper data-holder struct that is passed into
|
||||
// DependencyRegisterer's c-tor below.
|
||||
struct Dependency {
|
||||
Dependency(const char* n, GoogleInitializer* i) : name(n), initializer(i) {}
|
||||
const char* const name;
|
||||
GoogleInitializer* const initializer;
|
||||
};
|
||||
|
||||
// A static instance of 'DependencyRegisterer' is declared for every
|
||||
// piece of initializer ordering definition. The constructor registers the
|
||||
// ordering relation in the initialization table. This class is thread-safe.
|
||||
struct DependencyRegisterer {
|
||||
// Ask to run initializer specified by 'dependency'
|
||||
// before the 'initializer' with 'name'.
|
||||
// Both initializers are supposed to be of type 'type'.
|
||||
DependencyRegisterer(const char* type,
|
||||
const char* name,
|
||||
GoogleInitializer* initializer,
|
||||
const Dependency& dependency);
|
||||
private:
|
||||
void SharedConstructorCode(const char* type,
|
||||
const char* name,
|
||||
GoogleInitializer* initializer,
|
||||
const Dependency& dependency);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(DependencyRegisterer);
|
||||
};
|
||||
|
||||
// Side note: If we happen to decide that connecting all initializers into an
|
||||
// explicit DAG with one/few sink node(s) that depend on everything else
|
||||
// is important (to explicitly specify in code all the
|
||||
// required initializers of a binary) we can provide something like
|
||||
// static bool DoneAllInitializers(const char *type);
|
||||
// to check that all registered initializers have been executed.
|
||||
// Going this route does not seem worth it though:
|
||||
// it's equivalent to mandating creation of a third complete
|
||||
// module dependency DAG, the first two being via #include-s and BUILD
|
||||
// dependencies.
|
||||
|
||||
// Helper structs in .cc; public to declare file-level globals.
|
||||
struct InitializerData;
|
||||
struct TypeData;
|
||||
|
||||
private:
|
||||
void SharedConstructorCode(const char* type,
|
||||
const char* name,
|
||||
Initializer function);
|
||||
|
||||
const string type_; // Initializer type
|
||||
const string name_; // Initializer name
|
||||
Initializer function_; // The actual initializer
|
||||
bool done_; // Finished initializing?
|
||||
bool is_active_; // Is currently running
|
||||
|
||||
// Implementation helper for Require() and RunInitializers:
|
||||
// Runs initializer *this and all its dependencies
|
||||
// if that has not happened yet.
|
||||
// Assumes table_lock is reader-held and TypeData::lock for type_ is held.
|
||||
void RunIfNecessary_Locked();
|
||||
|
||||
// Helper to initialize/create and return data for a given initializer type.
|
||||
static TypeData* InitializerTypeData(const char* type);
|
||||
|
||||
DISALLOW_EVIL_CONSTRUCTORS(GoogleInitializer);
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Implementation Internals (most users should ignore)
|
||||
//
|
||||
// The *_GOOGLE_* macros are used to make separate initializer
|
||||
// sets. They should not be used directly by application code, but are
|
||||
// useful to library writers who want to create a new registration
|
||||
// mechanism. (See google2file.h and the *_FILE_* macros for an
|
||||
// example).
|
||||
|
||||
// TODO(maxim): When DECLARE_GOOGLE_INITIALIZER is not used in
|
||||
// REQUIRE_GOOGLE_INITIALIZED and REQUIRE_GOOGLE_MODULE
|
||||
// put google_initializer_##type##_##name (and google_init_##type##_##name)
|
||||
// into a gI##type namespace to force our users to use
|
||||
// DECLARE_GOOGLE_INITIALIZER not reimplement it
|
||||
// to manually declare an initializer.
|
||||
|
||||
#define DECLARE_GOOGLE_INITIALIZER(type, name) \
|
||||
extern GoogleInitializer google_initializer_##type##_##name
|
||||
|
||||
#define REGISTER_GOOGLE_INITIALIZER(type, name, body) \
|
||||
static void google_init_##type##_##name() { body; } \
|
||||
GoogleInitializer google_initializer_##type##_##name( \
|
||||
#type, #name, google_init_##type##_##name)
|
||||
|
||||
// Require initializer name1 of 'type' to run before initializer
|
||||
// initializer name2 of same 'type' (i.e. in the order they are written out).
|
||||
// "Sequence" only means ordering, not direct executions sequence
|
||||
// without any other initializer executed in between.
|
||||
// Initializers for both modules must be declared
|
||||
// with DECLARE_GOOGLE_INITIALIZER at this point.
|
||||
#define REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name1, name2) \
|
||||
namespace { \
|
||||
static GoogleInitializer::DependencyRegisterer \
|
||||
google_initializer_dependency_##type##_##name1##_##name2( \
|
||||
#type, #name2, &google_initializer_##type##_##name2, \
|
||||
GoogleInitializer::Dependency( \
|
||||
#name1, &google_initializer_##type##_##name1)); \
|
||||
}
|
||||
// Require initializers name1, name2, name3 of 'type' to run in the above order.
|
||||
// Added to support this frequent use case more conveniently.
|
||||
#define REGISTER_GOOGLE_INITIALIZER_SEQUENCE_3(type, name1, name2, name3) \
|
||||
REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name1, name2); \
|
||||
REGISTER_GOOGLE_INITIALIZER_SEQUENCE(type, name2, name3)
|
||||
|
||||
// Calling REQUIRE_GOOGLE_INITIALIZED(type, foo) means to make sure intializer
|
||||
// for foo and everything it depends on have executed, and as such
|
||||
// it can be used to e.g. pre-execute subsets of initializers
|
||||
// e.g. before everything is executed via RUN_GOGLE_INITIALIZERS(type).
|
||||
// The initializer must be declared with DECLARE_GOOGLE_INITIALIZER(type, name).
|
||||
// TODO : remove DECLARE_GOOGLE_INITIALIZER here
|
||||
// when all old code makes use of DECLARE_GOOGLE_INITIALIZER.
|
||||
#define REQUIRE_GOOGLE_INITIALIZED(type, name) \
|
||||
do { \
|
||||
DECLARE_GOOGLE_INITIALIZER(type, name); \
|
||||
google_initializer_##type##_##name.Require(); \
|
||||
} while (0)
|
||||
|
||||
#define RUN_GOOGLE_INITIALIZERS(type) \
|
||||
do { \
|
||||
GoogleInitializer::RunInitializers(#type); \
|
||||
} while (0)
|
||||
|
||||
// We force the dependant module to be loaded by taking the
|
||||
// address of an object inside the dependency
|
||||
// (created by REGISTER_GOOGLE_INITIALIZER). The rest
|
||||
// is required to avoid warnings about unused variables and
|
||||
// make sure gcc doesn't optimize it out of existence.
|
||||
// The initializer must be declared with DECLARE_GOOGLE_INITIALIZER(type, name).
|
||||
// TODO : remove DECLARE_GOOGLE_INITIALIZER here
|
||||
// when all old code makes use of DECLARE_GOOGLE_INITIALIZER.
|
||||
#define REQUIRE_GOOGLE_MODULE(type, name) \
|
||||
DECLARE_GOOGLE_INITIALIZER(type, name); \
|
||||
static struct GoogleModuleRef_##name { \
|
||||
GoogleModuleRef_##name(GoogleInitializer* r) : ref(r) {} \
|
||||
GoogleInitializer* ref; \
|
||||
} google_module_ref_##name(&google_initializer_##type##_##name)
|
||||
|
||||
|
||||
// External Interface (most users should use these macros)
|
||||
|
||||
#define DECLARE_MODULE_INITIALIZER(name) \
|
||||
DECLARE_GOOGLE_INITIALIZER(module, name)
|
||||
|
||||
#define REGISTER_MODULE_INITIALIZER(name, body) \
|
||||
REGISTER_GOOGLE_INITIALIZER(module, name, body)
|
||||
|
||||
#define REGISTER_MODULE_INITIALIZER_SEQUENCE(name1, name2) \
|
||||
REGISTER_GOOGLE_INITIALIZER_SEQUENCE(module, name1, name2)
|
||||
|
||||
#define REGISTER_MODULE_INITIALIZER_SEQUENCE_3(name1, name2, name3) \
|
||||
REGISTER_GOOGLE_INITIALIZER_SEQUENCE_3(module, name1, name2, name3)
|
||||
|
||||
#define REQUIRE_MODULE_INITIALIZED(name) \
|
||||
REQUIRE_GOOGLE_INITIALIZED(module, name)
|
||||
|
||||
#define RUN_MODULE_INITIALIZERS() \
|
||||
RUN_GOOGLE_INITIALIZERS(module)
|
||||
|
||||
// TODO : maybe rename this as REQUIRE_MODULE_LINKED
|
||||
#define REQUIRE_MODULE(name) \
|
||||
REQUIRE_GOOGLE_MODULE(module, name)
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
#endif // BASE_GOOGLEINIT_H_
|
||||
Referência em uma Nova Issue
Bloquear um usuário