gwenhywfar  5.10.1
cprogress.c
Go to the documentation of this file.
1 
2 
3 #ifdef HAVE_CONFIG_H
4 # include <config.h>
5 #endif
6 
7 #include "cprogress_p.h"
8 #include "cgui_l.h"
9 
10 #include <gwenhywfar/inherit.h>
11 #include <gwenhywfar/debug.h>
12 #include <gwenhywfar/misc.h>
13 
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <unistd.h>
17 #include <fcntl.h>
18 #include <errno.h>
19 #include <string.h>
20 
21 
23 
24 GWEN_LIST_FUNCTIONS(GWEN_GUI_CPROGRESS, GWEN_Gui_CProgress)
25 
26 
27 
29  uint32_t id,
30  uint32_t progressFlags,
31  const char *title,
32  const char *text,
33  uint64_t total)
34 {
36 
39  cp->gui=gui;
40  cp->id=id;
41  cp->startTime=time(0);
42  cp->flags=progressFlags;
43  if (title)
44  cp->title=strdup(title);
45  if (text)
46  cp->text=strdup(text);
47  cp->total=total;
48  cp->logBuf=GWEN_Buffer_new(0, 256, 0, 1);
49 
51  const char *s;
52 
54  s=getenv("GWEN_CPROGRESS_LOGLEVEL");
55  if (s) {
57 
59  if (GWEN_LoggerLevel_Unknown != ll)
60  CProgressLevel=ll;
61  }
62  }
63 
64  if (!(cp->flags & GWEN_GUI_PROGRESS_DELAY)) {
66  GWEN_Gui_StdPrintf(gui, stdout, "===== %s =====\n", title);
67  cp->shown=1;
68  }
69 
70  return cp;
71 }
72 
73 
74 
76 {
77  if (cp) {
79  GWEN_Buffer_free(cp->logBuf);
80  free(cp->text);
81  free(cp->title);
82  GWEN_FREE_OBJECT(cp);
83  }
84 }
85 
86 
87 
89 {
90  assert(cp);
91  return cp->gui;
92 }
93 
94 
95 
97 {
98  assert(cp);
99  return cp->id;
100 }
101 
102 
103 
105 {
106  assert(cp);
107  return cp->title;
108 }
109 
110 
111 
113 {
114  assert(cp);
115  return cp->text;
116 }
117 
118 
119 
121 {
122  assert(cp);
123  return cp->total;
124 }
125 
126 
127 
129 {
130  assert(cp);
131  cp->total=i;
132 }
133 
134 
135 
137 {
138  assert(cp);
139  return cp->current;
140 }
141 
142 
143 
145 {
146  assert(cp);
147  assert(cp->logBuf);
148  return GWEN_Buffer_GetStart(cp->logBuf);
149 }
150 
151 
152 
154 {
155  assert(cp);
156  return cp->aborted;
157 }
158 
159 
160 
161 
162 
163 
165 {
166 #ifndef OS_WIN32
167  int fl;
168 #endif
169 
170  assert(cp);
171  if (!cp->shown) {
172  time_t t1;
173 
174  t1=time(0);
175  if (difftime(t1, cp->startTime)>GWEN_GUI_DELAY_SECS) {
178  GWEN_Gui_StdPrintf(cp->gui, stdout, "%s: Started.\n", cp->title);
179  cp->shown=1;
180  }
181  }
182 
183  if (progress==GWEN_GUI_PROGRESS_ONE)
184  progress=cp->current+1;
185  if (progress!=GWEN_GUI_PROGRESS_NONE) {
186  if (progress!=cp->current) {
187  if (cp->shown) {
190  if (cp->total==GWEN_GUI_PROGRESS_NONE)
191  GWEN_Gui_StdPrintf(cp->gui, stdout, "%s: %" PRIu64 "\n", cp->title,
192  (uint64_t)progress);
193  else
194  GWEN_Gui_StdPrintf(cp->gui, stdout, "%s: %" PRIu64
195  " of %" PRIu64 "\n",
196  cp->title,
197  (uint64_t)progress,
198  (uint64_t)cp->total);
199  }
200  }
201  }
202  cp->current=progress;
203  }
204  }
205  if (cp->aborted)
207 
208 #ifndef OS_WIN32
210  /* check for abort */
211  fl=fcntl(fileno(stdin), F_GETFL);
212  if (fl!=-1) {
213  int chr;
214 
215  /* set stdin to nonblocking */
216  if (fcntl(fileno(stdin), F_SETFL, fl | O_NONBLOCK)) {
217  DBG_INFO(GWEN_LOGDOMAIN, "fcntl(stdin): %s", strerror(errno));
218  return 0;
219  }
220  /* check whether there is a character */
221  chr=getchar();
222  /* set blocking mode to what we found before modification */
223  fcntl(fileno(stdin), F_SETFL, fl);
224  if (chr==GWEN_GUI_CPROGRESS_CHAR_ABORT) {
226  GWEN_Gui_StdPrintf(cp->gui, stdout, "------> ABORTED BY USER\n");
227  cp->aborted=1;
229  }
230  }
231  }
232 #endif
233 
234  return 0;
235 }
236 
237 
238 
240  GWEN_LOGGER_LEVEL level,
241  const char *text)
242 {
243  assert(cp);
244  assert(text);
245 
247  GWEN_BUFFER *tbuf;
248  const char *t;
249 
250  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
251  GWEN_Gui_GetRawText(cp->gui, text, tbuf);
252  t=GWEN_Buffer_GetStart(tbuf);
253  if (t[GWEN_Buffer_GetUsedBytes(tbuf)-1]!='\n') {
254  GWEN_Buffer_AppendByte(tbuf, '\n');
255  /* Just in case the buffer has been reallocated */
256  t=GWEN_Buffer_GetStart(tbuf);
257  }
258  if (level <= CProgressLevel)
259  GWEN_Gui_StdPrintf(cp->gui, stdout, "%s", t);
260 
261  GWEN_Buffer_AppendString(cp->logBuf, t);
262  GWEN_Buffer_free(tbuf);
263  tbuf=0;
264  if (cp->aborted)
266  }
267  return 0;
268 }
269 
270 
271 
273 {
274  assert(cp);
275 
276  if (cp->shown) {
279  GWEN_Gui_StdPrintf(cp->gui, stdout, "%s: Finished.\n", cp->title);
280  }
281  if (cp->aborted)
283 
284  return 0;
285 }
286 
287 
288 
289 
const char * GWEN_Gui_CProgress_GetText(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:112
int GWEN_Gui_CProgress_GetAborted(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:153
char * GWEN_Buffer_GetStart(const GWEN_BUFFER *bf)
Definition: buffer.c:235
uint32_t GWEN_Gui_CProgress_GetId(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:96
uint32_t GWEN_Buffer_GetUsedBytes(const GWEN_BUFFER *bf)
Definition: buffer.c:277
#define GWEN_GUI_FLAGS_NONINTERACTIVE
Definition: gui.h:992
GWEN_LOGGER_LEVEL
Definition: logger.h:64
uint64_t GWEN_Gui_CProgress_GetCurrent(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:136
GWENHYWFAR_API int GWEN_Gui_StdPrintf(const GWEN_GUI *gui, FILE *stream, const char *fmt,...) GWEN_FORMAT(printf
#define GWEN_FREE_OBJECT(varname)
Definition: memory.h:61
const char * GWEN_Gui_CProgress_GetLogBuf(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:144
#define GWEN_GUI_PROGRESS_DELAY
Definition: gui.h:192
#define GWEN_LOGDOMAIN
Definition: logger.h:35
GWEN_LOGGER_LEVEL GWEN_Logger_Name2Level(const char *name)
Definition: logger.c:697
GWEN_BUFFER * GWEN_Buffer_new(char *buffer, uint32_t size, uint32_t used, int take)
Definition: buffer.c:42
int GWEN_Gui_CProgress_End(GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:272
GWEN_GUI * GWEN_Gui_CProgress_GetGui(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:88
#define GWEN_GUI_PROGRESS_ONE
Definition: gui.h:376
#define GWEN_NEW_OBJECT(typ, varname)
Definition: memory.h:55
#define GWEN_GUI_PROGRESS_NONE
Definition: gui.h:368
GWEN_GUI_CPROGRESS * GWEN_Gui_CProgress_new(GWEN_GUI *gui, uint32_t id, uint32_t progressFlags, const char *title, const char *text, uint64_t total)
Definition: cprogress.c:28
static GWEN_LOGGER_LEVEL CProgressLevel
Definition: cprogress.c:22
int GWEN_Buffer_AppendByte(GWEN_BUFFER *bf, char c)
Definition: buffer.c:394
uint64_t GWEN_Gui_CProgress_GetTotal(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:120
int GWEN_Gui_CProgress_Log(GWEN_GUI_CPROGRESS *cp, GWEN_LOGGER_LEVEL level, const char *text)
Definition: cprogress.c:239
void GWEN_Buffer_free(GWEN_BUFFER *bf)
Definition: buffer.c:89
struct GWEN_BUFFER GWEN_BUFFER
A dynamically resizeable text buffer.
Definition: buffer.h:38
int GWEN_Gui_CProgress_Advance(GWEN_GUI_CPROGRESS *cp, uint64_t progress)
Definition: cprogress.c:164
#define DBG_INFO(dbg_logger, format, args...)
Definition: debug.h:181
#define GWEN_LIST_INIT(t, element)
Definition: list1.h:465
struct GWEN_GUI GWEN_GUI
Definition: gui.h:176
const char * GWEN_Gui_CProgress_GetTitle(const GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:104
void GWEN_Gui_CProgress_SetTotal(GWEN_GUI_CPROGRESS *cp, uint64_t i)
Definition: cprogress.c:128
struct GWEN_GUI_CPROGRESS GWEN_GUI_CPROGRESS
Definition: cprogress_l.h:14
#define GWEN_LIST_FUNCTIONS(t, pr)
Definition: list1.h:366
void GWEN_Gui_CProgress_free(GWEN_GUI_CPROGRESS *cp)
Definition: cprogress.c:75
#define GWEN_ERROR_USER_ABORTED
Definition: error.h:65
GWENHYWFAR_API int GWENHYWFAR_API void GWEN_Gui_GetRawText(const GWEN_GUI *gui, const char *text, GWEN_BUFFER *tbuf)
uint32_t GWEN_Gui_GetFlags(const GWEN_GUI *gui)
Definition: gui.c:195
#define GWEN_LIST_FINI(t, element)
Definition: list1.h:474
int GWEN_Buffer_AppendString(GWEN_BUFFER *bf, const char *buffer)
Definition: buffer.c:989
#define GWEN_GUI_DELAY_SECS
Definition: gui.h:183