00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include "common.h"
00046
00047
00048 #ifdef HAVE_STRING_H
00049 #include <string.h>
00050 #endif
00051
00052 #include "tcl.h"
00053
00054 #include "machine.h"
00055 #include "cmd.h"
00056
00057
00058
00059
00060
00061
00062
00063 static void
00064 history_record(struct bu_cmdhist_obj *chop, struct bu_vls *cmdp, struct timeval *start, struct timeval *finish, int status)
00065
00066
00067
00068
00069 {
00070 struct bu_cmdhist *new_hist;
00071
00072 if (strcmp(bu_vls_addr(cmdp), "\n") == 0)
00073 return;
00074
00075 new_hist = (struct bu_cmdhist *)bu_malloc(sizeof(struct bu_cmdhist),
00076 "mged history");
00077 bu_vls_init(&new_hist->h_command);
00078 bu_vls_vlscat(&new_hist->h_command, cmdp);
00079 new_hist->h_start = *start;
00080 new_hist->h_finish = *finish;
00081 new_hist->h_status = status;
00082 BU_LIST_INSERT(&chop->cho_head.l, &new_hist->l);
00083
00084 chop->cho_curr = &chop->cho_head;
00085 }
00086
00087 static int
00088 timediff(struct timeval *tvdiff, struct timeval *start, struct timeval *finish)
00089 {
00090 if (finish->tv_sec == 0 && finish->tv_usec == 0)
00091 return -1;
00092 if (start->tv_sec == 0 && start->tv_usec == 0)
00093 return -1;
00094
00095 tvdiff->tv_sec = finish->tv_sec - start->tv_sec;
00096 tvdiff->tv_usec = finish->tv_usec - start->tv_usec;
00097 if (tvdiff->tv_usec < 0) {
00098 --tvdiff->tv_sec;
00099 tvdiff->tv_usec += 1000000L;
00100 }
00101
00102 return 0;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 int
00113 bu_cmdhist_history(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00114 {
00115 struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
00116 FILE *fp;
00117 int with_delays = 0;
00118 struct bu_cmdhist *hp, *hp_prev;
00119 struct bu_vls str;
00120 struct timeval tvdiff;
00121
00122 if (argc < 2 || 5 < argc) {
00123 struct bu_vls vls;
00124
00125 bu_vls_init(&vls);
00126 bu_vls_printf(&vls, "help history");
00127 Tcl_Eval(interp, bu_vls_addr(&vls));
00128 bu_vls_free(&vls);
00129 return TCL_ERROR;
00130 }
00131
00132 fp = NULL;
00133 while (argc >= 3) {
00134 if (strcmp(argv[2], "-delays") == 0)
00135 with_delays = 1;
00136 else if( strcmp(argv[2], "-outfile") == 0 ) {
00137 if (fp != NULL) {
00138 fclose(fp);
00139 Tcl_AppendResult(interp, "history: -outfile option given more than once\n",
00140 (char *)NULL);
00141 return TCL_ERROR;
00142 } else if (argc < 4 || strcmp(argv[3], "-delays") == 0) {
00143 Tcl_AppendResult(interp, "history: I need a file name\n", (char *)NULL);
00144 return TCL_ERROR;
00145 } else {
00146 fp = fopen( argv[3], "a+" );
00147 if (fp == NULL) {
00148 Tcl_AppendResult(interp, "history: error opening file", (char *)NULL);
00149 return TCL_ERROR;
00150 }
00151 --argc;
00152 ++argv;
00153 }
00154 } else {
00155 Tcl_AppendResult(interp, "Invalid option ", argv[2], "\n", (char *)NULL);
00156 }
00157 --argc;
00158 ++argv;
00159 }
00160
00161 bu_vls_init(&str);
00162 for (BU_LIST_FOR(hp, bu_cmdhist, &chop->cho_head.l)) {
00163 bu_vls_trunc(&str, 0);
00164 hp_prev = BU_LIST_PREV(bu_cmdhist, &hp->l);
00165 if (with_delays && BU_LIST_NOT_HEAD(hp_prev, &chop->cho_head.l)) {
00166 if (timediff(&tvdiff, &(hp_prev->h_finish), &(hp->h_start)) >= 0)
00167 bu_vls_printf(&str, "delay %ld %ld\n", (long)tvdiff.tv_sec,
00168 (long)tvdiff.tv_usec);
00169
00170 }
00171
00172 if (hp->h_status == TCL_ERROR)
00173 bu_vls_printf(&str, "# ");
00174 bu_vls_vlscat(&str, &(hp->h_command));
00175
00176 if (fp != NULL)
00177 bu_vls_fwrite(fp, &str);
00178 else
00179 Tcl_AppendResult(interp, bu_vls_addr(&str), (char *)NULL);
00180 }
00181
00182 if (fp != NULL)
00183 fclose(fp);
00184
00185 return TCL_OK;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195 int
00196 bu_cmdhist_add(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00197 {
00198 struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
00199 struct bu_vls vls;
00200 struct timeval zero;
00201
00202 if(argc != 3){
00203 bu_vls_init(&vls);
00204 bu_vls_printf(&vls, "helplib cmdhist_add");
00205 Tcl_Eval(interp, bu_vls_addr(&vls));
00206 bu_vls_free(&vls);
00207 return TCL_ERROR;
00208 }
00209
00210 if (argv[2][0] == '\n' || argv[2][0] == '\0')
00211 return TCL_OK;
00212
00213 bu_vls_init(&vls);
00214 bu_vls_strcpy(&vls, argv[2]);
00215 if (argv[2][strlen(argv[2])-1] != '\n')
00216 bu_vls_putc(&vls, '\n');
00217
00218 zero.tv_sec = zero.tv_usec = 0L;
00219 history_record(chop, &vls, &zero, &zero, TCL_OK);
00220
00221 bu_vls_free(&vls);
00222 return TCL_OK;
00223 }
00224
00225
00226
00227
00228
00229
00230
00231 int
00232 bu_cmdhist_prev(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00233 {
00234 struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
00235 struct bu_cmdhist *hp;
00236
00237 if (argc != 2) {
00238 struct bu_vls vls;
00239
00240 bu_vls_init(&vls);
00241 bu_vls_printf(&vls, "helplib cmdhist_prev");
00242 Tcl_Eval(interp, bu_vls_addr(&vls));
00243 bu_vls_free(&vls);
00244 return TCL_ERROR;
00245 }
00246
00247 hp = BU_LIST_PLAST(bu_cmdhist, chop->cho_curr);
00248 if (BU_LIST_NOT_HEAD(hp, &chop->cho_head.l))
00249 chop->cho_curr = hp;
00250
00251 Tcl_AppendResult(interp, bu_vls_addr(&chop->cho_curr->h_command), (char *)NULL);
00252 return TCL_OK;
00253 }
00254
00255
00256
00257
00258
00259
00260
00261 int
00262 bu_cmdhist_curr(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00263 {
00264 struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
00265
00266 if (argc != 2) {
00267 struct bu_vls vls;
00268
00269 bu_vls_init(&vls);
00270 bu_vls_printf(&vls, "helplib cmdhist_curr");
00271 Tcl_Eval(interp, bu_vls_addr(&vls));
00272 bu_vls_free(&vls);
00273 return TCL_ERROR;
00274 }
00275
00276 if (BU_LIST_NOT_HEAD(chop->cho_curr, &chop->cho_head.l))
00277 Tcl_AppendResult(interp, bu_vls_addr(&chop->cho_curr->h_command), (char *)NULL);
00278
00279 return TCL_OK;
00280 }
00281
00282
00283
00284
00285
00286
00287
00288 int
00289 bu_cmdhist_next(ClientData clientData, Tcl_Interp *interp, int argc, char **argv)
00290 {
00291 struct bu_cmdhist_obj *chop = (struct bu_cmdhist_obj *)clientData;
00292
00293 if (argc != 2) {
00294 struct bu_vls vls;
00295
00296 bu_vls_init(&vls);
00297 bu_vls_printf(&vls, "helplib cmdhist_next");
00298 Tcl_Eval(interp, bu_vls_addr(&vls));
00299 bu_vls_free(&vls);
00300 return TCL_ERROR;
00301 }
00302
00303 if (BU_LIST_IS_HEAD(chop->cho_curr, &chop->cho_head.l))
00304 return TCL_ERROR;
00305
00306 chop->cho_curr = BU_LIST_PNEXT(bu_cmdhist, chop->cho_curr);
00307 if (BU_LIST_IS_HEAD(chop->cho_curr, &chop->cho_head.l))
00308 return TCL_ERROR;
00309
00310 Tcl_AppendResult(interp, bu_vls_addr(&chop->cho_curr->h_command), (char *)NULL);
00311 return TCL_OK;
00312 }
00313
00314 #if 0
00315
00316
00317
00318
00319
00320
00321
00322 int
00323 f_delay(clientData, interp, argc, argv)
00324 ClientData clientData;
00325 Tcl_Interp *interp;
00326 int argc;
00327 char **argv;
00328 {
00329 struct timeval tv;
00330
00331 if(argc < 3 || 3 < argc){
00332 struct bu_vls vls;
00333
00334 bu_vls_init(&vls);
00335 bu_vls_printf(&vls, "help delay");
00336 Tcl_Eval(interp, bu_vls_addr(&vls));
00337 bu_vls_free(&vls);
00338 return TCL_ERROR;
00339 }
00340
00341 tv.tv_sec = atoi(argv[1]);
00342 tv.tv_usec = atoi(argv[2]);
00343 select(0, NULL, NULL, NULL, &tv);
00344
00345 return TCL_OK;
00346 }
00347 #endif
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357