source: branches/heur/Cbc/src/CbcGenMessages.cpp @ 885

Last change on this file since 885 was 640, checked in by forrest, 12 years ago

trunk from branches/devel

File size: 4.9 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
15  char svnid[] = "$Id$" ;
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 { CbcGenMsgCode inID ;
36                 int exID ;
37                 int lvl ;
38                 const char *fmt ; } MsgDefn ;
39
40static MsgDefn us_en_defns[] = {
41  // informational (0 -- 2999)
42  { CBCGEN_TEST_MSG, 1, 2, "This is the us_en test message, eh." },
43  { CBCGEN_NEW_SOLVER, 2, 2, "Solver is now \"%s\"." },
44  // warning (3000 -- 5999)
45  // Non-fatal errors (6000 -- 8999)
46  // Fatal errors (9000 and up)
47  { CBCGEN_CONFUSION, 9001, 1, "Internal confusion, line %d." },
48  { CBCGEN_DUMMY_END, 999999, 0, "" }
49} ;
50
51/*
52  We seem to need a dummy CoinMessages object to prevent the compiler from
53  complaining that CoinMessages::Language is unintialised.
54
55  const CoinMessages dummy(0) ;
56*/
57/*
58  The author is Canadian, eh. But we'll go with us_en anyways.
59*/
60  const CoinMessages::Language default_language = CoinMessages::us_en ;
61
62} /* End file local namespace */
63
64/*!
65  This function constructs a CoinMessages object filled with a default set of
66  messages, overlaid with whatever is available for the specified language.
67  It is used to establish the initial set of messages, and is also called
68  whenever the language is changed. The latter, because there's no way of
69  guaranteeing that the message sets for alternate languages will all
70  replace the same messages. This approach guarantees that the set of
71  messages is always composed of the default language overlaid with any
72  messages for an alternate language.
73
74  The default for lang is us_en, specified up in CbcGenCtlBlk.hpp. If you want
75  to change the default language, change the declaration there. That said,
76  you'll also have to provide the necessary message definitions and augment the
77  case statements below.
78*/
79
80void CbcGenCtlBlk::setMessages (CoinMessages::Language lang)
81
82{
83/*
84  If messages exist, in the correct language, we have nothing more to do.
85*/
86  if (msgs_ && cur_lang_ == lang)
87  { return ; }
88/*
89  Otherwise, we need to do a wholesale rebuild. Create a new object of the
90  appropriate size.
91*/
92  CoinMessages *msgs = new CoinMessages(sizeof(us_en_defns)/sizeof(MsgDefn)) ;
93
94  msgs->setLanguage(lang) ;
95  strcpy(msgs->source_,"CbcG");
96/*
97  Yes, this is gloriously redundant, but it's set up in anticipation of
98  future extensions.
99*/
100  MsgDefn *msgdefn ;
101  switch (lang)
102  { case CoinMessages::us_en:
103    { msgdefn = us_en_defns ;
104      break ; }
105    default:
106    { msgdefn = us_en_defns ;
107      break ; } }
108/*
109  Open a loop to create and load the messages.
110*/
111  while (msgdefn->inID != CBCGEN_DUMMY_END)
112  { CoinOneMessage msg(msgdefn->exID,msgdefn->lvl,msgdefn->fmt) ;
113    msgs->addMessage(msgdefn->inID,msg) ;
114    msgdefn++ ; }
115/*
116  Now, if the local language differs from the default language, load any
117  overrides. Again, useless now, but maybe in the future ...
118*/
119  if (lang != cur_lang_)
120  { switch (lang)
121    { case CoinMessages::us_en:
122      { msgdefn = us_en_defns ;
123        break; }
124      default:
125      { msgdefn = us_en_defns ;
126        break; } }
127
128    while (msgdefn->inID != CBCGEN_DUMMY_END)
129    { msgs->replaceMessage(msgdefn->inID,msgdefn->fmt) ;
130      msgdefn++ ; } }
131/*
132  Each CoinOneMessage has a fixed-length array to hold the message; by default
133  this is 400 chars. Convert to `compressed' CoinOneMessage objects where the
134  array is only as large as necessary. Any attempt to replace a message, or the
135  message text, will automatically trigger a decompress operation before doing
136  the replacement, but the messages will *not* be automatically recompressed.
137*/
138  msgs->toCompact() ;
139  msgs_ = msgs ;
140
141  return ; }
142
143
144/*
145  Replaces the current message handler with the handler supplied as a
146  parameter. If ourMsgHandler_ is true, the existing handler is destroyed.
147*/
148
149void CbcGenCtlBlk::passInMessageHandler (CoinMessageHandler *newMsgHandler)
150
151{ if (msgHandler_ && ourMsgHandler_)
152  { delete msgHandler_ ; }
153
154  msgHandler_ = newMsgHandler ;
155  ourMsgHandler_ = false ;
156
157  return ; }
158
159/*
160  Start a message. This routine buries the whole business of locating the
161  message handler and messages, getting the log level right, etc. If, by some
162  chance, messages are not yet loaded, do so.
163*/
164
165CoinMessageHandler &CbcGenCtlBlk::message (CbcGenMsgCode inID)
166
167{ if (!msgs_)
168  { setMessages() ; }
169  msgHandler_->setLogLevel(logLvl_) ;
170
171  msgHandler_->message(inID,*msgs_) ;
172
173  return (*msgHandler_) ; }
174   
Note: See TracBrowser for help on using the repository browser.