~ubuntu-branches/ubuntu/wily/octave-miscellaneous/wily

« back to all changes in this revision

Viewing changes to src/text_waitbar.cc

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot
  • Date: 2012-10-17 13:40:55 UTC
  • mfrom: (1.1.6)
  • mto: (5.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 13.
  • Revision ID: package-import@ubuntu.com-20121017134055-e8lrxjd3qgcd3kmt
Tags: upstream-1.2.0
Import upstream version 1.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C) 2002 Quentin Spencer <qspencer@ieee.org>
 
2
//
 
3
// This program is free software; you can redistribute it and/or modify it under
 
4
// the terms of the GNU General Public License as published by the Free Software
 
5
// Foundation; either version 3 of the License, or (at your option) any later
 
6
// version.
 
7
//
 
8
// This program is distributed in the hope that it will be useful, but WITHOUT
 
9
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
10
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 
11
// details.
 
12
//
 
13
// You should have received a copy of the GNU General Public License along with
 
14
// this program; if not, see <http://www.gnu.org/licenses/>.
 
15
 
 
16
#include <octave/oct.h>
 
17
 
 
18
// Note the extern "C" is need for mingw with a version of termcap.h
 
19
// without the extern "C" explicitly included. Doing it twice should be
 
20
// harmless.
 
21
extern "C" {
 
22
#if defined (HAVE_TERM_H)
 
23
#  include <term.h>
 
24
#elif defined (HAVE_TERMCAP_H)
 
25
#  include <termcap.h>
 
26
#endif
 
27
};
 
28
 
 
29
#define BUF_SIZE        256
 
30
#define MAX_LEN         240
 
31
#define DEFAULT_LEN     50
 
32
#define BAR_CHAR        '#'
 
33
#define SPACING         3
 
34
 
 
35
static bool no_terminal=false;
 
36
 
 
37
DEFUN_DLD(text_waitbar, args, nargout,
 
38
"  -*- texinfo -*-\n\
 
39
@deftypefn {Loadable Function}  {} text_waitbar (@var{frac})\n\
 
40
@deftypefnx {Loadable Function} {} text_waitbar (@var{frac}, @var{msg})\n\
 
41
@deftypefnx {Loadable Function} {} text_waitbar (0, @var{n})\n\
 
42
Display text-based waitbar/progress bar.\n\
 
43
\n\
 
44
This function is similar to the @code{waitbar} function but is a text, rather\n\
 
45
than graphical bar. The waitbar is filled to fraction @var{frac} which must\n\
 
46
be in the range [0, 1]. Values exactly equal to 0 or 1 clear the waitbar.\n\
 
47
\n\
 
48
The optional message @var{msg} sets the waitbar caption. If Octave is running\n\
 
49
in a smart terminal, the width is automatically detected, and @var{msg} is\n\
 
50
displayed in the waitbar (and truncated if it is too long). Otherwise,\n\
 
51
@var{msg} is not displayed and the width is initialized to a default of 50\n\
 
52
characters, or it can be set to @var{n} characters with\n\
 
53
@code{text_waitbar (0, @var{n})}. If no terminal is detected (such as when\n\
 
54
Octave is run in batch mode and output is redirected), no output is\n\
 
55
generated.\n\
 
56
\n\
 
57
Additional arguments are ignored for compatibility with the graphical\n\
 
58
counterpart of this function but there are no guarantees of perfect\n\
 
59
compatibility.\n\
 
60
\n\
 
61
@seealso{waitbar}\n\
 
62
@end deftypefn\n")
 
63
{
 
64
  static char print_buf[BUF_SIZE];
 
65
  static int n_chars_old;
 
66
  static int pct_int_old;
 
67
  static int length;
 
68
#if defined(USE_TERM)
 
69
  static char term_buffer[1024];
 
70
  static char *begin_rv, *end_rv;
 
71
  static int brvlen, ervlen, pct_pos;
 
72
  static bool smart_term;
 
73
  static bool newtitle = false;
 
74
  static charMatrix title;
 
75
  int j;
 
76
#endif
 
77
  static char *term;
 
78
  static bool init;
 
79
 
 
80
  double pct;
 
81
  int i;
 
82
 
 
83
  octave_value_list retval;
 
84
  retval(0) = Matrix(0,0);
 
85
  int nargin = args.length();
 
86
  if (nargin < 1) {
 
87
    print_usage ();
 
88
    return retval;
 
89
  }
 
90
 
 
91
  if(no_terminal)
 
92
    return retval;
 
93
 
 
94
  pct   = args(0).double_value();
 
95
  if(pct>1.0)   pct     = 1.0;          // to prevent overflow
 
96
 
 
97
#if defined(USE_TERM)
 
98
  if(nargin==2 && args(1).is_string())
 
99
    {
 
100
      newtitle = true;
 
101
      title = args(1).string_value();
 
102
    }
 
103
  if(nargin==3)
 
104
    {
 
105
      newtitle = true;
 
106
      title = args(2).string_value();
 
107
    }
 
108
#endif
 
109
 
 
110
  if(pct==0.0 || pct==1.0)
 
111
    {
 
112
      init = true;
 
113
      term = getenv("TERM");
 
114
      if(!term)
 
115
        {
 
116
          no_terminal = true;
 
117
          return retval;
 
118
        }
 
119
#if defined (USE_TERM)
 
120
      i = tgetnum("co");
 
121
      smart_term = i ? true : false;
 
122
      if(nargin==1 || args(1).is_string())
 
123
        length = smart_term ? i-1 : DEFAULT_LEN;
 
124
#else
 
125
      if(nargin==1)
 
126
        length = DEFAULT_LEN;
 
127
#endif
 
128
      else
 
129
        if(nargin==2 && !(args(1).is_string()))
 
130
        {
 
131
          length = args(1).int_value();
 
132
          if(length>MAX_LEN)    length  = MAX_LEN;
 
133
          if(length<=0)         length  = DEFAULT_LEN;
 
134
        }
 
135
#if defined (USE_TERM)
 
136
      pct_pos = length/2-2;
 
137
      if(smart_term)
 
138
        {
 
139
          // get terminal strings ("rv"="reverse video")
 
140
          char* buf_ptr = term_buffer;
 
141
          begin_rv      = tgetstr("so", &buf_ptr);
 
142
          end_rv        = tgetstr("se", &buf_ptr);
 
143
          
 
144
          // Display a progress bar, but only if the current terminal has a
 
145
          // standout mode
 
146
          if (begin_rv && end_rv)
 
147
            {
 
148
              brvlen = 0;
 
149
              buf_ptr = begin_rv;
 
150
              while(buf_ptr[++brvlen]);
 
151
              ervlen = 0;       buf_ptr = end_rv;
 
152
              while(buf_ptr[++ervlen]);
 
153
            }
 
154
          // initialize print buffer
 
155
          for(i=0; i<BUF_SIZE; ++i)
 
156
            print_buf[i]        = ' ';
 
157
          print_buf[length+brvlen+ervlen+1] = '\r';
 
158
          print_buf[length+brvlen+ervlen+2] = '\0';
 
159
          for(i=0; i<brvlen; ++i)
 
160
            print_buf[i]        = begin_rv[i];
 
161
          for(i=0; i<ervlen; ++i)
 
162
            print_buf[i+brvlen] = end_rv[i];
 
163
          fputs(print_buf,stdout);
 
164
          if(title.length())
 
165
            newtitle    = true;
 
166
        }
 
167
      else
 
168
        {
 
169
#endif
 
170
          for(i=0; i<BUF_SIZE; ++i)
 
171
            print_buf[i]        = ' ';
 
172
          print_buf[length+8]   = '\r';
 
173
          print_buf[length+9]   = '\0';
 
174
          fputs(print_buf,stdout);
 
175
          print_buf[0]          = '[';
 
176
          print_buf[length+1]   = ']';
 
177
#if defined (USE_TERM)
 
178
        }
 
179
#endif
 
180
      n_chars_old       = 0;
 
181
      fflush(stdout);
 
182
      return retval;
 
183
    }
 
184
  else
 
185
    {
 
186
      // calculate position
 
187
      int n_chars=(int)(pct*length+0.5);
 
188
      int pct_int=(int)(pct*100.0+0.5);
 
189
 
 
190
      // check to see if we got this far without initialization
 
191
      if(init==false)
 
192
        {
 
193
          Ftext_waitbar(octave_value(0.0),0);
 
194
          fputs(print_buf,stdout);
 
195
          fflush(stdout);
 
196
        }
 
197
 
 
198
      // check to see of output needs to be updated
 
199
#if !defined (USE_TERM)
 
200
      if(n_chars!=n_chars_old || pct_int!=pct_int_old)
 
201
        {
 
202
#else
 
203
      if(n_chars!=n_chars_old || pct_int!=pct_int_old || newtitle)
 
204
        {
 
205
          if(smart_term)
 
206
            {
 
207
              static char pct_str[5];
 
208
              sprintf(pct_str,"%3i%%",pct_int);
 
209
 
 
210
              // Insert the title
 
211
              if(newtitle)
 
212
                {
 
213
                  pct_pos       = length-SPACING*2;
 
214
                  for(i=SPACING+brvlen; i<pct_pos+brvlen-SPACING;  ++i)
 
215
                    print_buf[ i>=n_chars_old+brvlen ? i+ervlen : i ] = ' ';
 
216
                  for(i=SPACING+brvlen, j=0; j<title.length(); ++i, ++j)
 
217
                    if(i<pct_pos+brvlen-SPACING)
 
218
                      print_buf[ i>=n_chars_old ? i+ervlen : i ] = title(0,j);
 
219
                  newtitle      = false;
 
220
                }
 
221
 
 
222
              // Insert the percentage string
 
223
              for(i=pct_pos+brvlen, j=0; j<4; ++i, ++j)
 
224
                print_buf[ i>=n_chars_old+brvlen ? i+ervlen : i ] = pct_str[j];
 
225
 
 
226
              // Move print_buf characters
 
227
              if(n_chars_old<n_chars)
 
228
                for(i=n_chars_old+brvlen; i<n_chars+brvlen; ++i)
 
229
                  print_buf[i]  = print_buf[i+ervlen];
 
230
              else
 
231
                for(i=n_chars_old+brvlen-1; i>=n_chars+brvlen; --i)
 
232
                  print_buf[i+ervlen]   = print_buf[i];
 
233
 
 
234
              // Insert end of reverse video
 
235
              for(i=n_chars+brvlen, j=0; j<ervlen; ++i, ++j)
 
236
                print_buf[i]    = end_rv[j];
 
237
            }
 
238
          else
 
239
            {
 
240
#endif
 
241
              if(n_chars>=n_chars_old)
 
242
                for(int i=n_chars_old+1; i<=n_chars; ++i)
 
243
                  print_buf[i]  = BAR_CHAR;
 
244
              else
 
245
                for(int i=n_chars+1; i<=n_chars_old; ++i)
 
246
                  print_buf[i]  = ' ';
 
247
              sprintf(&(print_buf[length+3])," %3i%%\r",pct_int);
 
248
#if defined (USE_TERM)
 
249
            }
 
250
#endif
 
251
          fputs(print_buf,stdout);
 
252
          fflush(stdout);
 
253
          n_chars_old   = n_chars;
 
254
          pct_int_old   = pct_int;
 
255
        }
 
256
    }
 
257
  return retval;
 
258
}