~ubuntu-branches/ubuntu/saucy/octave-miscellaneous/saucy-proposed

« back to all changes in this revision

Viewing changes to src/text_waitbar.cc

  • Committer: Package Import Robot
  • Author(s): Thomas Weber, Rafael Laboissiere, Sébastien Villemot
  • Date: 2012-03-11 23:14:58 UTC
  • Revision ID: package-import@ubuntu.com-20120311231458-s8nkjp69yz5c9t4u
Tags: 1.0.11-2
[ Rafael Laboissiere ]
* Bump the debhelper compatibility level to 9
* debian/control: Bump standards version to 3.9.3, no changes needed

[ Sébastien Villemot ]
* Add Sébastien Villemot to Uploaders
* Build-Depend on octave-pkg-dev >= 1.0.0
* debian/copyright: update using machine-readable format 1.0
* debian/patches/match-cell-array.patch: new patch
* debian/rules: fix wrong +x perms in upstream tarball
* debian/patches/waitbar-rename.patch: new patch

Show diffs side-by-side

added added

removed removed

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