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

Last change on this file since 501 was 501, checked in by claird, 15 years ago

Cleaned up all the Copyright comments.

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