source: trunk/Cbc/src/CbcGenMessages.cpp @ 1514

Last change on this file since 1514 was 1464, checked in by stefan, 9 years ago

merge split branch into trunk; fix some examples

File size: 5.3 KB
Line 
1/*! \legal
2  Copyright (C) 2007
3  Lou Hafer, International Business Machines Corporation and others. All
4  Rights Reserved.
5
6  This file is part of cbc-generic.
7*/
8
9#include "CbcGenMessages.hpp"
10
11#include "CbcGenCtlBlk.hpp"
12
13namespace {
14
15char svnid[] = "$Id: CbcGenMessages.cpp 1173 2009-06-04 09:44:10Z forrest $" ;
16
17}
18
19/*
20  Begin file local namespace
21*/
22namespace {
23
24/*
25  Message definitions.
26
27  The precise form isn't important here, so long as the method that loads them
28  into a CoinMessages object can come up with values for external ID,
29  detail level, and format string. The use of an enum to provide an internal ID
30  for each message is mainly useful with the internationalisation feature. It
31  makes it easy to slap the same ID on alternate versions of a message.
32*/
33
34
35typedef struct {
36    CbcGenMsgCode inID ;
37    int exID ;
38    int lvl ;
39    const char *fmt ;
40} MsgDefn ;
41
42static MsgDefn us_en_defns[] = {
43    // informational (0 -- 2999)
44    { CBCGEN_TEST_MSG, 1, 2, "This is the us_en test message, eh." },
45    { CBCGEN_NEW_SOLVER, 2, 2, "Solver is now \"%s\"." },
46    // warning (3000 -- 5999)
47    // Non-fatal errors (6000 -- 8999)
48    // Fatal errors (9000 and up)
49    { CBCGEN_CONFUSION, 9001, 1, "Internal confusion, line %d." },
50    { CBCGEN_DUMMY_END, 999999, 0, "" }
51} ;
52
53/*
54  We seem to need a dummy CoinMessages object to prevent the compiler from
55  complaining that CoinMessages::Language is unintialised.
56
57  const CoinMessages dummy(0) ;
58*/
59/*
60  The author is Canadian, eh. But we'll go with us_en anyways.
61*/
62const CoinMessages::Language default_language = CoinMessages::us_en ;
63
64} /* End file local namespace */
65
66/*!
67  This function constructs a CoinMessages object filled with a default set of
68  messages, overlaid with whatever is available for the specified language.
69  It is used to establish the initial set of messages, and is also called
70  whenever the language is changed. The latter, because there's no way of
71  guaranteeing that the message sets for alternate languages will all
72  replace the same messages. This approach guarantees that the set of
73  messages is always composed of the default language overlaid with any
74  messages for an alternate language.
75
76  The default for lang is us_en, specified up in CbcGenCtlBlk.hpp. If you want
77  to change the default language, change the declaration there. That said,
78  you'll also have to provide the necessary message definitions and augment the
79  case statements below.
80*/
81
82void CbcGenCtlBlk::setMessages (CoinMessages::Language lang)
83
84{
85    /*
86      If messages exist, in the correct language, we have nothing more to do.
87    */
88    if (msgs_ && cur_lang_ == lang) {
89        return ;
90    }
91    /*
92      Otherwise, we need to do a wholesale rebuild. Create a new object of the
93      appropriate size.
94    */
95    CoinMessages *msgs = new CoinMessages(sizeof(us_en_defns) / sizeof(MsgDefn)) ;
96
97    msgs->setLanguage(lang) ;
98    strcpy(msgs->source_, "CbcG");
99    /*
100      Yes, this is gloriously redundant, but it's set up in anticipation of
101      future extensions.
102    */
103    MsgDefn *msgdefn ;
104    switch (lang) {
105    case CoinMessages::us_en: {
106        msgdefn = us_en_defns ;
107        break ;
108    }
109    default: {
110        msgdefn = us_en_defns ;
111        break ;
112    }
113    }
114    /*
115      Open a loop to create and load the messages.
116    */
117    while (msgdefn->inID != CBCGEN_DUMMY_END) {
118        CoinOneMessage msg(msgdefn->exID, msgdefn->lvl, msgdefn->fmt) ;
119        msgs->addMessage(msgdefn->inID, msg) ;
120        msgdefn++ ;
121    }
122    /*
123      Now, if the local language differs from the default language, load any
124      overrides. Again, useless now, but maybe in the future ...
125    */
126    if (lang != cur_lang_) {
127        switch (lang) {
128        case CoinMessages::us_en: {
129            msgdefn = us_en_defns ;
130            break;
131        }
132        default: {
133            msgdefn = us_en_defns ;
134            break;
135        }
136        }
137
138        while (msgdefn->inID != CBCGEN_DUMMY_END) {
139            msgs->replaceMessage(msgdefn->inID, msgdefn->fmt) ;
140            msgdefn++ ;
141        }
142    }
143    /*
144      Each CoinOneMessage has a fixed-length array to hold the message; by default
145      this is 400 chars. Convert to `compressed' CoinOneMessage objects where the
146      array is only as large as necessary. Any attempt to replace a message, or the
147      message text, will automatically trigger a decompress operation before doing
148      the replacement, but the messages will *not* be automatically recompressed.
149    */
150    msgs->toCompact() ;
151    msgs_ = msgs ;
152
153    return ;
154}
155
156
157/*
158  Replaces the current message handler with the handler supplied as a
159  parameter. If ourMsgHandler_ is true, the existing handler is destroyed.
160*/
161
162void CbcGenCtlBlk::passInMessageHandler (CoinMessageHandler *newMsgHandler)
163
164{
165    if (msgHandler_ && ourMsgHandler_) {
166        delete msgHandler_ ;
167    }
168
169    msgHandler_ = newMsgHandler ;
170    ourMsgHandler_ = false ;
171
172    return ;
173}
174
175/*
176  Start a message. This routine buries the whole business of locating the
177  message handler and messages, getting the log level right, etc. If, by some
178  chance, messages are not yet loaded, do so.
179*/
180
181CoinMessageHandler &CbcGenCtlBlk::message (CbcGenMsgCode inID)
182
183{
184    if (!msgs_) {
185        setMessages() ;
186    }
187    msgHandler_->setLogLevel(logLvl_) ;
188
189    msgHandler_->message(inID, *msgs_) ;
190
191    return (*msgHandler_) ;
192}
193
Note: See TracBrowser for help on using the repository browser.