source: branches/dev/Common/IpJournalist.cpp @ 567

Last change on this file since 567 was 567, checked in by andreasw, 15 years ago

adapted for Portland compilers

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.5 KB
Line 
1// Copyright (C) 2004, 2005 International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpJournalist.cpp 567 2005-11-01 23:27:11Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
8
9#include "IpJournalist.hpp"
10#include "IpDebug.hpp"
11
12namespace Ipopt
13{
14
15  Journalist::Journalist()
16  {}
17
18  Journalist::~Journalist()
19  {
20    journals_.clear();
21  }
22
23  void Journalist::Printf( EJournalLevel level, EJournalCategory category,
24                           const char* pformat, ... ) const
25  {
26    // wrap the arguments and pass to VPrintf
27    va_list ap;
28    va_start(ap, pformat);
29
30    VPrintf(level, category, pformat, ap);
31
32    va_end(ap);
33  }
34
35  void Journalist::PrintStringOverLines(EJournalLevel level,
36                                        EJournalCategory category,
37                                        Index indent_spaces, Index max_length,
38                                        const std::string& line) const
39  {
40    DBG_ASSERT(indent_spaces + max_length + 1 < 1024);
41    char buffer[1024];
42    std::string::size_type last_line_pos = 0;
43    std::string::size_type last_word_pos = 0;
44    bool first_line = true;
45    Index buffer_pos = 0;
46
47    while (last_line_pos < line.length()) {
48      std::string::size_type line_pos = last_line_pos;
49      Index curr_length = 0;
50      while (curr_length < max_length && line_pos < line.length()) {
51        buffer[buffer_pos] = line[line_pos];
52        if (line[line_pos] == ' ') {
53          last_word_pos = line_pos+1;
54        }
55        curr_length++;
56        buffer_pos++;
57        line_pos++;
58      }
59      if (line_pos == line.length()) {
60        // This is the last line to be printed.
61        buffer[buffer_pos] = '\0';
62        Printf(level, category, "%s", buffer);
63        break;
64      }
65      if (last_word_pos == last_line_pos) {
66        if (line[line_pos]==' ') {
67          buffer[buffer_pos] = '\0';
68          last_word_pos = line_pos+1;
69          last_line_pos = line_pos+1;
70        }
71        else {
72          // The current word is too long to fit into one line
73          // split word over two lines
74          buffer[buffer_pos-1] = '-';
75          buffer[buffer_pos] = '\0';
76          last_word_pos = line_pos-1;
77          last_line_pos = last_word_pos;
78        }
79      }
80      else {
81        // insert '\0' character after last complete word
82        buffer[buffer_pos-(line_pos-last_word_pos)-1] = '\0';
83        last_line_pos = last_word_pos;
84      }
85
86      Printf(level, category, "%s\n", buffer);
87      if (first_line) {
88        for(Index i=0; i<indent_spaces; i++) {
89          buffer[i] = ' ';
90        }
91        first_line = false;
92      }
93      buffer_pos = indent_spaces;
94    }
95  }
96
97  void Journalist::PrintfIndented( EJournalLevel level,
98                                   EJournalCategory category, Index indent_level,
99                                   const char* pformat, ... ) const
100  {
101    // wrap the arguments and pass to VPrintfIndented
102    va_list ap;
103    va_start(ap, pformat);
104
105    VPrintfIndented(level, category, indent_level, pformat, ap);
106
107    va_end(ap);
108  }
109
110  //   void Journalist::PrintVector(EJournalLevel level,
111  //                                EJournalCategory category,
112  //                                const std::string& name,
113  //                                const Vector& vector,
114  //                                Index indent,
115  //                                const std::string prefix) const
116  //   {
117  //     // print the msg on every journal that accepts
118  //     // the category and output level
119  //     for (Index i=0; i<(Index)journals_.size(); i++) {
120  //       if (journals_[i]->IsAccepted(category, level)) {
121  //         // print the message
122  //         journals_[i]->PrintVector(name, vector, indent, prefix);
123  //       }
124  //     }
125  //   }
126
127  //   void Journalist::PrintMatrix(EJournalLevel level,
128  //                                EJournalCategory category,
129  //                                const std::string& name,
130  //                                const Matrix& matrix,
131  //                                Index indent /*=0*/,
132  //                                std::string prefix /*=""*/) const
133  //   {
134  //     // print the msg on every journal that accepts
135  //     // the category and output level
136  //     for (Index i=0; i<(Index)journals_.size(); i++) {
137  //       if (journals_[i]->IsAccepted(category, level)) {
138  //         // print the message
139  //         journals_[i]->PrintMatrix(name, matrix, indent, prefix);
140  //       }
141  //     }
142  //   }
143
144  void Journalist::VPrintf(
145    EJournalLevel level,
146    EJournalCategory category,
147    const char* pformat, va_list ap) const
148  {
149    // print the msg on every journal that accepts
150    // the category and output level
151    for (Index i=0; i<(Index)journals_.size(); i++) {
152      if (journals_[i]->IsAccepted(category, level)) {
153        // print the message
154#ifdef HAVE_VA_COPY
155        va_list apcopy;
156        va_copy(apcopy, ap);
157        journals_[i]->Printf(pformat, apcopy);
158        va_end(apcopy);
159#else
160
161        journals_[i]->Printf(pformat, ap);
162#endif
163
164      }
165    }
166  }
167
168  void Journalist::VPrintfIndented(
169    EJournalLevel level,
170    EJournalCategory category,
171    Index indent_level,
172    const char* pformat, va_list ap) const
173  {
174    // print the msg on every journal that accepts
175    // the category and output level
176    for (Index i=0; i<(Index)journals_.size(); i++) {
177      if (journals_[i]->IsAccepted(category, level)) {
178
179        // indent the appropriate amount
180        for (Index s=0; s<indent_level; s++) {
181          journals_[i]->Print("  ");
182        }
183
184        // print the message
185#ifdef HAVE_VA_COPY
186        va_list apcopy;
187        va_copy(apcopy, ap);
188        journals_[i]->Printf(pformat, apcopy);
189        va_end(apcopy);
190#else
191
192        journals_[i]->Printf(pformat, ap);
193#endif
194
195      }
196    }
197  }
198
199  bool Journalist::ProduceOutput(EJournalLevel level,
200                                 EJournalCategory category) const
201  {
202    for (Index i=0; i<(Index)journals_.size(); i++) {
203      if (journals_[i]->IsAccepted(category, level)) {
204        return true;
205      }
206    }
207    return false;
208  }
209
210  bool Journalist::AddJournal(const SmartPtr<Journal> jrnl)
211  {
212    DBG_ASSERT(IsValid(jrnl));
213    std::string name = jrnl->Name();
214
215    SmartPtr<Journal> temp = GetJournal(name);
216    DBG_ASSERT(IsNull(temp));
217    if (IsValid(temp)) {
218      return false;
219    }
220
221    journals_.push_back(jrnl);
222    return true;
223  }
224
225  SmartPtr<Journal> Journalist::AddFileJournal(
226    const std::string& journal_name,
227    const std::string& fname,
228    EJournalLevel default_level
229  )
230  {
231    SmartPtr<FileJournal> temp = new FileJournal(journal_name, default_level);
232
233    // Open the file (Note:, a fname of "stdout" is handled by the
234    // Journal class to mean stdout, etc.
235    if (temp->Open(fname.c_str()) && AddJournal(GetRawPtr(temp))) {
236      return GetRawPtr(temp);
237    }
238    return NULL;
239  }
240
241  void Journalist::FlushBuffer() const
242  {
243    for (Index i=0; i<(Index)journals_.size(); i++) {
244      journals_[i]->FlushBuffer();
245    }
246  }
247
248  SmartPtr<Journal> Journalist::GetJournal(
249    const std::string& journal_name
250  )
251  {
252    SmartPtr<Journal> retValue = NULL;
253
254    // try to find the journal
255    for (Index i=0; i<(Index)journals_.size(); i++) {
256      SmartPtr<Journal> tmp = journals_[i];
257      if (tmp->Name() == journal_name) {
258        retValue = tmp;
259        break;
260      }
261    }
262
263    return retValue;
264  }
265
266  ///////////////////////////////////////////////////////////////////////////
267  //                 Implementation of the Journal class                   //
268  ///////////////////////////////////////////////////////////////////////////
269
270  Journal::Journal(
271    const std::string& name,
272    EJournalLevel default_level
273  )
274      :
275      name_(name)
276  {
277    for (Index i=0; i<J_LAST_CATEGORY; i++) {
278      print_levels_[i] = default_level;
279    }
280  }
281
282  Journal::~Journal()
283  {}
284
285  std::string Journal::Name()
286  {
287    return name_;
288  }
289
290  bool Journal::IsAccepted(
291    EJournalCategory category,
292    EJournalLevel level
293  ) const
294  {
295    if (print_levels_[(Index)category] >= (Index) level) {
296      return true;
297    }
298
299    return false;
300  }
301
302  void Journal::SetPrintLevel(
303    EJournalCategory category,
304    EJournalLevel level)
305  {
306    print_levels_[(Index)category] = (Index) level;
307  }
308
309  void Journal::SetAllPrintLevels(
310    EJournalLevel level)
311  {
312    for (Index category=(Index)J_DBG;
313         category<(Index)J_LAST_CATEGORY;
314         category++) {
315      print_levels_[category] = (Index) level;
316    }
317  }
318
319
320  ///////////////////////////////////////////////////////////////////////////
321  //                 Implementation of the FileJournal class                   //
322  ///////////////////////////////////////////////////////////////////////////
323
324  FileJournal::FileJournal(
325    const std::string& name,
326    EJournalLevel default_level
327  )
328      :
329      Journal(name, default_level),
330      file_(NULL)
331  {}
332
333  FileJournal::~FileJournal()
334  {
335    if (file_ && file_ != stdout && file_ != stderr) {
336      // close the file
337      fclose(file_);
338    }
339    file_ = NULL;
340  }
341
342
343  bool FileJournal::Open(const char* fname)
344  {
345    if (file_ && file_ != stdout && file_ != stderr) {
346      // file already opened, close it
347      fclose(file_);
348    }
349    file_ = NULL;
350
351    if (strcmp("stdout", fname)==0) {
352      file_=stdout;
353      return true;
354    }
355    else if (strcmp("stderr", fname)==0) {
356      file_=stderr;
357      return true;
358    }
359    else {
360      // open the file on disk
361      file_ = fopen(fname, "w+");
362      if (file_) {
363        return true;
364      }
365    }
366
367    return false;
368  }
369
370
371  void FileJournal::PrintImpl(const char* str)
372  {
373    DBG_START_METH("Journal::Print", 0);
374    if (file_) {
375      fprintf(file_, str);
376      DBG_EXEC(0, fflush(file_));
377    }
378  }
379
380  void FileJournal::PrintfImpl(const char* pformat, va_list ap)
381  {
382    DBG_START_METH("Journal::Printf", 0);
383    if (file_) {
384      vfprintf(file_, pformat, ap);
385      DBG_EXEC(0, fflush(file_));
386    }
387  }
388
389  //   void FileJournal::PrintVectorImpl(const std::string name, const Vector& vector, Index indent, std::string prefix)
390  //   {
391  //     DBG_START_METH("Journal::PrintVector", 0);
392  //     if (file_) {
393  //       vector.Print(file_, name, indent, prefix);
394  //       DBG_EXEC(0, fflush(file_));
395  //     }
396  //   }
397
398  //   void FileJournal::PrintMatrixImpl(const std::string name, const Matrix& matrix, Index indent, std::string prefix)
399  //   {
400  //     DBG_START_METH("Journal::PrintMatrix", 0);
401  //     if (file_) {
402  //       matrix.Print(file_, name, indent, prefix);
403  //       DBG_EXEC(0, fflush(file_));
404  //     }
405  //   }
406
407  void FileJournal::FlushBufferImpl()
408  {
409    if (file_) {
410      fflush(file_);
411    }
412  }
413} // namespace Ipopt
Note: See TracBrowser for help on using the repository browser.